Author: Maciej Fijalkowski <[email protected]>
Branch: imrpove-custom-gc-tracing
Changeset: r60192:b103c0c9fec5
Date: 2013-01-19 11:32 +0200
http://bitbucket.org/pypy/pypy/changeset/b103c0c9fec5/

Log:    work in progress not sure where to go from here

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
@@ -500,6 +500,7 @@
     'gc_gcflag_extra'     : LLOp(),
     'gc_add_memory_pressure': LLOp(),
     'gc_set_extra_threshold': LLOp(canrun=True, canmallocgc=True),
+    'gc_call_custom_trace': LLOp(canrun=True), # cannot malloc
 
     # ------- JIT & GC interaction, only for some GCs ----------
 
diff --git a/pypy/rpython/lltypesystem/opimpl.py 
b/pypy/rpython/lltypesystem/opimpl.py
--- a/pypy/rpython/lltypesystem/opimpl.py
+++ b/pypy/rpython/lltypesystem/opimpl.py
@@ -647,6 +647,9 @@
 def op_gc_set_extra_threshold(threshold):
     pass
 
+def op_gc_call_custom_trace(gc, *args):
+    gc._call_custom_trace(*args)
+
 def op_shrink_array(array, smallersize):
     return False
 
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
@@ -6,6 +6,7 @@
 from pypy.rpython.memory.support import get_address_stack, get_address_deque
 from pypy.rpython.memory.support import AddressDict, null_address_dict
 from pypy.rpython.lltypesystem.llmemory import NULL, raw_malloc_usage
+from pypy.rlib.objectmodel import specialize
 
 TYPEID_MAP = lltype.GcStruct('TYPEID_MAP', ('count', lltype.Signed),
                              ('size', lltype.Signed),
@@ -210,11 +211,13 @@
     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 wrapper(item, arg):
+        #    if self.is_valid_gc_object(item):
+        #        callback(item, arg)
+
+        for obj_typeid, func in self.custom_trace_funcs:
+            if typeid == obj_typeid:
+                func(obj, callback, arg)
 
     def _trace_slow_path(self, obj, callback, arg):
         typeid = self.get_type_id(obj)
@@ -233,7 +236,10 @@
                 item += itemlength
                 length -= 1
         if self.has_custom_trace(typeid):
-            self._call_custom_trace(obj, typeid, callback, arg)
+            # an obscure hack to flow those only when we
+            # actually have all typeids
+            llop.gc_call_custom_trace(lltype.Void, self, 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/gctransform/framework.py 
b/pypy/rpython/memory/gctransform/framework.py
--- a/pypy/rpython/memory/gctransform/framework.py
+++ b/pypy/rpython/memory/gctransform/framework.py
@@ -888,6 +888,11 @@
                                   source_addr, dest_addr] + op.args[2:],
                   resultvar=op.result)
 
+    def gct_gc_call_custom_trace(self, hop):
+        args = hop.spaceop.args
+        args[3].concretetype
+        hop.genop('direct_call', [])
+
     def gct_weakref_create(self, hop):
         op = hop.spaceop
 
@@ -1216,6 +1221,7 @@
         else:
             lltype2vtable = None
         self.translator = translator
+        self.custom_trace_funcs = []
         super(TransformerLayoutBuilder, self).__init__(GCClass, lltype2vtable)
 
     def has_finalizer(self, TYPE):
@@ -1229,7 +1235,7 @@
 
     def has_custom_trace(self, TYPE):
         rtti = get_rtti(TYPE)
-        return rtti is not None and getattr(rtti._obj, 'custom_trace_funcptr',
+        return rtti is not None and getattr(rtti._obj, 'custom_trace_func',
                                             None)
 
     def make_finalizer_funcptr_for_type(self, TYPE):
@@ -1249,16 +1255,14 @@
         light = not 
FinalizerAnalyzer(self.translator).analyze_light_finalizer(g)
         return fptr, light
 
-    def make_custom_trace_funcptr_for_type(self, TYPE):
+    def get_custom_trace_func(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
+        return rtti._obj.custom_trace_func
+
+    def record_custom_trace(self, typeid, custom_trace_func):
+        self.custom_trace_funcs.append((typeid, custom_trace_func))
 
 
 def gen_zero_gc_pointers(TYPE, v, llops, previous_steps=None):
diff --git a/pypy/rpython/memory/gctransform/transform.py 
b/pypy/rpython/memory/gctransform/transform.py
--- a/pypy/rpython/memory/gctransform/transform.py
+++ b/pypy/rpython/memory/gctransform/transform.py
@@ -103,6 +103,7 @@
             self.minimalgctransformer = self.MinimalGCTransformer(self)
         else:
             self.minimalgctransformer = None
+        self.call_custom_trace_cache = {}
 
     def get_lltype_of_exception_value(self):
         exceptiondata = self.translator.rtyper.getexceptiondata()
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
@@ -183,7 +183,7 @@
               "invalid type_id")
 
 
-def encode_type_shape(builder, info, TYPE, index):
+def encode_type_shape(builder, info, TYPE, index, type_id):
     """Encode the shape of the TYPE into the TYPE_INFO structure 'info'."""
     offsets = offsets_to_gc_pointers(TYPE)
     infobits = index
@@ -202,7 +202,7 @@
     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)
+        builder.record_custom_trace(type_id, custom_trace_func)
     #
     if not TYPE._is_varsize():
         info.fixedsize = llarena.round_up_for_allocation(
@@ -296,9 +296,10 @@
                 info = fullinfo.header
             type_id = self.type_info_group.add_member(fullinfo)
             if self.can_encode_type_shape:
-                encode_type_shape(self, info, TYPE, type_id.index)
+                encode_type_shape(self, info, TYPE, type_id.index, type_id)
             else:
-                self._pending_type_shapes.append((info, TYPE, type_id.index))
+                self._pending_type_shapes.append((info, TYPE, type_id.index,
+                                                  type_id))
             # store it
             self.id_of_type[TYPE] = type_id
             self.add_vtable_after_typeinfo(TYPE)
@@ -341,8 +342,8 @@
     def encode_type_shapes_now(self):
         if not self.can_encode_type_shape:
             self.can_encode_type_shape = True
-            for info, TYPE, index in self._pending_type_shapes:
-                encode_type_shape(self, info, TYPE, index)
+            for info, TYPE, index, type_id in self._pending_type_shapes:
+                encode_type_shape(self, info, TYPE, index, type_id)
             del self._pending_type_shapes
 
     def delay_encoding(self):
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
@@ -26,7 +26,7 @@
     def prepare_graphs(self, flowgraphs):
         lltype2vtable = self.llinterp.typer.lltype2vtable
         # only valid for direct layout builder
-        self.gc.custom_trace_funcs = {}
+        self.gc.custom_trace_funcs = []
         layoutbuilder = DirectRunLayoutBuilder(self.gc.__class__,
                                                lltype2vtable,
                                                self.llinterp,
@@ -232,7 +232,7 @@
         return llhelper(gctypelayout.GCData.FINALIZER_OR_CT, ll_finalizer), 
light
 
     def record_custom_trace(self, tid, custom_trace_func):
-        self.custom_trace_funcs[tid] = custom_trace_func
+        self.custom_trace_funcs.append((tid, custom_trace_func))
 
     def get_custom_trace_func(self, TYPE):
         from pypy.rpython.memory.gctransform.support import get_rtti
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
@@ -382,21 +382,13 @@
         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 customtrace(obj, callback, arg):
+            callback(obj + offset_of_x, arg)
+        lltype.attachRuntimeTypeInfo(S, custom_trace_func=customtrace)
         #
         def setup():
             s1 = lltype.malloc(S)
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to