Author: Maciej Fijalkowski <[email protected]>
Branch: jitframe-on-heap
Changeset: r60173:c68a9032570c
Date: 2013-01-18 16:17 +0200
http://bitbucket.org/pypy/pypy/changeset/c68a9032570c/
Log: an API I want from a custom tracer (that can be run directly too)
diff --git a/pypy/rpython/lltypesystem/lltype.py
b/pypy/rpython/lltypesystem/lltype.py
--- a/pypy/rpython/lltypesystem/lltype.py
+++ b/pypy/rpython/lltypesystem/lltype.py
@@ -361,7 +361,7 @@
Struct._install_extras(self, **kwds)
def _attach_runtime_type_info_funcptr(self, funcptr, destrptr,
- customtraceptr):
+ custom_trace_func):
if self._runtime_type_info is None:
raise TypeError("attachRuntimeTypeInfo: %r must have been built "
"with the rtti=True argument" % (self,))
@@ -385,18 +385,8 @@
raise TypeError("expected a destructor function "
"implementation, got: %s" % destrptr)
self._runtime_type_info.destructor_funcptr = destrptr
- if customtraceptr is not None:
- from pypy.rpython.lltypesystem import llmemory
- T = typeOf(customtraceptr)
- if (not isinstance(T, Ptr) or
- not isinstance(T.TO, FuncType) or
- len(T.TO.ARGS) != 2 or
- T.TO.RESULT != llmemory.Address or
- T.TO.ARGS[0] != llmemory.Address or
- T.TO.ARGS[1] != llmemory.Address):
- raise TypeError("expected a custom trace function "
- "implementation, got: %s" % customtraceptr)
- self._runtime_type_info.custom_trace_funcptr = customtraceptr
+ if custom_trace_func is not None:
+ self._runtime_type_info.custom_trace_func = custom_trace_func
class GcStruct(RttiStruct):
_gckind = 'gc'
@@ -2050,11 +2040,11 @@
return _ptr(PTRTYPE, oddint, solid=True)
def attachRuntimeTypeInfo(GCSTRUCT, funcptr=None, destrptr=None,
- customtraceptr=None):
+ custom_trace_func=None):
if not isinstance(GCSTRUCT, RttiStruct):
raise TypeError, "expected a RttiStruct: %s" % GCSTRUCT
GCSTRUCT._attach_runtime_type_info_funcptr(funcptr, destrptr,
- customtraceptr)
+ custom_trace_func)
return _ptr(Ptr(RuntimeTypeInfo), GCSTRUCT._runtime_type_info)
def getRuntimeTypeInfo(GCSTRUCT):
diff --git a/pypy/rpython/memory/gc/base.py b/pypy/rpython/memory/gc/base.py
--- a/pypy/rpython/memory/gc/base.py
+++ b/pypy/rpython/memory/gc/base.py
@@ -73,7 +73,6 @@
member_index,
is_rpython_class,
has_custom_trace,
- get_custom_trace,
fast_path_tracing):
self.getfinalizer = getfinalizer
self.getlightfinalizer = getlightfinalizer
@@ -90,7 +89,6 @@
self.member_index = member_index
self.is_rpython_class = is_rpython_class
self.has_custom_trace = has_custom_trace
- self.get_custom_trace = get_custom_trace
self.fast_path_tracing = fast_path_tracing
def get_member_index(self, type_id):
@@ -211,6 +209,13 @@
i += 1
trace._annspecialcase_ = 'specialize:arg(2)'
+ def _call_custom_trace(self, obj, typeid, callback, arg):
+ def wrapper(item, arg):
+ if self.is_valid_gc_object(item):
+ callback(item, arg)
+
+ self.custom_trace_funcs[typeid.index](obj, wrapper, arg)
+
def _trace_slow_path(self, obj, callback, arg):
typeid = self.get_type_id(obj)
if self.has_gcptr_in_varsize(typeid):
@@ -228,14 +233,7 @@
item += itemlength
length -= 1
if self.has_custom_trace(typeid):
- generator = self.get_custom_trace(typeid)
- item = llmemory.NULL
- while True:
- item = generator(obj, item)
- if not item:
- break
- if self.points_to_valid_gc_object(item):
- callback(item, arg)
+ self._call_custom_trace(obj, typeid, callback, arg)
_trace_slow_path._annspecialcase_ = 'specialize:arg(2)'
def trace_partial(self, obj, start, stop, callback, arg):
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
@@ -127,12 +127,6 @@
infobits = self.get(typeid).infobits
return infobits & T_HAS_CUSTOM_TRACE != 0
- def q_get_custom_trace(self, typeid):
- ll_assert(self.q_has_custom_trace(typeid),
- "T_HAS_CUSTOM_TRACE missing")
- typeinfo = self.get(typeid)
- return typeinfo.finalizer_or_customtrace
-
def q_fast_path_tracing(self, typeid):
# return True if none of the flags T_HAS_GCPTR_IN_VARSIZE,
# T_IS_GCARRAY_OF_GCPTR or T_HAS_CUSTOM_TRACE is set
@@ -159,7 +153,6 @@
self.q_member_index,
self.q_is_rpython_class,
self.q_has_custom_trace,
- self.q_get_custom_trace,
self.q_fast_path_tracing)
@@ -204,10 +197,12 @@
infobits |= T_HAS_FINALIZER
elif kind == 'light_finalizer':
infobits |= T_HAS_FINALIZER | T_HAS_LIGHTWEIGHT_FINALIZER
- elif kind == "custom_trace":
- infobits |= T_HAS_CUSTOM_TRACE
else:
assert 0, kind
+ custom_trace_func = builder.get_custom_trace_func(TYPE)
+ if custom_trace_func is not None:
+ infobits |= T_HAS_CUSTOM_TRACE
+ builder.record_custom_trace(index, custom_trace_func)
#
if not TYPE._is_varsize():
info.fixedsize = llarena.round_up_for_allocation(
@@ -378,16 +373,11 @@
if TYPE in self._special_funcptrs:
return self._special_funcptrs[TYPE]
fptr1, is_lightweight = self.make_finalizer_funcptr_for_type(TYPE)
- fptr2 = self.make_custom_trace_funcptr_for_type(TYPE)
- assert not (fptr1 and fptr2), (
- "type %r needs both a finalizer and a custom tracer" % (TYPE,))
if fptr1:
if is_lightweight:
kind_and_fptr = "light_finalizer", fptr1
else:
kind_and_fptr = "finalizer", fptr1
- elif fptr2:
- kind_and_fptr = "custom_trace", fptr2
else:
kind_and_fptr = None
self._special_funcptrs[TYPE] = kind_and_fptr
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
@@ -25,9 +25,12 @@
def prepare_graphs(self, flowgraphs):
lltype2vtable = self.llinterp.typer.lltype2vtable
+ # only valid for direct layout builder
+ self.gc.custom_trace_funcs = {}
layoutbuilder = DirectRunLayoutBuilder(self.gc.__class__,
lltype2vtable,
- self.llinterp)
+ self.llinterp,
+ self.gc.custom_trace_funcs)
self.get_type_id = layoutbuilder.get_type_id
layoutbuilder.initialize_gc_query_function(self.gc)
@@ -200,9 +203,10 @@
class DirectRunLayoutBuilder(gctypelayout.TypeLayoutBuilder):
- def __init__(self, GCClass, lltype2vtable, llinterp):
+ def __init__(self, GCClass, lltype2vtable, llinterp, custom_trace_funcs):
self.llinterp = llinterp
super(DirectRunLayoutBuilder, self).__init__(GCClass, lltype2vtable)
+ self.custom_trace_funcs = custom_trace_funcs
def make_finalizer_funcptr_for_type(self, TYPE):
from pypy.rpython.memory.gctransform.support import get_rtti
@@ -227,11 +231,14 @@
return llmemory.NULL
return llhelper(gctypelayout.GCData.FINALIZER_OR_CT, ll_finalizer),
light
- def make_custom_trace_funcptr_for_type(self, TYPE):
+ def record_custom_trace(self, tid, custom_trace_func):
+ self.custom_trace_funcs[tid] = custom_trace_func
+
+ def get_custom_trace_func(self, TYPE):
from pypy.rpython.memory.gctransform.support import get_rtti
rtti = get_rtti(TYPE)
- if rtti is not None and hasattr(rtti._obj, 'custom_trace_funcptr'):
- return rtti._obj.custom_trace_funcptr
+ if rtti is not None and hasattr(rtti._obj, 'custom_trace_func'):
+ return rtti._obj.custom_trace_func
else:
return None
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
@@ -7,10 +7,11 @@
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 compute_unique_id, specialize
from pypy.rlib import rgc
from pypy.rlib.rstring import StringBuilder
from pypy.rlib.rarithmetic import LONG_BIT
+from pypy.jit.backend.llsupport import jitframe
WORD = LONG_BIT // 8
@@ -237,7 +238,6 @@
assert 160 <= res <= 165
def test_custom_trace(self):
- from pypy.rpython.annlowlevel import llhelper
from pypy.rpython.lltypesystem import llmemory
from pypy.rpython.lltypesystem.llarena import ArenaError
#
@@ -245,15 +245,10 @@
('y', 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 customtrace(obj, callback, arg):
+ callback(obj + offset_of_x, arg)
+
+ lltype.attachRuntimeTypeInfo(S, custom_trace_func=customtrace)
#
for attrname in ['x', 'y']:
def setup():
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit