Author: Stefan Beyer <[email protected]>
Branch: cpyext-gc-cycle
Changeset: r96629:ec43b45f7cc4
Date: 2019-05-16 16:19 +0200
http://bitbucket.org/pypy/pypy/changeset/ec43b45f7cc4/

Log:    Added support for untracked objects in rawrefcount tests Fixed a bug
        in incminimark when using rawrefcounted modern finalizers

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
@@ -3401,11 +3401,19 @@
         # Only trace and mark rawrefcounted object if we are not doing
         # something special, like building gc.garbage.
         if self.rrc_state == self.RAWREFCOUNT_STATE_DEFAULT:
+            merged_old_list = False
             # check objects with finalizers from last collection cycle
             if not self._rrc_gc_list_is_empty(self.rrc_pyobj_old_list):
-                self._rrc_check_finalizer()
+                merged_old_list = self._rrc_check_finalizer()
             # collect all rawrefcounted roots
             self._rrc_collect_rawrefcount_roots(self.rrc_pyobj_list)
+            if merged_old_list:
+                # set all refcounts to zero for objects in dead list
+                # (might have been incremented) by fix_refcnt
+                gchdr = self.rrc_pyobj_dead_list.c_gc_next
+                while gchdr <> self.rrc_pyobj_dead_list:
+                    gchdr.c_gc_refs = 0
+                    gchdr = gchdr.c_gc_next
             self._rrc_debug_check_consistency(print_label="roots-marked")
             # mark all objects reachable from rawrefcounted roots
             self._rrc_mark_rawrefcount()
@@ -3740,10 +3748,12 @@
         if found_alive:
             self._rrc_gc_list_merge(self.rrc_pyobj_old_list,
                                     self.rrc_pyobj_list)
+            return False
         else:
             self._rrc_clear_weakref_callbacks()
             self._rrc_gc_list_merge(self.rrc_pyobj_old_list,
                                     self.rrc_pyobj_dead_list)
+            return True
 
     def _rrc_find_finalizer(self):
         found_finalizer = False
@@ -3841,10 +3851,11 @@
                                        should_print, "rrc_pyobj_old_list")
             self._rrc_debug_check_list(self.rrc_pyobj_dead_list,
                                        should_print, "rrc_pyobj_dead_list")
-            self._rrc_debug_check_list(self.rrc_pyobj_garbage_list,
-                                       should_print, "rrc_pyobj_garbage_list")
             self._rrc_debug_check_list(self.rrc_pyobj_isolate_list,
                                        should_print, "rrc_pyobj_isolate_list")
+            # rrc_pyobj_garbage_list is not a real list, it just marks the
+            # first and the last object in rrc_pyobj_list, which are garbage
+
             if should_print:
                 debug_stop("rrc-lists " + print_label)
 
diff --git a/rpython/memory/gc/test/dot/free_cpython_simple.dot 
b/rpython/memory/gc/test/dot/free_cpython_untracked_1.dot
copy from rpython/memory/gc/test/dot/free_cpython_simple.dot
copy to rpython/memory/gc/test/dot/free_cpython_untracked_1.dot
--- a/rpython/memory/gc/test/dot/free_cpython_simple.dot
+++ b/rpython/memory/gc/test/dot/free_cpython_untracked_1.dot
@@ -1,6 +1,8 @@
 digraph G {
     "a" [type=C, alive=n];
-    "b" [type=C, alive=n];
+    "b" [type=C, alive=n, tracked=n];
+    "c" [type=C, alive=n];
     "a" -> "b";
-    "b" -> "a";
+    "b" -> "c";
+    "c" -> "a"
 }
diff --git a/rpython/memory/gc/test/dot/keep_cpython_self.dot 
b/rpython/memory/gc/test/dot/keep_cpython_untracked_1.dot
copy from rpython/memory/gc/test/dot/keep_cpython_self.dot
copy to rpython/memory/gc/test/dot/keep_cpython_untracked_1.dot
--- a/rpython/memory/gc/test/dot/keep_cpython_self.dot
+++ b/rpython/memory/gc/test/dot/keep_cpython_untracked_1.dot
@@ -1,4 +1,8 @@
 digraph G {
     "a" [type=C, alive=y, ext_refcnt=1];
-    "a" -> "a";
+    "b" [type=C, alive=y, tracked=n];
+    "c" [type=C, alive=y];
+    "a" -> "b";
+    "b" -> "c";
+    "c" -> "a";
 }
diff --git a/rpython/memory/gc/test/test_rawrefcount.py 
b/rpython/memory/gc/test/test_rawrefcount.py
--- a/rpython/memory/gc/test/test_rawrefcount.py
+++ b/rpython/memory/gc/test/test_rawrefcount.py
@@ -12,6 +12,7 @@
 RAWREFCOUNT_FINALIZER_MODERN = IncMiniMark.RAWREFCOUNT_FINALIZER_MODERN
 RAWREFCOUNT_FINALIZER_LEGACY = IncMiniMark.RAWREFCOUNT_FINALIZER_LEGACY
 RAWREFCOUNT_FINALIZER_NONE = IncMiniMark.RAWREFCOUNT_FINALIZER_NONE
