Author: Armin Rigo <ar...@tunes.org>
Branch: gc-del-3
Changeset: r84184:70f42e6f2872
Date: 2016-05-04 10:00 +0200
http://bitbucket.org/pypy/pypy/changeset/70f42e6f2872/

Log:    in-progress: "test_transformed_gc -k Inc" seems happy

diff --git a/rpython/memory/gc/base.py b/rpython/memory/gc/base.py
--- a/rpython/memory/gc/base.py
+++ b/rpython/memory/gc/base.py
@@ -7,6 +7,7 @@
 from rpython.memory.support import get_address_stack, get_address_deque
 from rpython.memory.support import AddressDict, null_address_dict
 from rpython.rtyper.lltypesystem.llmemory import NULL, raw_malloc_usage
+from rpython.rtyper.annlowlevel import cast_adr_to_nongc_instance
 
 TYPEID_MAP = lltype.GcStruct('TYPEID_MAP', ('count', lltype.Signed),
                              ('size', lltype.Signed),
@@ -40,8 +41,8 @@
         self.finalizer_lock = False
 
     def mark_finalizer_to_run(self, fq_index, obj):
-        fdeque = self.get_run_finalizer_queue(self.AddressDeque, fq_index)
-        fdeque.append(obj)
+        handlers = self.finalizer_handlers()
+        self._adr2deque(handlers[fq_index].deque).append(obj)
 
     def post_setup(self):
         # More stuff that needs to be initialized when the GC is already
@@ -64,8 +65,7 @@
 
     def set_query_functions(self, is_varsize, has_gcptr_in_varsize,
                             is_gcarrayofgcptr,
-                            finalizer_trigger,
-                            get_run_finalizer_queue,
+                            finalizer_handlers,
                             destructor_or_custom_trace,
                             offsets_to_gc_pointers,
                             fixed_size, varsize_item_sizes,
@@ -79,8 +79,7 @@
                             fast_path_tracing,
                             has_gcptr,
                             cannot_pin):
-        self.finalizer_trigger = finalizer_trigger
-        self.get_run_finalizer_queue = get_run_finalizer_queue
+        self.finalizer_handlers = finalizer_handlers
         self.destructor_or_custom_trace = destructor_or_custom_trace
         self.is_varsize = is_varsize
         self.has_gcptr_in_varsize = has_gcptr_in_varsize
@@ -332,12 +331,10 @@
     enumerate_all_roots._annspecialcase_ = 'specialize:arg(1)'
 
     def enum_pending_finalizers(self, callback, arg):
+        handlers = self.finalizer_handlers()
         i = 0
-        while True:
-            fdeque = self.get_run_finalizer_queue(self.AddressDeque, i)
-            if fdeque is None:
-                break
-            fdeque.foreach(callback, arg)
+        while i < len(handlers):
+            self._adr2deque(handlers[i].deque).foreach(callback, arg)
             i += 1
     enum_pending_finalizers._annspecialcase_ = 'specialize:arg(1)'
 
@@ -379,23 +376,25 @@
     def debug_check_object(self, obj):
         pass
 
+    def _adr2deque(self, adr):
+        return cast_adr_to_nongc_instance(self.AddressDeque, adr)
+
     def execute_finalizers(self):
         if self.finalizer_lock:
             return  # the outer invocation of execute_finalizers() will do it
         self.finalizer_lock = True
         try:
+            handlers = self.finalizer_handlers()
             i = 0
-            while True:
-                fdeque = self.get_run_finalizer_queue(self.AddressDeque, i)
-                if fdeque is None:
-                    break
-                if fdeque.non_empty():
-                    self.finalizer_trigger(i)
+            while i < len(handlers):
+                if self._adr2deque(handlers[i].deque).non_empty():
+                    handlers[i].trigger()
                 i += 1
         finally:
             self.finalizer_lock = False
 
     def finalizer_next_dead(self, fq_index):
+        xxxxxxxxxxxx
         fdeque = self.get_run_finalizer_queue(self.AddressDeque, fq_index)
         if fdeque.non_empty():
             obj = fdeque.popleft()
diff --git a/rpython/memory/gc/incminimark.py b/rpython/memory/gc/incminimark.py
--- a/rpython/memory/gc/incminimark.py
+++ b/rpython/memory/gc/incminimark.py
@@ -1568,8 +1568,8 @@
     def register_finalizer(self, fq_index, gcobj):
         from rpython.rtyper.lltypesystem import rffi
         obj = llmemory.cast_ptr_to_adr(gcobj)
+        fq_index = rffi.cast(llmemory.Address, fq_index)
         self.probably_young_objects_with_finalizers.append(obj)
-        fq_index = rffi.cast(llmemory.Address, fq_index)
         self.probably_young_objects_with_finalizers.append(fq_index)
 
     # ----------
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
@@ -9,8 +9,10 @@
 from rpython.memory import gctypelayout
 from rpython.memory.gctransform.log import log
 from rpython.memory.gctransform.support import get_rtti, ll_call_destructor
+from rpython.memory.gctransform.support import ll_report_finalizer_error
 from rpython.memory.gctransform.transform import GCTransformer
 from rpython.memory.gctypelayout import ll_weakref_deref, WEAKREF, WEAKREFPTR
+from rpython.memory.gctypelayout import FIN_TRIGGER_FUNC, FIN_HANDLER_ARRAY
 from rpython.tool.sourcetools import func_with_new_name
 from rpython.translator.backendopt import graphanalyze
 from rpython.translator.backendopt.finalizer import FinalizerAnalyzer
@@ -181,9 +183,11 @@
         gcdata.max_type_id = 13                          # patched in finish()
         gcdata.typeids_z = a_random_address              # patched in finish()
         gcdata.typeids_list = a_random_address           # patched in finish()
+        gcdata.finalizer_handlers = a_random_address     # patched in finish()
         self.gcdata = gcdata
         self.malloc_fnptr_cache = {}
         self.finalizer_queue_indexes = {}
+        self.finalizer_handlers = []
 
         gcdata.gc = GCClass(translator.config.translation, **GC_PARAMS)
         root_walker = self.build_root_walker()
@@ -218,6 +222,7 @@
         data_classdef.generalize_attr('max_type_id', annmodel.SomeInteger())
         data_classdef.generalize_attr('typeids_z', SomeAddress())
         data_classdef.generalize_attr('typeids_list', SomeAddress())
+        data_classdef.generalize_attr('finalizer_handlers', SomeAddress())
 
         annhelper = annlowlevel.MixLevelHelperAnnotator(self.translator.rtyper)
 
@@ -256,7 +261,6 @@
 
         self.layoutbuilder.encode_type_shapes_now()
         self.create_custom_trace_funcs(gcdata.gc, translator.rtyper)
-        self.create_finalizer_trigger(gcdata)
 
         annhelper.finish()   # at this point, annotate all mix-level helpers
         annhelper.backend_optimize()
@@ -603,11 +607,6 @@
                     "the custom trace hook %r for %r can cause "
                     "the GC to be called!" % (func, TP))
 
