[pypy-commit] pypy gc-del-3: update semispace

arigo pypy.commits at gmail.com
Wed May 4 12:11:15 EDT 2016


Author: Armin Rigo <arigo at tunes.org>
Branch: gc-del-3
Changeset: r84191:6343ed75104e
Date: 2016-05-04 18:11 +0200
http://bitbucket.org/pypy/pypy/changeset/6343ed75104e/

Log:	update semispace

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
@@ -347,6 +347,32 @@
             i += 1
     enum_pending_finalizers._annspecialcase_ = 'specialize:arg(1)'
 
+    def _copy_pending_finalizers_deque(self, deque, copy_fn):
+        tmp = self.AddressDeque()
+        while deque.non_empty():
+            obj = deque.popleft()
+            tmp.append(copy_fn(obj))
+        while tmp.non_empty():
+            deque.append(tmp.popleft())
+        tmp.delete()
+
+    def copy_pending_finalizers(self, copy_fn):
+        "NOTE: not very efficient, but only for SemiSpaceGC and subclasses"
+        self._copy_pending_finalizers_deque(
+            self.run_old_style_finalizers, copy_fn)
+        handlers = self.finalizer_handlers()
+        i = 0
+        while i < len(handlers):
+            h = handlers[i]
+            self._copy_pending_finalizers_deque(
+                self._adr2deque(h.deque), copy_fn)
+            i += 1
+
+    def call_destructor(self, obj):
+        destructor = self.destructor_or_custom_trace(self.get_type_id(obj))
+        ll_assert(bool(destructor), "no destructor found")
+        destructor(obj)
+
     def debug_check_consistency(self):
         """To use after a collection.  If self.DEBUG is set, this
         enumerates all roots and traces all objects to check if we didn't
@@ -402,8 +428,6 @@
             while self.run_old_style_finalizers.non_empty():
                 obj = self.run_old_style_finalizers.popleft()
                 typeid = self.get_type_id(obj)
-                ll_assert(self.is_old_style_finalizer(typeid),
-                          "bogus old-style finalizer")
                 finalizer = self.destructor_or_custom_trace(typeid)
                 finalizer(obj)
         finally:
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
@@ -2602,11 +2602,6 @@
     # ----------
     # Finalizers
 
-    def call_destructor(self, obj):
-        destructor = self.destructor_or_custom_trace(self.get_type_id(obj))
-        ll_assert(bool(destructor), "no destructor found")
-        destructor(obj)
-
     def deal_with_young_objects_with_destructors(self):
         """We can reasonably assume that destructors don't do
         anything fancy and *just* call them. Among other things
diff --git a/rpython/memory/gc/semispace.py b/rpython/memory/gc/semispace.py
--- a/rpython/memory/gc/semispace.py
+++ b/rpython/memory/gc/semispace.py
@@ -111,7 +111,9 @@
         #    self.objects_with_light_finalizers.append(result + size_gc_header)
         #else:
         if has_finalizer:
+            from rpython.rtyper.lltypesystem import rffi
             self.objects_with_finalizers.append(result + size_gc_header)
+            self.objects_with_finalizers.append(rffi.cast(llmemory.Address, -1))
         if contains_weakptr:
             self.objects_with_weakrefs.append(result + size_gc_header)
         return llmemory.cast_adr_to_ptr(result+size_gc_header, llmemory.GCREF)
@@ -149,6 +151,13 @@
         else:
             return False
 
+    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.objects_with_finalizers.append(obj)
+        self.objects_with_finalizers.append(fq_index)
+
     def obtain_free_space(self, needed):
         # a bit of tweaking to maximize the performance and minimize the
         # amount of code in an inlined version of malloc_fixedsize_clear()
@@ -268,8 +277,7 @@
         scan = self.free = tospace
         self.starting_full_collect()
         self.collect_roots()
-        if self.run_finalizers.non_empty():
-            self.update_run_finalizers()
+        self.copy_pending_finalizers(self.copy)
         scan = self.scan_copied(scan)
         if self.objects_with_light_finalizers.non_empty():
             self.deal_with_objects_with_light_finalizers()
@@ -499,8 +507,7 @@
             if self.surviving(obj):
                 new_objects.append(self.get_forwarding_address(obj))
             else:
-                finalizer = self.getfinalizer(self.get_type_id(obj))
-                finalizer(obj)
+                self.call_destructor(obj)
         self.objects_with_light_finalizers.delete()
         self.objects_with_light_finalizers = new_objects
 
@@ -517,12 +524,15 @@
         self.tmpstack = self.AddressStack()
         while self.objects_with_finalizers.non_empty():
             x = self.objects_with_finalizers.popleft()
+            fq_nr = self.objects_with_finalizers.popleft()
             ll_assert(self._finalization_state(x) != 1, 
                       "bad finalization state 1")
             if self.surviving(x):
                 new_with_finalizer.append(self.get_forwarding_address(x))
+                new_with_finalizer.append(fq_nr)
                 continue
             marked.append(x)
+            marked.append(fq_nr)
             pending.append(x)
             while pending.non_empty():
                 y = pending.pop()
@@ -537,17 +547,21 @@
 
         while marked.non_empty():
             x = marked.popleft()
+            fq_nr = marked.popleft()
             state = self._finalization_state(x)
             ll_assert(state >= 2, "unexpected finalization state < 2")
             newx = self.get_forwarding_address(x)
             if state == 2:
-                self.run_finalizers.append(newx)
+                from rpython.rtyper.lltypesystem import rffi
+                fq_index = rffi.cast(lltype.Signed, fq_nr)
+                self.mark_finalizer_to_run(fq_index, newx)
                 # we must also fix the state from 2 to 3 here, otherwise
                 # we leave the GCFLAG_FINALIZATION_ORDERING bit behind
                 # which will confuse the next collection
                 self._recursively_bump_finalization_state_from_2_to_3(x)
             else:
                 new_with_finalizer.append(newx)
+                new_with_finalizer.append(fq_nr)
 
         self.tmpstack.delete()
         pending.delete()
@@ -627,16 +641,6 @@
         self.objects_with_weakrefs.delete()
         self.objects_with_weakrefs = new_with_weakref
 
-    def update_run_finalizers(self):
-        # we are in an inner collection, caused by a finalizer
-        # the run_finalizers objects need to be copied
-        new_run_finalizer = self.AddressDeque()
-        while self.run_finalizers.non_empty():
-            obj = self.run_finalizers.popleft()
-            new_run_finalizer.append(self.copy(obj))
-        self.run_finalizers.delete()
-        self.run_finalizers = new_run_finalizer
-
     def _is_external(self, obj):
         return (self.header(obj).tid & GCFLAG_EXTERNAL) != 0
 


More information about the pypy-commit mailing list