+RAWREFCOUNT_REFS_UNTRACKED = IncMiniMark.RAWREFCOUNT_REFS_UNTRACKED
 
 S = lltype.GcForwardReference()
 S.become(lltype.GcStruct('S',
@@ -136,7 +137,8 @@
 
         return p1, p1ref, check_alive
 
-    def _rawrefcount_pyobj(self, create_immortal=False, is_gc=True):
+    def _rawrefcount_pyobj(self, create_immortal=False, is_gc=True,
+                           tracked=True):
         r1 = lltype.malloc(PYOBJ_HDR, flavor='raw',
                            immortal=create_immortal)
         r1.c_ob_refcnt = 0
@@ -144,13 +146,7 @@
         r1addr = llmemory.cast_ptr_to_adr(r1)
 
         if is_gc:
-            r1gc = lltype.malloc(PYOBJ_GC_HDR, flavor='raw',
-                                 immortal=True)
-            r1gc.c_gc_next = self.pyobj_list
-            r1gc.c_gc_prev = self.pyobj_list.c_gc_prev
-            r1gc.c_gc_prev.c_gc_next = r1gc
-            self.pyobj_list.c_gc_prev = r1gc
-            self.gcobjs.append(r1gc)
+            self._rawrefcount_add_gc(tracked)
 
         self.pyobjs.append(r1)
         self.is_pygc.append(is_gc)
@@ -164,7 +160,8 @@
 
     def _rawrefcount_pair(self, intval, is_light=False, is_pyobj=False,
                           create_old=False, create_immortal=False,
-                          rooted=False, force_external=False, is_gc=True):
+                          rooted=False, force_external=False, is_gc=True,
+                          tracked=True):
         if is_light:
             rc = REFCNT_FROM_PYPY_LIGHT
         else:
@@ -197,13 +194,7 @@
         r1addr = llmemory.cast_ptr_to_adr(r1)
 
         if is_gc:
-            r1gc = lltype.malloc(PYOBJ_GC_HDR, flavor='raw',
-                                 immortal=True)
-            r1gc.c_gc_next = self.pyobj_list
-            r1gc.c_gc_prev = self.pyobj_list.c_gc_prev
-            r1gc.c_gc_prev.c_gc_next = r1gc
-            self.pyobj_list.c_gc_prev = r1gc
-            self.gcobjs.append(r1gc)
+            self._rawrefcount_add_gc(tracked)
 
         self.pyobjs.append(r1)
         self.is_pygc.append(is_gc)
@@ -231,6 +222,19 @@
             return p1
         return p1, p1ref, r1, r1addr, check_alive
 
+    def _rawrefcount_add_gc(self, tracked):
+        r1gc = lltype.malloc(PYOBJ_GC_HDR, flavor='raw',
+                             immortal=True)
+        self.gcobjs.append(r1gc)
+        if tracked:
+            r1gc.c_gc_refs = 0
+            r1gc.c_gc_next = self.pyobj_list
+            r1gc.c_gc_prev = self.pyobj_list.c_gc_prev
+            r1gc.c_gc_prev.c_gc_next = r1gc
+            self.pyobj_list.c_gc_prev = r1gc
+        else:
+            r1gc.c_gc_refs = RAWREFCOUNT_REFS_UNTRACKED
+
     def test_rawrefcount_objects_basic(self, old=False):
         p1, p1ref, r1, r1addr, check_alive = (
             self._rawrefcount_pair(42, is_light=True, create_old=old))
@@ -519,6 +523,7 @@
             rooted = attr['rooted'] == "y" if 'rooted' in attr else False
             ext_refcnt = int(attr['ext_refcnt']) if 'ext_refcnt' in attr else 0
             finalizer = attr['finalizer'] if 'finalizer' in attr else None
+            tracked = attr['tracked'] == "y" if 'tracked' in attr else True
             if finalizer == "modern":
                 finalizers = True
             resurrect = attr['resurrect'] if 'resurrect' in attr else None
@@ -527,7 +532,8 @@
             info = NodeInfo(type, alive, ext_refcnt, finalizer, resurrect,
                             delete, garbage)
             if type == "C":
-                r, raddr, check_alive = self._rawrefcount_pyobj()
+                r, raddr, check_alive = self._rawrefcount_pyobj(
+                    tracked=tracked)
                 r.c_ob_refcnt += ext_refcnt
                 nodes[name] = CPythonNode(r, raddr, check_alive, info)
             elif type == "P":
@@ -539,7 +545,7 @@
             elif type == "B":
                 p, pref, r, raddr, check_alive =\
                     self._rawrefcount_pair(42 + i, rooted=rooted,
-                                           create_old=True)
+                                           create_old=True, tracked=tracked)
                 r.c_ob_refcnt += ext_refcnt
                 nodes[name] = BorderNode(p, pref, r, raddr, check_alive, info)
                 i += 1
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to