-    def create_finalizer_trigger(self, gcdata):
-        def ll_finalizer_trigger(fq_index):
-            pass #xxxxxxxxxxxxx
-        gcdata.init_finalizer_trigger(ll_finalizer_trigger)
-
     def consider_constant(self, TYPE, value):
         self.layoutbuilder.consider_constant(TYPE, value, self.gcdata.gc)
 
@@ -692,8 +691,15 @@
         ll_instance.inst_typeids_list= 
llmemory.cast_ptr_to_adr(ll_typeids_list)
         newgcdependencies.append(ll_typeids_list)
         #
-        # update this field too
-        ll_instance.inst_run_finalizer_queues = 
self.gcdata.run_finalizer_queues
+        handlers = self.finalizer_handlers
+        ll_handlers = lltype.malloc(FIN_HANDLER_ARRAY, len(handlers),
+                                    immortal=True)
+        for i in range(len(handlers)):
+            ll_handlers[i].deque = handlers[i][0]
+            ll_handlers[i].trigger = handlers[i][1]
+        ll_instance.inst_finalizer_handlers = llmemory.cast_ptr_to_adr(
+            ll_handlers)
+        newgcdependencies.append(ll_handlers)
         #
         return newgcdependencies
 
@@ -1515,8 +1521,34 @@
         try:
             index = self.finalizer_queue_indexes[fq]
         except KeyError:
