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