Author: Stefan Beyer <[email protected]>
Branch: cpyext-gc-cycle
Changeset: r96125:a3d95a9939f4
Date: 2019-02-22 11:27 +0100
http://bitbucket.org/pypy/pypy/changeset/a3d95a9939f4/
Log: Added more tests for "modern" rawrefcount finalizers
diff --git a/rpython/memory/gc/test/dot/free_finalizer_nocycle.dot
b/rpython/memory/gc/test/dot/free_finalizer_nocycle_1a.dot
rename from rpython/memory/gc/test/dot/free_finalizer_nocycle.dot
rename to rpython/memory/gc/test/dot/free_finalizer_nocycle_1a.dot
diff --git a/rpython/memory/gc/test/dot/free_finalizer_nocycle.dot
b/rpython/memory/gc/test/dot/free_finalizer_nocycle_1b.dot
copy from rpython/memory/gc/test/dot/free_finalizer_nocycle.dot
copy to rpython/memory/gc/test/dot/free_finalizer_nocycle_1b.dot
--- a/rpython/memory/gc/test/dot/free_finalizer_nocycle.dot
+++ b/rpython/memory/gc/test/dot/free_finalizer_nocycle_1b.dot
@@ -1,7 +1,7 @@
digraph G {
"a" [type=P, alive=n];
"b" [type=B, alive=n];
- "c" [type=C, alive=n, finalizer=modern];
+ "c" [type=C, alive=n, finalizer=modern, delete="d"];
"d" [type=C, alive=n];
"e" [type=B, alive=n];
"f" [type=P, alive=n];
diff --git a/rpython/memory/gc/test/dot/free_finalizer_nocycle.dot
b/rpython/memory/gc/test/dot/free_finalizer_nocycle_1c.dot
copy from rpython/memory/gc/test/dot/free_finalizer_nocycle.dot
copy to rpython/memory/gc/test/dot/free_finalizer_nocycle_1c.dot
--- a/rpython/memory/gc/test/dot/free_finalizer_nocycle.dot
+++ b/rpython/memory/gc/test/dot/free_finalizer_nocycle_1c.dot
@@ -1,8 +1,8 @@
digraph G {
"a" [type=P, alive=n];
"b" [type=B, alive=n];
- "c" [type=C, alive=n, finalizer=modern];
- "d" [type=C, alive=n];
+ "c" [type=C, alive=n, finalizer=modern, delete="d"];
+ "d" [type=C, alive=n, finalizer=modern, delete="e"];
"e" [type=B, alive=n];
"f" [type=P, alive=n];
"a" -> "b";
diff --git a/rpython/memory/gc/test/dot/free_finalizer_simple.dot
b/rpython/memory/gc/test/dot/free_finalizer_simple_1a.dot
rename from rpython/memory/gc/test/dot/free_finalizer_simple.dot
rename to rpython/memory/gc/test/dot/free_finalizer_simple_1a.dot
diff --git a/rpython/memory/gc/test/dot/free_finalizer_simple.dot
b/rpython/memory/gc/test/dot/free_finalizer_simple_1b.dot
copy from rpython/memory/gc/test/dot/free_finalizer_simple.dot
copy to rpython/memory/gc/test/dot/free_finalizer_simple_1b.dot
--- a/rpython/memory/gc/test/dot/free_finalizer_simple.dot
+++ b/rpython/memory/gc/test/dot/free_finalizer_simple_1b.dot
@@ -1,7 +1,7 @@
digraph G {
"a" [type=P, alive=n];
"b" [type=B, alive=n];
- "c" [type=C, alive=n, finalizer=modern];
+ "c" [type=C, alive=n, finalizer=modern, delete="d"];
"d" [type=C, alive=n];
"e" [type=B, alive=n];
"f" [type=P, alive=n];
diff --git a/rpython/memory/gc/test/dot/keep_finalizer_simple.dot
b/rpython/memory/gc/test/dot/keep_finalizer_simple_1a.dot
rename from rpython/memory/gc/test/dot/keep_finalizer_simple.dot
rename to rpython/memory/gc/test/dot/keep_finalizer_simple_1a.dot
diff --git a/rpython/memory/gc/test/dot/keep_finalizer_simple.dot
b/rpython/memory/gc/test/dot/keep_finalizer_simple_1b.dot
copy from rpython/memory/gc/test/dot/keep_finalizer_simple.dot
copy to rpython/memory/gc/test/dot/keep_finalizer_simple_1b.dot
--- a/rpython/memory/gc/test/dot/keep_finalizer_simple.dot
+++ b/rpython/memory/gc/test/dot/keep_finalizer_simple_1b.dot
@@ -1,7 +1,7 @@
digraph G {
"a" [type=P, alive=y];
"b" [type=B, alive=y];
- "c" [type=C, alive=y, finalizer=modern, resurrect="d"];
+ "c" [type=C, alive=y, finalizer=modern, resurrect="c"];
"d" [type=C, alive=y];
"e" [type=B, alive=y];
"f" [type=P, alive=y];
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
@@ -31,7 +31,9 @@
self.pyobjs = []
self.pyobj_refs = []
self.pyobj_finalizer = {}
+ self.pyobj_finalized = {}
self.pyobj_resurrect = {}
+ self.pyobj_delete = {}
def rawrefcount_tp_traverse(obj, callback, args):
refs = self.pyobj_refs[self.pyobjs.index(obj)]
@@ -85,6 +87,10 @@
refs = self.pyobj_resurrect[self.pyobjs.index(pyobj_source)] = []
refs.append(pyobj_target)
+ def _rawrefcount_add_delete(self, pyobj_source, pyobj_target):
+ refs = self.pyobj_delete[self.pyobjs.index(pyobj_source)] = []
+ refs.append(pyobj_target)
+
def _rawrefcount_pypyobj(self, intval, rooted=False, create_old=True):
p1 = self.malloc(S)
p1.x = intval
@@ -412,8 +418,6 @@
@py.test.mark.parametrize("file", dot_files)
def test_dots(self, file):
from rpython.memory.gc.test.dot import pydot
- from rpython.rlib.rawrefcount import REFCNT_FROM_PYPY
- from rpython.rlib.rawrefcount import REFCNT_FROM_PYPY_LIGHT
class Node:
def __init__(self, info):
@@ -443,12 +447,14 @@
self.info = info
class NodeInfo:
- def __init__(self, type, alive, ext_refcnt, finalizer, resurrect):
+ def __init__(self, type, alive, ext_refcnt, finalizer, resurrect,
+ delete):
self.type = type
self.alive = alive
self.ext_refcnt = ext_refcnt
self.finalizer = finalizer
self.resurrect = resurrect
+ self.delete = delete
path = os.path.join(self.dot_dir, file)
g = pydot.graph_from_dot_file(path)[0]
@@ -468,7 +474,9 @@
if finalizer <> None:
finalizers = True
resurrect = attr['resurrect'] if 'resurrect' in attr else None
- info = NodeInfo(type, alive, ext_refcnt, finalizer, resurrect)
+ delete = attr['delete'] if 'delete' in attr else None
+ info = NodeInfo(type, alive, ext_refcnt, finalizer, resurrect,
+ delete)
if type == "C":
r, raddr, check_alive = self._rawrefcount_pyobj()
r.c_ob_refcnt += ext_refcnt
@@ -509,10 +517,15 @@
if hasattr(n, "r"):
index = self.pyobjs.index(n.r)
resurrect = n.info.resurrect
- if n.info.finalizer == "modern" and resurrect is not None:
+ delete = n.info.delete
+ if n.info.finalizer == "modern":
self.pyobj_finalizer[index] = RAWREFCOUNT_FINALIZER_MODERN
- self._rawrefcount_add_resurrect(n.r, nodes[resurrect].r)
- nodes[resurrect].info.ext_refcnt += 1
+ if resurrect is not None:
+ self._rawrefcount_add_resurrect(n.r,
+ nodes[resurrect].r)
+ nodes[resurrect].info.ext_refcnt += 1
+ if delete is not None:
+ self._rawrefcount_add_delete(n.r, nodes[delete].r)
else:
self.pyobj_finalizer[index] = RAWREFCOUNT_FINALIZER_NONE
@@ -534,18 +547,32 @@
def cleanup():
# do cleanup after collection (clear all dead pyobjects)
+ def finalize_modern(pyobj):
+ index = self.pyobjs.index(pyobj)
+ if not self.pyobj_finalizer.has_key(index) or \
+ self.pyobj_finalizer[index] != \
+ RAWREFCOUNT_FINALIZER_MODERN:
+ return
+ if self.pyobj_finalized.has_key(index):
+ return
+ self.pyobj_finalized[index] = True
+ if self.pyobj_resurrect.has_key(index):
+ resurrect = self.pyobj_resurrect[index]
+ for r in resurrect:
+ r.c_ob_refcnt += 1
+ if self.pyobj_delete.has_key(index):
+ delete = self.pyobj_delete[index]
+ for r in delete:
+ self.pyobj_refs[index].remove(r)
+ decref(r, None)
+
def decref_children(pyobj):
self.gc.rrc_tp_traverse(pyobj, decref, None)
def decref(pyobj, ignore):
pyobj.c_ob_refcnt -= 1
if pyobj.c_ob_refcnt == 0:
- if self.pyobj_resurrect.has_key(self.pyobjs.index(pyobj)):
- resurrect = self.pyobj_resurrect[
- self.pyobjs.index(pyobj)]
- for r in resurrect:
- r.c_ob_refcnt += 1
- resurrect.remove(r)
+ finalize_modern(pyobj)
if pyobj.c_ob_refcnt == 0:
gchdr = self.gc.rrc_pyobj_as_gc(pyobj)
next = gchdr.c_gc_next
@@ -567,12 +594,9 @@
while next <> llmemory.NULL:
pyobj = llmemory.cast_adr_to_ptr(next,
self.gc.PYOBJ_HDR_PTR)
- if self.pyobj_resurrect.has_key(self.pyobjs.index(pyobj)):
- resurrect = self.pyobj_resurrect[self.pyobjs.index(pyobj)]
- for r in resurrect:
- r.c_ob_refcnt += 1
- # TODO: improve test, use flag in gc_refs instead
- resurrect.remove(r)
+ pyobj.c_ob_refcnt += 1
+ finalize_modern(pyobj)
+ decref(pyobj, None)
next = self.gc.rawrefcount_next_cyclic_isolate()
next_dead = self.gc.rawrefcount_cyclic_garbage_head()
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit