[pypy-commit] pypy erase-raw-mem: (fijal, alex): refactor untyped storage (works on llinterp!), and add a gc test
alex_gaynor
noreply at buildbot.pypy.org
Tue Mar 13 04:40:14 CET 2012
Author: Alex Gaynor <alex.gaynor at gmail.com>
Branch: erase-raw-mem
Changeset: r53407:6b75ec7ff14d
Date: 2012-03-12 20:39 -0700
http://bitbucket.org/pypy/pypy/changeset/6b75ec7ff14d/
Log: (fijal, alex): refactor untyped storage (works on llinterp!), and
add a gc test
diff --git a/pypy/rlib/rerased_raw.py b/pypy/rlib/rerased_raw.py
--- a/pypy/rlib/rerased_raw.py
+++ b/pypy/rlib/rerased_raw.py
@@ -1,47 +1,51 @@
"""
This module supports raw storage of arbitrary data (GC ptr, instance, float,
-int) into a void *.
+int) into a void *. The creator of the UntypedStorage is responsible for
+making sure that the shape string is cached correctly.
"""
from pypy.annotation import model as annmodel
from pypy.annotation.bookkeeper import getbookkeeper
+from pypy.rpython.annlowlevel import hlstr, llstr
from pypy.rpython.extregistry import ExtRegistryEntry
-from pypy.rpython.lltypesystem import rffi, lltype, llmemory
+from pypy.rpython.lltypesystem import rffi, lltype, llmemory, rstr
from pypy.rpython.rmodel import Repr
+INT = "i"
+INSTANCE = "o"
+
class UntypedStorage(object):
- def __init__(self, n):
- self.storage = [None] * n
+ def __init__(self, shape):
+ self.storage = [None] * len(shape)
+ self.shape = shape
def getint(self, idx):
+ assert self.shape[idx] == INT
v = self.storage[idx]
assert isinstance(v, int)
return v
def setint(self, idx, v):
+ assert self.shape[idx] == INT
assert isinstance(v, int)
self.storage[idx] = v
- # def getfloat(self, idx, f):
- # return self.storage[idx]
-
- # def setfloat(self, idx, f):
- # self.storage[idx] = f
-
def getinstance(self, idx, cls):
obj = self.storage[idx]
+ assert self.shape[idx] == INSTANCE
assert isinstance(obj, cls)
return obj
def setinstance(self, idx, obj):
+ assert self.shape[idx] == INSTANCE
self.storage[idx] = obj
class UntypedStorageEntry(ExtRegistryEntry):
_about_ = UntypedStorage
- def compute_result_annotation(self, s_n):
- assert annmodel.SomeInteger().contains(s_n)
+ def compute_result_annotation(self, s_shape):
+ assert annmodel.SomeString().contains(s_shape)
return SomeUntypedStorage()
def specialize_call(self, hop):
@@ -75,38 +79,55 @@
assert isinstance(s_obj, annmodel.SomeInstance)
class UntypedStorageRepr(Repr):
- lowleveltype = lltype.Ptr(lltype.GcArray(lltype.Signed))
+ lowleveltype = lltype.Ptr(lltype.GcStruct("untypedstorage",
+ ("shape", lltype.Ptr(rstr.STR)),
+ ("data", lltype.Array(lltype.Signed, hints={"nolength": True})),
+ ))
- def rtyper_new(self, hop):
- [v_arg] = hop.inputargs(lltype.Signed)
+ def _read_index(self, hop):
+ v_arr = hop.inputarg(self, arg=0)
+ v_idx = hop.inputarg(lltype.Signed, arg=1)
+ c_name = hop.inputconst(lltype.Void, "data")
hop.exception_cannot_occur()
- return hop.gendirectcall(self.ll_new, v_arg)
+ return hop.genop("getinteriorfield", [v_arr, c_name, v_idx],
+ resulttype=lltype.Signed)
- def rtype_method_getint(self, hop):
- [v_arr, v_idx] = hop.inputargs(self, lltype.Signed)
- hop.exception_cannot_occur()
- return hop.genop("getarrayitem", [v_arr, v_idx], resulttype=lltype.Signed)
-
- def rtype_method_setint(self, hop):
- [v_arr, v_idx, v_value] = hop.inputargs(self, lltype.Signed, lltype.Signed)
- hop.exception_cannot_occur()
- hop.genop("setarrayitem", [v_arr, v_idx, v_value])
-
- def rtype_method_getinstance(self, hop):
+ def _write_index(self, hop, v_value):
v_arr = hop.inputarg(self, arg=0)
v_idx = hop.inputarg(lltype.Signed, arg=1)
hop.exception_cannot_occur()
- v_result = hop.genop("getarrayitem", [v_arr, v_idx], resulttype=lltype.Signed)
+ c_name = hop.inputconst(lltype.Void, "data")
+ hop.genop("setinteriorfield", [v_arr, c_name, v_idx, v_value])
+
+ def rtyper_new(self, hop):
+ [v_shape] = hop.inputargs(rstr.string_repr)
+ hop.exception_cannot_occur()
+ return hop.gendirectcall(self.ll_new, v_shape)
+
+ def rtype_method_getint(self, hop):
+ return self._read_index(hop)
+
+ def rtype_method_setint(self, hop):
+ v_value = hop.inputarg(lltype.Signed, arg=2)
+ self._write_index(hop, v_value)
+
+ def rtype_method_getinstance(self, hop):
+ v_result = self._read_index(hop)
v_addr = hop.genop("cast_int_to_adr", [v_result], resulttype=llmemory.Address)
return hop.genop("cast_adr_to_ptr", [v_addr], resulttype=hop.r_result.lowleveltype)
def rtype_method_setinstance(self, hop):
- [v_arr, v_idx, v_instance] = hop.inputargs(self, lltype.Signed, hop.args_r[2])
- hop.exception_cannot_occur()
- v_addr = hop.genop("cast_ptr_to_adr", [v_instance], resulttype=llmemory.Address)
- v_result = hop.genop("cast_adr_to_int", [v_addr, hop.inputconst(lltype.Void, "symbolic")], resulttype=lltype.Signed)
- hop.genop("setarrayitem", [v_arr, v_idx, v_result])
+ v_instance = hop.inputarg(hop.args_r[2], arg=2)
+
+ v_addr = hop.genop("cast_ptr_to_adr", [v_instance],
+ resulttype=llmemory.Address)
+ v_value = hop.genop("cast_adr_to_int",
+ [v_addr, hop.inputconst(lltype.Void, "symbolic")],
+ resulttype=lltype.Signed)
+ self._write_index(hop, v_value)
@classmethod
- def ll_new(cls, size):
- return lltype.malloc(cls.lowleveltype.TO, size)
\ No newline at end of file
+ def ll_new(cls, shape):
+ obj = lltype.malloc(cls.lowleveltype.TO, len(shape.chars))
+ obj.shape = shape
+ return obj
\ No newline at end of file
diff --git a/pypy/rlib/test/test_rerased_raw.py b/pypy/rlib/test/test_rerased_raw.py
--- a/pypy/rlib/test/test_rerased_raw.py
+++ b/pypy/rlib/test/test_rerased_raw.py
@@ -5,7 +5,7 @@
def test_direct_int():
- storage = rerased_raw.UntypedStorage(2)
+ storage = rerased_raw.UntypedStorage("ii")
storage.setint(0, 2)
assert storage.getint(0) == 2
@@ -18,7 +18,7 @@
def __init__(self, value):
self.value = value
- storage = rerased_raw.UntypedStorage(1)
+ storage = rerased_raw.UntypedStorage("o")
storage.setinstance(0, A(4))
assert storage.getinstance(0, A).value == 4
@@ -27,7 +27,7 @@
class TestRerasedRawLLType(LLRtypeMixin, BaseRtypingTest):
def test_int(self):
def f(x):
- storage = rerased_raw.UntypedStorage(1)
+ storage = rerased_raw.UntypedStorage("i")
storage.setint(0, x)
return storage.getint(0)
@@ -40,7 +40,7 @@
self.v = v
def f(x):
- storage = rerased_raw.UntypedStorage(1)
+ storage = rerased_raw.UntypedStorage("o")
storage.setinstance(0, A(x))
return storage.getinstance(0, A).v
@@ -54,7 +54,7 @@
def f(x):
try:
- storage = rerased_raw.UntypedStorage(2)
+ storage = rerased_raw.UntypedStorage("io")
storage.setint(0, x)
value1 = storage.getint(0)
storage.setinstance(1, A(x))
@@ -65,3 +65,15 @@
res = self.interpret(f, [4])
assert res == 8
+
+ def test_union(self):
+ def f(x, v):
+ if x:
+ storage = rerased_raw.UntypedStorage("i")
+ else:
+ storage = rerased_raw.UntypedStorage("ii")
+ storage.setint(0, v)
+ return storage.getint(0)
+
+ res = self.interpret(f, [True, 15])
+ assert res == 15
diff --git a/pypy/rpython/memory/test/test_gc.py b/pypy/rpython/memory/test/test_gc.py
--- a/pypy/rpython/memory/test/test_gc.py
+++ b/pypy/rpython/memory/test/test_gc.py
@@ -6,9 +6,9 @@
from pypy.rpython.test.test_llinterp import get_interpreter
from pypy.rpython.lltypesystem import lltype
from pypy.rpython.lltypesystem.lloperation import llop
-from pypy.rlib.objectmodel import we_are_translated
-from pypy.rlib.objectmodel import compute_unique_id
+from pypy.rlib.objectmodel import we_are_translated, compute_unique_id
from pypy.rlib import rgc
+from pypy.rlib.rerased_raw import UntypedStorage
from pypy.rlib.rstring import StringBuilder
from pypy.rlib.rarithmetic import LONG_BIT
@@ -86,7 +86,7 @@
for i in range(1, 15):
res = self.interpret(append_to_list, [i, i - 1])
assert res == i - 1 # crashes if constants are not considered roots
-
+
def test_string_concatenation(self):
#curr = simulator.current_size
def concat(j):
@@ -746,6 +746,22 @@
res = self.interpret(fn, [])
assert res == ord('y')
+ def test_untypedstorage(self):
+ class A(object):
+ def __init__(self, v):
+ self.v = v
+
+ def fn(v):
+ s = UntypedStorage("io")
+ s.setint(0, v)
+ s.setinstance(1, A(v))
+ rgc.collect()
+ return s.getint(0) + s.getinstance(1, A).v
+
+ res = self.interpret(fn, [10])
+ assert res == 20
+
+
from pypy.rlib.objectmodel import UnboxedValue
class TaggedBase(object):
More information about the pypy-commit
mailing list