[pypy-commit] pypy erase-raw-mem: (arigato, fijal, alex): make untyped storage work with the GC, other things were refactored
alex_gaynor
noreply at buildbot.pypy.org
Tue Mar 13 05:32:26 CET 2012
Author: Alex Gaynor <alex.gaynor at gmail.com>
Branch: erase-raw-mem
Changeset: r53408:fb11c92cde91
Date: 2012-03-12 21:32 -0700
http://bitbucket.org/pypy/pypy/changeset/fb11c92cde91/
Log: (arigato, fijal, alex): make untyped storage work with the GC, other
things were refactored
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
@@ -6,9 +6,10 @@
from pypy.annotation import model as annmodel
from pypy.annotation.bookkeeper import getbookkeeper
-from pypy.rpython.annlowlevel import hlstr, llstr
+from pypy.rpython.annlowlevel import hlstr, llstr, llhelper
from pypy.rpython.extregistry import ExtRegistryEntry
-from pypy.rpython.lltypesystem import rffi, lltype, llmemory, rstr
+from pypy.rpython.lltypesystem import rffi, lltype, llmemory
+from pypy.rpython.lltypesystem.rstr import STR, string_repr
from pypy.rpython.rmodel import Repr
@@ -78,11 +79,40 @@
self._check_idx(s_idx)
assert isinstance(s_obj, annmodel.SomeInstance)
+UNTYPEDSTORAGE = lltype.GcStruct("untypedstorage",
+ ("shape", lltype.Ptr(STR)),
+ ("data", lltype.Array(llmemory.Address)),
+ rtti=True,
+)
+
+
+CUSTOMTRACEFUNC = lltype.FuncType([llmemory.Address, llmemory.Address],
+ llmemory.Address)
+def trace_untypedstorage(obj_addr, prev):
+ shape_addr = obj_addr + llmemory.offsetof(UNTYPEDSTORAGE, "shape")
+ if not prev:
+ return shape_addr
+ shape = shape_addr.address[0]
+ length_offset = (llmemory.offsetof(STR, "chars") +
+ llmemory.arraylengthoffset(STR.chars))
+ length = (shape + length_offset).signed[0]
+ if prev == shape_addr:
+ i = 0
+ while i < length:
+ char = (shape + llmemory.offsetof(STR, "chars") +
+ llmemory.itemoffsetof(STR.chars, 0) +
+ (llmemory.sizeof(STR.chars.OF) * i)).char[0]
+ if char == INSTANCE:
+ return (obj_addr + llmemory.offsetof(UNTYPEDSTORAGE, "data") +
+ llmemory.itemoffsetof(UNTYPEDSTORAGE.data, 0) +
+ llmemory.sizeof(UNTYPEDSTORAGE.data.OF) * i)
+ i += 1
+ return llmemory.NULL
+trace_untypedstorage_ptr = llhelper(lltype.Ptr(CUSTOMTRACEFUNC), trace_untypedstorage)
+
class UntypedStorageRepr(Repr):
- lowleveltype = lltype.Ptr(lltype.GcStruct("untypedstorage",
- ("shape", lltype.Ptr(rstr.STR)),
- ("data", lltype.Array(lltype.Signed, hints={"nolength": True})),
- ))
+ lowleveltype = lltype.Ptr(UNTYPEDSTORAGE)
+ lltype.attachRuntimeTypeInfo(lowleveltype.TO, customtraceptr=trace_untypedstorage_ptr)
def _read_index(self, hop):
v_arr = hop.inputarg(self, arg=0)
@@ -90,7 +120,7 @@
c_name = hop.inputconst(lltype.Void, "data")
hop.exception_cannot_occur()
return hop.genop("getinteriorfield", [v_arr, c_name, v_idx],
- resulttype=lltype.Signed)
+ resulttype=llmemory.Address)
def _write_index(self, hop, v_value):
v_arr = hop.inputarg(self, arg=0)
@@ -100,31 +130,31 @@
hop.genop("setinteriorfield", [v_arr, c_name, v_idx, v_value])
def rtyper_new(self, hop):
- [v_shape] = hop.inputargs(rstr.string_repr)
+ [v_shape] = hop.inputargs(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)
+ v_addr = self._read_index(hop)
+ return hop.genop("force_cast", [v_addr], resulttype=lltype.Signed)
def rtype_method_setint(self, hop):
v_value = hop.inputarg(lltype.Signed, arg=2)
- self._write_index(hop, v_value)
+ v_addr = hop.genop("force_cast", [v_value], resulttype=llmemory.Address)
+ self._write_index(hop, v_addr)
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)
+ v_addr = self._read_index(hop)
return hop.genop("cast_adr_to_ptr", [v_addr], resulttype=hop.r_result.lowleveltype)
def rtype_method_setinstance(self, hop):
+ v_arr = hop.inputarg(self, arg=0)
v_instance = hop.inputarg(hop.args_r[2], arg=2)
+ hop.genop("gc_writebarrier", [v_instance, v_arr])
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)
+ self._write_index(hop, v_addr)
@classmethod
def ll_new(cls, shape):
diff --git a/pypy/rpython/llinterp.py b/pypy/rpython/llinterp.py
--- a/pypy/rpython/llinterp.py
+++ b/pypy/rpython/llinterp.py
@@ -42,7 +42,7 @@
return ''.join(etype.name).rstrip('\x00')
else:
# ootype!
- return etype._INSTANCE._name.split(".")[-1]
+ return etype._INSTANCE._name.split(".")[-1]
class LLInterpreter(object):
""" low level interpreter working with concrete values. """
@@ -654,11 +654,11 @@
return self.invoke_callable_with_pyexceptions(f, *args)
args_v = graph.getargs()
if len(ARGS) != len(args_v):
- raise TypeError("graph with %d args called with wrong func ptr type: %r" %(len(args_v), ARGS))
+ raise TypeError("graph with %d args called with wrong func ptr type: %r" %(len(args_v), ARGS))
for T, v in zip(ARGS, args_v):
if not lltype.isCompatibleType(T, v.concretetype):
raise TypeError("graph with %r args called with wrong func ptr type: %r" %
- (tuple([v.concretetype for v in args_v]), ARGS))
+ (tuple([v.concretetype for v in args_v]), ARGS))
frame = self.newsubframe(graph, args)
return frame.eval()
@@ -672,7 +672,7 @@
if graphs is not None:
obj = self.llinterpreter.typer.type_system.deref(f)
if hasattr(obj, 'graph'):
- assert obj.graph in graphs
+ assert obj.graph in graphs
else:
pass
#log.warn("op_indirect_call with graphs=None:", f)
@@ -728,6 +728,12 @@
def op_zero_gc_pointers_inside(self, obj):
raise NotImplementedError("zero_gc_pointers_inside")
+ def op_gc_writebarrier(self, newvalue, struct):
+ assert isinstance(lltype.typeOf(newvalue), lltype.Ptr)
+ assert isinstance(lltype.typeOf(struct), lltype.Ptr)
+ if hasattr(self.heap, "writebarrier"):
+ self.heap.writebarrier(newvalue, struct)
+
def op_gc_writebarrier_before_copy(self, source, dest,
source_start, dest_start, length):
if hasattr(self.heap, 'writebarrier_before_copy'):
@@ -982,7 +988,7 @@
return llmemory.raw_malloc_usage(size)
def op_raw_free(self, addr):
- checkadr(addr)
+ checkadr(addr)
llmemory.raw_free(addr)
def op_raw_memclear(self, addr, size):
@@ -1126,7 +1132,7 @@
def op_new(self, INST):
assert isinstance(INST, (ootype.Instance, ootype.BuiltinType))
return ootype.new(INST)
-
+
def op_oonewarray(self, ARRAY, length):
assert isinstance(ARRAY, ootype.Array)
assert isinstance(length, int)
@@ -1140,7 +1146,7 @@
eq_name, interp_eq = \
wrap_callable(self.llinterpreter, eq_func, eq_obj, eq_method_name)
EQ_FUNC = ootype.StaticMethod([DICT._KEYTYPE, DICT._KEYTYPE], ootype.Bool)
- sm_eq = ootype.static_meth(EQ_FUNC, eq_name, _callable=interp_eq)
+ sm_eq = ootype.static_meth(EQ_FUNC, eq_name, _callable=interp_eq)
hash_name, interp_hash = \
wrap_callable(self.llinterpreter, hash_func, hash_obj, hash_method_name)
diff --git a/pypy/rpython/lltypesystem/llmemory.py b/pypy/rpython/lltypesystem/llmemory.py
--- a/pypy/rpython/lltypesystem/llmemory.py
+++ b/pypy/rpython/lltypesystem/llmemory.py
@@ -5,7 +5,7 @@
# sizeof, offsetof
import weakref
-from pypy.rlib.objectmodel import Symbolic
+from pypy.rlib.objectmodel import Symbolic, specialize
from pypy.rpython.lltypesystem import lltype
from pypy.tool.uid import uid
@@ -380,6 +380,7 @@
else:
raise Exception("don't know how to take the size of a %r"%TYPE)
+ at specialize.arg(0)
def sizeof(TYPE, n=None):
if n is None:
return _sizeof_none(TYPE)
@@ -387,19 +388,23 @@
return itemoffsetof(TYPE) + _sizeof_none(TYPE.OF) * n
else:
return _sizeof_int(TYPE, n)
-sizeof._annspecialcase_ = 'specialize:arg(0)'
+ at specialize.memo()
def offsetof(TYPE, fldname):
assert fldname in TYPE._flds
return FieldOffset(TYPE, fldname)
-offsetof._annspecialcase_ = 'specialize:memo'
+ at specialize.memo()
def itemoffsetof(TYPE, n=0):
result = ArrayItemsOffset(TYPE)
if n != 0:
result += ItemOffset(TYPE.OF) * n
return result
-itemoffsetof._annspecialcase_ = 'specialize:memo'
+
+ at specialize.memo()
+def arraylengthoffset(TYPE):
+ return ArrayLengthOffset(TYPE)
+
# -------------------------------------------------------------
class fakeaddress(object):
@@ -880,7 +885,7 @@
assert isinstance(s_from, SomeAddress)
assert isinstance(s_to, SomeAddress)
assert isinstance(s_size, SomeInteger)
-
+
def specialize_call(self, hop):
hop.exception_cannot_occur()
v_list = hop.inputargs(Address, Address, lltype.Signed)
diff --git a/pypy/rpython/lltypesystem/lloperation.py b/pypy/rpython/lltypesystem/lloperation.py
--- a/pypy/rpython/lltypesystem/lloperation.py
+++ b/pypy/rpython/lltypesystem/lloperation.py
@@ -464,6 +464,7 @@
'gc_thread_before_fork':LLOp(), # returns an opaque address
'gc_thread_after_fork': LLOp(), # arguments: (result_of_fork, opaqueaddr)
'gc_assume_young_pointers': LLOp(canrun=True),
+ 'gc_writebarrier': LLOp(canrun=True),
'gc_writebarrier_before_copy': LLOp(canrun=True),
'gc_heap_stats' : LLOp(canmallocgc=True),
diff --git a/pypy/rpython/memory/gcwrapper.py b/pypy/rpython/memory/gcwrapper.py
--- a/pypy/rpython/memory/gcwrapper.py
+++ b/pypy/rpython/memory/gcwrapper.py
@@ -132,7 +132,7 @@
result = llmemory.cast_adr_to_ptr(addr, gctypelayout.WEAKREFPTR)
result.weakptr = llmemory.cast_ptr_to_adr(objgetter())
return llmemory.cast_ptr_to_weakrefptr(result)
-
+
def weakref_deref(self, PTRTYPE, obj):
addr = gctypelayout.ll_weakref_deref(obj)
return llmemory.cast_adr_to_ptr(addr, PTRTYPE)
@@ -141,6 +141,12 @@
ptr = lltype.cast_opaque_ptr(llmemory.GCREF, ptr)
return self.gc.id(ptr)
+ def writebarrier(self, newvalue, struct):
+ if self.gc.needs_write_barrier:
+ newvalue_addr = llmemory.cast_ptr_to_adr(newvalue)
+ struct_addr = llmemory.cast_ptr_to_adr(struct)
+ self.gc.write_barrier(newvalue_addr, struct_addr)
+
def writebarrier_before_copy(self, source, dest,
source_start, dest_start, length):
if self.gc.needs_write_barrier:
More information about the pypy-commit
mailing list