Author: Armin Rigo <ar...@tunes.org> Branch: improve-gc-tracing-hooks Changeset: r74030:00d7923edeea Date: 2014-10-21 13:33 +0200 http://bitbucket.org/pypy/pypy/changeset/00d7923edeea/
Log: Shuffle shuffle shuffle until test_transformed_gc is happy diff --git a/rpython/memory/gctransform/framework.py b/rpython/memory/gctransform/framework.py --- a/rpython/memory/gctransform/framework.py +++ b/rpython/memory/gctransform/framework.py @@ -5,7 +5,7 @@ from rpython.rlib.unroll import unrolling_iterable from rpython.rtyper import rmodel, annlowlevel from rpython.rtyper.lltypesystem import lltype, llmemory, rffi, llgroup -from rpython.rtyper.lltypesystem.lloperation import LL_OPERATIONS +from rpython.rtyper.lltypesystem.lloperation import LL_OPERATIONS, llop from rpython.memory import gctypelayout from rpython.memory.gctransform.log import log from rpython.memory.gctransform.support import get_rtti, ll_call_destructor @@ -174,8 +174,6 @@ self.malloc_fnptr_cache = {} gcdata.gc = GCClass(translator.config.translation, **GC_PARAMS) - self.create_custom_trace_funcs(gcdata.gc, - translator.rtyper.custom_trace_funcs) root_walker = self.build_root_walker() root_walker.finished_minor_collection_func = finished_minor_collection self.root_walker = root_walker @@ -243,6 +241,8 @@ root_walker.need_stacklet_support(self, getfn) self.layoutbuilder.encode_type_shapes_now() + self.create_custom_trace_funcs(gcdata.gc, + translator.rtyper.custom_trace_funcs) annhelper.finish() # at this point, annotate all mix-level helpers annhelper.backend_optimize() @@ -498,19 +498,21 @@ custom_trace_funcs_unrolled = unrolling_iterable( [(self.get_type_id(TP), func) for TP, func in custom_trace_funcs]) - @specialize.arg(3) - def custom_trace_dispatcher(self, obj, typeid, callback, arg): + @specialize.arg(2) + def custom_trace_dispatcher(obj, typeid, callback, arg): for type_id_exp, func in custom_trace_funcs_unrolled: - if typeid == type_id_exp: - func(obj, callback, arg) + if (llop.combine_ushort(lltype.Signed, typeid, 0) == + llop.combine_ushort(lltype.Signed, type_id_exp, 0)): + func(gc, obj, callback, arg) return else: assert False - gc.__class__.custom_trace_dispatcher = custom_trace_dispatcher + gc.custom_trace_dispatcher = custom_trace_dispatcher for TP, func in custom_trace_funcs: - specialize.arg(1)(func) + self.gcdata._has_got_custom_trace(self.get_type_id(TP)) + specialize.arg(2)(func) def consider_constant(self, TYPE, value): self.layoutbuilder.consider_constant(TYPE, value, self.gcdata.gc) diff --git a/rpython/memory/gctypelayout.py b/rpython/memory/gctypelayout.py --- a/rpython/memory/gctypelayout.py +++ b/rpython/memory/gctypelayout.py @@ -151,6 +151,10 @@ self.q_fast_path_tracing, self.q_has_gcptr) + def _has_got_custom_trace(self, typeid): + type_info = self.get(typeid) + type_info.infobits |= (T_HAS_CUSTOM_TRACE | T_HAS_GCPTR) + # the lowest 16bits are used to store group member index T_MEMBER_INDEX = 0xffff diff --git a/rpython/memory/gcwrapper.py b/rpython/memory/gcwrapper.py --- a/rpython/memory/gcwrapper.py +++ b/rpython/memory/gcwrapper.py @@ -47,15 +47,13 @@ def custom_trace(obj, typeid, callback, arg): for TP, func in custom_trace_funcs: if typeid == self.get_type_id(TP): - func(obj, callback, arg) + func(self.gc, obj, callback, arg) return else: assert False for TP, func in custom_trace_funcs: - type_info = gcdata.get(self.get_type_id(TP)) - type_info.infobits |= (gctypelayout.T_HAS_CUSTOM_TRACE | - gctypelayout.T_HAS_GCPTR) + gcdata._has_got_custom_trace(self.get_type_id(TP)) self.gc.custom_trace_dispatcher = custom_trace diff --git a/rpython/memory/test/gc_test_base.py b/rpython/memory/test/gc_test_base.py --- a/rpython/memory/test/gc_test_base.py +++ b/rpython/memory/test/gc_test_base.py @@ -244,12 +244,14 @@ ('y', llmemory.Address)) T = lltype.GcStruct('T', ('z', lltype.Signed)) offset_of_x = llmemory.offsetof(S, 'x') - def customtrace(obj, callback, arg): - callback(obj + offset_of_x, arg) + def customtrace(gc, obj, callback, arg): + if gc.is_valid_gc_object((obj + offset_of_x).address[0]): + callback(obj + offset_of_x, arg) + lambda_customtrace = lambda: customtrace # for attrname in ['x', 'y']: def setup(): - rgc.register_custom_trace_hook(S, customtrace) + rgc.register_custom_trace_hook(S, lambda_customtrace) s1 = lltype.malloc(S) tx = lltype.malloc(T) tx.z = 42 @@ -760,11 +762,12 @@ S = lltype.GcStruct('S', ('x', lltype.Signed)) called = [] - def trace_hook(obj, callback, arg): + def trace_hook(gc, obj, callback, arg): called.append("called") + lambda_trace_hook = lambda: trace_hook def f(): - rgc.register_custom_trace_hook(S, trace_hook) + rgc.register_custom_trace_hook(S, lambda_trace_hook) s = lltype.malloc(S) rgc.collect() keepalive_until_here(s) diff --git a/rpython/memory/test/test_transformed_gc.py b/rpython/memory/test/test_transformed_gc.py --- a/rpython/memory/test/test_transformed_gc.py +++ b/rpython/memory/test/test_transformed_gc.py @@ -389,15 +389,17 @@ S = lltype.GcStruct('S', ('x', llmemory.Address)) T = lltype.GcStruct('T', ('z', lltype.Signed)) offset_of_x = llmemory.offsetof(S, 'x') - def customtrace(obj, callback, arg): - callback(obj + offset_of_x, arg) + def customtrace(gc, obj, callback, arg): + if gc.is_valid_gc_object((obj + offset_of_x).address[0]): + callback(obj + offset_of_x, arg) + lambda_customtrace = lambda: customtrace # def setup(): - rgc.register_custom_trace_hook(S, customtrace) - s1 = lltype.malloc(S) + rgc.register_custom_trace_hook(S, lambda_customtrace) tx = lltype.malloc(T) tx.z = 4243 + s1 = lltype.malloc(S) s1.x = llmemory.cast_ptr_to_adr(tx) return s1 def f(): diff --git a/rpython/rlib/rgc.py b/rpython/rlib/rgc.py --- a/rpython/rlib/rgc.py +++ b/rpython/rlib/rgc.py @@ -550,10 +550,11 @@ def lltype_is_gc(TP): return getattr(getattr(TP, "TO", None), "_gckind", "?") == 'gc' -def register_custom_trace_hook(TP, func): +def register_custom_trace_hook(TP, lambda_func): """ This function does not do anything, but called from any annotated place, will tell that "func" is used to trace GC roots inside any instance - of the type TP + of the type TP. The func must be specified as "lambda: func" in this + call, for internal reasons. """ class RegisterGcTraceEntry(ExtRegistryEntry): @@ -564,6 +565,6 @@ def specialize_call(self, hop): TP = hop.args_s[0].const - func = hop.args_s[1].const + lambda_func = hop.args_s[1].const hop.exception_cannot_occur() - hop.rtyper.custom_trace_funcs.append((TP, func)) + hop.rtyper.custom_trace_funcs.append((TP, lambda_func())) diff --git a/rpython/rlib/test/test_rgc.py b/rpython/rlib/test/test_rgc.py --- a/rpython/rlib/test/test_rgc.py +++ b/rpython/rlib/test/test_rgc.py @@ -234,9 +234,10 @@ def trace_func(): xxx # should not be annotated here + lambda_trace_func = lambda: trace_func def f(): - rgc.register_custom_trace_hook(TP, trace_func) + rgc.register_custom_trace_hook(TP, lambda_trace_func) t, typer, graph = gengraph(f, []) diff --git a/rpython/rtyper/lltypesystem/opimpl.py b/rpython/rtyper/lltypesystem/opimpl.py --- a/rpython/rtyper/lltypesystem/opimpl.py +++ b/rpython/rtyper/lltypesystem/opimpl.py @@ -82,13 +82,11 @@ else: def op_function(x, y): if not isinstance(x, argtype): - if not (isinstance(x, AddressAsInt) and argtype is int): - raise TypeError("%r arg 1 must be %s, got %r instead"% ( - fullopname, typname, type(x).__name__)) + raise TypeError("%r arg 1 must be %s, got %r instead"% ( + fullopname, typname, type(x).__name__)) if not isinstance(y, argtype): - if not (isinstance(y, AddressAsInt) and argtype is int): - raise TypeError("%r arg 2 must be %s, got %r instead"% ( - fullopname, typname, type(y).__name__)) + raise TypeError("%r arg 2 must be %s, got %r instead"% ( + fullopname, typname, type(y).__name__)) return adjust_result(func(x, y)) return func_with_new_name(op_function, 'op_' + fullopname) @@ -104,6 +102,19 @@ lltype.typeOf(adr),)) +def op_int_eq(x, y): + if not isinstance(x, (int, long)): + from rpython.rtyper.lltypesystem import llgroup + assert isinstance(x, llgroup.CombinedSymbolic), ( + "'int_eq' arg 1 must be int-like, got %r instead" % ( + type(x).__name__,)) + if not isinstance(y, (int, long)): + from rpython.rtyper.lltypesystem import llgroup + assert isinstance(y, llgroup.CombinedSymbolic), ( + "'int_eq' arg 2 must be int-like, got %r instead" % ( + type(y).__name__,)) + return x == y + def op_ptr_eq(ptr1, ptr2): checkptr(ptr1) checkptr(ptr2) _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit