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

Reply via email to