-            index = self.gcdata.register_next_finalizer_queue(
-                self.gcdata.gc.AddressDeque)
+            index = len(self.finalizer_queue_indexes)
+            assert index == len(self.finalizer_handlers)
+            deque = self.gcdata.gc.AddressDeque()
+            #
+            def ll_finalizer_trigger():
+                try:
+                    fq.finalizer_trigger()
+                except Exception as e:
+                    ll_report_finalizer_error(e)
+            ll_trigger = self.annotate_finalizer(ll_finalizer_trigger, [],
+                                                 lltype.Void)
+            def ll_next_dead():
+                if deque.non_empty():
+                    return deque.popleft()
+                else:
+                    return llmemory.NULL
+            ll_next_dead = self.annotate_finalizer(ll_next_dead, [],
+                                                   llmemory.Address)
+            c_ll_next_dead = rmodel.inputconst(lltype.typeOf(ll_next_dead),
+                                               ll_next_dead)
+            #
+            s_deque = 
self.translator.annotator.bookkeeper.immutablevalue(deque)
+            r_deque = self.translator.rtyper.getrepr(s_deque)
+            ll_deque = r_deque.convert_const(deque)
+            adr_deque = llmemory.cast_ptr_to_adr(ll_deque)
+            #
+            self.finalizer_handlers.append((adr_deque, ll_trigger,
+                                            c_ll_next_dead))
             self.finalizer_queue_indexes[fq] = index
         return index
 
@@ -1530,7 +1562,12 @@
                                   c_index, v_ptr])
 
     def gct_gc_fq_next_dead(self, hop):
-        xxxx
+        index = self.get_finalizer_queue_index(hop)
+        c_ll_next_dead = self.finalizer_handlers[index][2]
+        v_adr = hop.genop("direct_call", [c_ll_next_dead],
+                          resulttype=llmemory.Address)
+        hop.genop("cast_adr_to_ptr", [v_adr],
+                  resultvar = hop.spaceop.result)
 
 
 class TransformerLayoutBuilder(gctypelayout.TypeLayoutBuilder):
diff --git a/rpython/memory/gctransform/support.py 
b/rpython/memory/gctransform/support.py
--- a/rpython/memory/gctransform/support.py
+++ b/rpython/memory/gctransform/support.py
@@ -89,3 +89,11 @@
             write(2, " ignoring it\n")
         except:
             pass
+
+def ll_report_finalizer_error(e):
+    try:
+        write(2, "triggering finalizers raised an exception ")
+        write(2, str(e))
+        write(2, " ignoring it\n")
+    except:
+        pass
diff --git a/rpython/memory/gctypelayout.py b/rpython/memory/gctypelayout.py
--- a/rpython/memory/gctypelayout.py
+++ b/rpython/memory/gctypelayout.py
@@ -4,9 +4,6 @@
 from rpython.rlib.debug import ll_assert
 from rpython.rlib.rarithmetic import intmask
 from rpython.tool.identity_dict import identity_dict
-from rpython.memory.support import make_list_of_nongc_instances
-from rpython.memory.support import list_set_nongc_instance
-from rpython.memory.support import list_get_nongc_instance
 
 
 class GCData(object):
@@ -50,7 +47,6 @@
         assert isinstance(type_info_group, llgroup.group)
         self.type_info_group = type_info_group
         self.type_info_group_ptr = type_info_group._as_ptr()
-        self.run_finalizer_queues = make_list_of_nongc_instances(1)
 
     def get(self, typeid):
         res = llop.get_group_member(GCData.TYPE_INFO_PTR,
@@ -87,30 +83,9 @@
         ANY = (T_HAS_GCPTR | T_IS_WEAKREF)
         return (typeinfo.infobits & ANY) != 0 or bool(typeinfo.customfunc)
 
-    def init_finalizer_trigger(self, finalizer_trigger):
-        self._finalizer_trigger = finalizer_trigger
-
-    def register_next_finalizer_queue(self, AddressDeque):
-        "NOT_RPYTHON"
-        # 'self.run_finalizer_queues' has got no length, but is NULL-terminated
-        prevlength = self.run_finalizer_queues._obj.getlength()
-        array = make_list_of_nongc_instances(prevlength + 1)
-        for i in range(prevlength):
-            array[i] = self.run_finalizer_queues[i]
-        self.run_finalizer_queues = array
-        #
-        fq_index = prevlength - 1
-        assert fq_index >= 0
-        list_set_nongc_instance(self.run_finalizer_queues, fq_index,
-                                AddressDeque())
-        return fq_index
-
-    def q_finalizer_trigger(self, fq_index):
-        self._finalizer_trigger(fq_index)
-
-    def q_get_run_finalizer_queue(self, AddressDeque, fq_index):
-        return list_get_nongc_instance(AddressDeque,
-                                       self.run_finalizer_queues, fq_index)
+    def q_finalizer_handlers(self):
+        adr = self.finalizer_handlers   # set from framework.py or gcwrapper.py
+        return llmemory.cast_adr_to_ptr(adr, lltype.Ptr(FIN_HANDLER_ARRAY))
 
     def q_destructor_or_custom_trace(self, typeid):
         return self.get(typeid).customfunc
@@ -165,8 +140,7 @@
             self.q_is_varsize,
             self.q_has_gcptr_in_varsize,
             self.q_is_gcarrayofgcptr,
-            self.q_finalizer_trigger,
-            self.q_get_run_finalizer_queue,
+            self.q_finalizer_handlers,
             self.q_destructor_or_custom_trace,
             self.q_offsets_to_gc_pointers,
             self.q_fixed_size,
@@ -568,3 +542,9 @@
         link = lltype.malloc(WEAKREF, immortal=True)
         link.weakptr = llmemory.cast_ptr_to_adr(targetptr)
         return link
+
+########## finalizers ##########
+
+FIN_TRIGGER_FUNC = lltype.FuncType([], lltype.Void)
+FIN_HANDLER_ARRAY = lltype.Array(('deque', llmemory.Address),
+                                 ('trigger', lltype.Ptr(FIN_TRIGGER_FUNC)))
diff --git a/rpython/memory/support.py b/rpython/memory/support.py
--- a/rpython/memory/support.py
+++ b/rpython/memory/support.py
@@ -396,17 +396,3 @@
 def _null_value_checker(key, value, arg):
     if value:
         arg.setitem(key, value)
-
-# ____________________________________________________________
-
-NONGCARRAY = lltype.Array(NONGCOBJECTPTR, hints={'nolength': True})
-
-def make_list_of_nongc_instances(count):
-    return lltype.malloc(NONGCARRAY, count, flavor='raw', zero=True,
-                         track_allocation=False)
-
-def list_get_nongc_instance(Class, array, index):
-    return cast_base_ptr_to_nongc_instance(Class, array[index])
-
-def list_set_nongc_instance(array, index, instance):
-    array[index] = cast_nongc_instance_to_base_ptr(instance)
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
@@ -50,6 +50,8 @@
     taggedpointers = False
 
     def setup_class(cls):
+        if cls is not TestIncrementalMiniMarkGC:
+            py.test.skip("FOO")
         cls.marker = lltype.malloc(rffi.CArray(lltype.Signed), 1,
                                    flavor='raw', zero=True)
         funcs0 = []
diff --git a/rpython/rtyper/annlowlevel.py b/rpython/rtyper/annlowlevel.py
--- a/rpython/rtyper/annlowlevel.py
+++ b/rpython/rtyper/annlowlevel.py
@@ -526,6 +526,12 @@
     ptr = lltype.cast_opaque_ptr(OBJECTPTR, ptr)
     return cast_base_ptr_to_instance(Class, ptr)
 
+@specialize.arg(0)
+def cast_adr_to_nongc_instance(Class, ptr):
+    from rpython.rtyper.rclass import NONGCOBJECTPTR
+    ptr = llmemory.cast_adr_to_ptr(ptr, NONGCOBJECTPTR)
+    return cast_base_ptr_to_nongc_instance(Class, ptr)
+
 class CastBasePtrToInstanceEntry(extregistry.ExtRegistryEntry):
     _about_ = cast_base_ptr_to_instance
 
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to