[pypy-commit] pypy custom-trace: test_transformed_gc for custom tracers.
arigo
noreply at buildbot.pypy.org
Fri Jul 22 13:24:02 CEST 2011
Author: Armin Rigo <arigo at tunes.org>
Branch: custom-trace
Changeset: r45869:7467e121d4ac
Date: 2011-07-21 21:28 +0200
http://bitbucket.org/pypy/pypy/changeset/7467e121d4ac/
Log: test_transformed_gc for custom tracers.
diff --git a/pypy/rpython/memory/gctransform/framework.py b/pypy/rpython/memory/gctransform/framework.py
--- a/pypy/rpython/memory/gctransform/framework.py
+++ b/pypy/rpython/memory/gctransform/framework.py
@@ -534,8 +534,8 @@
# this method is attached to the instance and redirects to
# layoutbuilder.get_type_id().
- def finalizer_funcptr_for_type(self, TYPE):
- return self.layoutbuilder.finalizer_funcptr_for_type(TYPE)
+ def special_funcptr_for_type(self, TYPE):
+ return self.layoutbuilder.special_funcptr_for_type(TYPE)
def gc_header_for(self, obj, needs_hash=False):
hdr = self.gcdata.gc.gcheaderbuilder.header_of_object(obj)
@@ -678,7 +678,9 @@
c_type_id = rmodel.inputconst(TYPE_ID, type_id)
info = self.layoutbuilder.get_info(type_id)
c_size = rmodel.inputconst(lltype.Signed, info.fixedsize)
- has_finalizer = bool(self.finalizer_funcptr_for_type(TYPE))
+ kind_and_fptr = self.special_funcptr_for_type(TYPE)
+ has_finalizer = (kind_and_fptr is not None and
+ kind_and_fptr[0] == "finalizer")
c_has_finalizer = rmodel.inputconst(lltype.Bool, has_finalizer)
if not op.opname.endswith('_varsize') and not flags.get('varsize'):
@@ -1233,19 +1235,21 @@
def has_finalizer(self, TYPE):
rtti = get_rtti(TYPE)
- return rtti is not None and hasattr(rtti._obj, 'destructor_funcptr')
+ return rtti is not None and getattr(rtti._obj, 'destructor_funcptr',
+ None)
+
+ def has_custom_trace(self, TYPE):
+ rtti = get_rtti(TYPE)
+ return rtti is not None and getattr(rtti._obj, 'custom_trace_funcptr',
+ None)
def make_finalizer_funcptr_for_type(self, TYPE):
- if self.has_finalizer(TYPE):
+ if not self.has_finalizer(TYPE):
+ return None
rtti = get_rtti(TYPE)
destrptr = rtti._obj.destructor_funcptr
DESTR_ARG = lltype.typeOf(destrptr).TO.ARGS[0]
- else:
- destrptr = None
- DESTR_ARG = None
-
assert not type_contains_pyobjs(TYPE), "not implemented"
- if destrptr:
typename = TYPE.__name__
def ll_finalizer(addr, ignored):
v = llmemory.cast_adr_to_ptr(addr, DESTR_ARG)
@@ -1254,8 +1258,17 @@
fptr = self.transformer.annotate_finalizer(ll_finalizer,
[llmemory.Address, llmemory.Address], llmemory.Address)
return fptr
- else:
+
+ def make_custom_trace_funcptr_for_type(self, TYPE):
+ if not self.has_custom_trace(TYPE):
return None
+ rtti = get_rtti(TYPE)
+ fptr = rtti._obj.custom_trace_funcptr
+ if not hasattr(fptr._obj, 'graph'):
+ ll_func = fptr._obj._callable
+ fptr = self.transformer.annotate_finalizer(ll_func,
+ [llmemory.Address, llmemory.Address], llmemory.Address)
+ return fptr
def gen_zero_gc_pointers(TYPE, v, llops, previous_steps=None):
diff --git a/pypy/rpython/memory/gctypelayout.py b/pypy/rpython/memory/gctypelayout.py
--- a/pypy/rpython/memory/gctypelayout.py
+++ b/pypy/rpython/memory/gctypelayout.py
@@ -188,7 +188,7 @@
infobits = index
info.ofstoptrs = builder.offsets2table(offsets, TYPE)
#
- kind_and_fptr = builder.finalizer_funcptr_for_type(TYPE)
+ kind_and_fptr = builder.special_funcptr_for_type(TYPE)
if kind_and_fptr is not None:
kind, fptr = kind_and_fptr
info.finalizer_or_customtrace = fptr
@@ -263,7 +263,7 @@
# for debugging, the following list collects all the prebuilt
# GcStructs and GcArrays
self.all_prebuilt_gc = []
- self._finalizer_funcptrs = {}
+ self._special_funcptrs = {}
self.offsettable_cache = {}
def make_type_info_group(self):
@@ -364,9 +364,9 @@
self.offsettable_cache = None
return self.type_info_group
- def finalizer_funcptr_for_type(self, TYPE):
- if TYPE in self._finalizer_funcptrs:
- return self._finalizer_funcptrs[TYPE]
+ def special_funcptr_for_type(self, TYPE):
+ if TYPE in self._special_funcptrs:
+ return self._special_funcptrs[TYPE]
fptr1 = self.make_finalizer_funcptr_for_type(TYPE)
fptr2 = self.make_custom_trace_funcptr_for_type(TYPE)
assert not (fptr1 and fptr2), (
@@ -377,7 +377,7 @@
kind_and_fptr = "custom_trace", fptr2
else:
kind_and_fptr = None
- self._finalizer_funcptrs[TYPE] = kind_and_fptr
+ self._special_funcptrs[TYPE] = kind_and_fptr
return kind_and_fptr
def make_finalizer_funcptr_for_type(self, TYPE):
diff --git a/pypy/rpython/memory/test/test_transformed_gc.py b/pypy/rpython/memory/test/test_transformed_gc.py
--- a/pypy/rpython/memory/test/test_transformed_gc.py
+++ b/pypy/rpython/memory/test/test_transformed_gc.py
@@ -410,6 +410,40 @@
res = run([5, 42]) #XXX pure lazyness here too
assert 160 <= res <= 165
+ def define_custom_trace(cls):
+ from pypy.rpython.annlowlevel import llhelper
+ from pypy.rpython.lltypesystem import llmemory
+ #
+ S = lltype.GcStruct('S', ('x', llmemory.Address), rtti=True)
+ T = lltype.GcStruct('T', ('z', lltype.Signed))
+ offset_of_x = llmemory.offsetof(S, 'x')
+ def customtrace(obj, prev):
+ if not prev:
+ return obj + offset_of_x
+ else:
+ return llmemory.NULL
+ CUSTOMTRACEFUNC = lltype.FuncType([llmemory.Address, llmemory.Address],
+ llmemory.Address)
+ customtraceptr = llhelper(lltype.Ptr(CUSTOMTRACEFUNC), customtrace)
+ lltype.attachRuntimeTypeInfo(S, customtraceptr=customtraceptr)
+ #
+ def setup():
+ s1 = lltype.malloc(S)
+ tx = lltype.malloc(T)
+ tx.z = 4243
+ s1.x = llmemory.cast_ptr_to_adr(tx)
+ return s1
+ def f():
+ s1 = setup()
+ llop.gc__collect(lltype.Void)
+ return llmemory.cast_adr_to_ptr(s1.x, lltype.Ptr(T)).z
+ return f
+
+ def test_custom_trace(self):
+ run = self.runner("custom_trace")
+ res = run([])
+ assert res == 4243
+
def define_weakref(cls):
import weakref, gc
class A(object):
diff --git a/pypy/translator/c/gc.py b/pypy/translator/c/gc.py
--- a/pypy/translator/c/gc.py
+++ b/pypy/translator/c/gc.py
@@ -320,8 +320,10 @@
# still important to see it so that it can be followed as soon as
# the mixlevelannotator resolves it.
gctransf = self.db.gctransformer
- fptr = gctransf.finalizer_funcptr_for_type(structdefnode.STRUCT)
- self.db.get(fptr)
+ TYPE = structdefnode.STRUCT
+ kind_and_fptr = gctransf.special_funcptr_for_type(TYPE)
+ if kind_and_fptr:
+ self.db.get(kind_and_fptr[1])
def array_setup(self, arraydefnode):
pass
More information about the pypy-commit
mailing list