[pypy-commit] pypy cpyext-gc-cycle: Fixed issues with rrc tuples
stevie_92
pypy.commits at gmail.com
Sat Oct 5 04:50:52 EDT 2019
Author: Stefan Beyer <home at sbeyer.at>
Branch: cpyext-gc-cycle
Changeset: r97728:6e21fe036218
Date: 2019-10-05 10:50 +0200
http://bitbucket.org/pypy/pypy/changeset/6e21fe036218/
Log: Fixed issues with rrc tuples Implemented cpyext statistics
diff --git a/pypy/module/cpyext/state.py b/pypy/module/cpyext/state.py
--- a/pypy/module/cpyext/state.py
+++ b/pypy/module/cpyext/state.py
@@ -8,6 +8,7 @@
from rpython.rlib import rawrefcount
from rpython.rlib.debug import debug_print
import sys
+import time
# Keep track of exceptions raised in cpyext for a particular execution
@@ -159,6 +160,10 @@
space.actionflag.register_periodic_action(action,
use_bytecode_counter=True)
else:
+ module = space.builtin_modules['gc']
+ attribute = space.newtext('cpyext_durations')
+ space.setattr(module, attribute, space.newlist([]))
+
pyobj_dealloc_action = PyObjDeallocAction(space)
self.dealloc_trigger = lambda: pyobj_dealloc_action.fire()
@@ -310,12 +315,14 @@
return True
-def _rawrefcount_perform(space):
+def _rawrefcount_perform(space): # TODO: measure time spent, make incremental??
from pypy.interpreter.baseobjspace import W_Root
from pypy.module.cpyext.pyobject import (PyObject, incref, decref,
finalize, from_ref, cts)
from pypy.module.cpyext.api import generic_cpy_call
+ start = time.time()
+
while True:
py_obj = rawrefcount.next_dead(PyObject)
if not py_obj:
@@ -337,11 +344,11 @@
pto = pyobj.c_ob_type
if pto.c_tp_clear:
incref(space, py_obj)
- if pto and pto.c_tp_name:
- tp_name = pto.c_tp_name
- name = rffi.charp2str(cts.cast('char*', tp_name))
- debug_print("tp_clear", pyobj, ": type", pto,
- ": name", name)
+ #if pto and pto.c_tp_name:
+ # tp_name = pto.c_tp_name
+ # name = rffi.charp2str(cts.cast('char*', tp_name))
+ # debug_print("tp_clear", pyobj, ": type", pto,
+ # ": name", name)
generic_cpy_call(space, pto.c_tp_clear, pyobj)
decref(space, py_obj)
head = rawrefcount.cyclic_garbage_head(PyObject)
@@ -365,6 +372,11 @@
w_list)
rawrefcount.end_garbage()
+ duration = time.time() - start
+ module = space.builtin_modules['gc']
+ durations = space.getattr(module, space.newtext('cpyext_durations'))
+ durations.append(space.newfloat(duration))
+
class PyObjDeallocAction(executioncontext.AsyncAction):
"""An action that invokes _Py_Dealloc() on the dying PyObjects.
"""
diff --git a/rpython/memory/gc/rrc/incmark.py b/rpython/memory/gc/rrc/incmark.py
--- a/rpython/memory/gc/rrc/incmark.py
+++ b/rpython/memory/gc/rrc/incmark.py
@@ -258,7 +258,8 @@
addr = self.snapshot_refs[obj.refs_index + j]
obj_ref = llmemory.cast_adr_to_ptr(addr,
self.PYOBJ_SNAPSHOT_OBJ_PTR)
- obj_ref.refcnt -= 1
+ if obj_ref != lltype.nullptr(self.PYOBJ_SNAPSHOT_OBJ):
+ obj_ref.refcnt -= 1
# now all rawrefcounted roots or live border objects have a
# refcount > 0
@@ -299,7 +300,8 @@
addr = self.snapshot_refs[snapobj.refs_index + j]
obj_ref = llmemory.cast_adr_to_ptr(addr,
self.PYOBJ_SNAPSHOT_OBJ_PTR)
- obj_ref.refcnt += 1
+ if obj_ref != lltype.nullptr(self.PYOBJ_SNAPSHOT_OBJ):
+ obj_ref.refcnt += 1
# mark recursively, if it is a pypyobj
if snapobj.pypy_link <> 0:
intobj = snapobj.pypy_link
@@ -320,6 +322,10 @@
total_refcnt += self._take_snapshot_count_gc(pygchdr)
total_objs += 1
pygchdr = pygchdr.c_gc_next
+ pygchdr = self.tuple_list.c_gc_next
+ while pygchdr <> self.tuple_list:
+ total_refcnt += self._take_snapshot_count_gc(pygchdr)
+ pygchdr = pygchdr.c_gc_next
pygchdr = self.pyobj_isolate_old_list.c_gc_next
while pygchdr <> self.pyobj_isolate_old_list:
total_refcnt += self._take_snapshot_count_gc(pygchdr)
@@ -364,7 +370,10 @@
pygchdr = self.pyobj_as_gc(pyobj)
if (pygchdr <> lltype.nullptr(self.PYOBJ_GC_HDR) and
pygchdr.c_gc_refs != self.RAWREFCOUNT_REFS_UNTRACKED):
- obj = self.snapshot_objs[pygchdr.c_gc_refs - 1]
+ if pygchdr.c_gc_refs > 0:
+ obj = self.snapshot_objs[pygchdr.c_gc_refs - 1]
+ else:
+ obj = lltype.nullptr(self.PYOBJ_SNAPSHOT_OBJ)
else:
obj = self.snapshot_objs[pyobj.c_ob_pypy_link - 1]
self.snapshot_refs[i] = llmemory.cast_ptr_to_adr(obj)
diff --git a/rpython/memory/gc/test/dot/free_cpython_tuple_1.dot b/rpython/memory/gc/test/dot/free_cpython_tuple_1.dot
--- a/rpython/memory/gc/test/dot/free_cpython_tuple_1.dot
+++ b/rpython/memory/gc/test/dot/free_cpython_tuple_1.dot
@@ -1,5 +1,5 @@
digraph G {
- "a" [type=C, alive=n, tuple=y];
+ "a" [type=C, alive=n, tuple=1];
"b" [type=C, alive=n];
"a" -> "b";
"b" -> "a";
diff --git a/rpython/memory/gc/test/dot/free_cpython_tuple_1.dot b/rpython/memory/gc/test/dot/free_cpython_tuple_2.dot
copy from rpython/memory/gc/test/dot/free_cpython_tuple_1.dot
copy to rpython/memory/gc/test/dot/free_cpython_tuple_2.dot
--- a/rpython/memory/gc/test/dot/free_cpython_tuple_1.dot
+++ b/rpython/memory/gc/test/dot/free_cpython_tuple_2.dot
@@ -1,6 +1,5 @@
digraph G {
- "a" [type=C, alive=n, tuple=y];
- "b" [type=C, alive=n];
+ "a" [type=C, alive=y, ext_refcnt=1];
+ "b" [type=C, alive=y, tuple=0];
"a" -> "b";
- "b" -> "a";
}
diff --git a/rpython/memory/gc/test/dot/free_cpython_tuple_1.dot b/rpython/memory/gc/test/dot/free_cpython_tuple_3.dot
copy from rpython/memory/gc/test/dot/free_cpython_tuple_1.dot
copy to rpython/memory/gc/test/dot/free_cpython_tuple_3.dot
--- a/rpython/memory/gc/test/dot/free_cpython_tuple_1.dot
+++ b/rpython/memory/gc/test/dot/free_cpython_tuple_3.dot
@@ -1,6 +1,5 @@
digraph G {
- "a" [type=C, alive=n, tuple=y];
- "b" [type=C, alive=n];
+ "a" [type=C, alive=y, ext_refcnt=1];
+ "b" [type=C, alive=y, tuple=2];
"a" -> "b";
- "b" -> "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
@@ -43,6 +43,7 @@
self.pyobj_resurrect = {}
self.pyobj_delete = {}
self.is_pygc = []
+ self.tupletypes = []
def rawrefcount_tp_traverse(obj, callback, args):
refs = self.pyobj_refs[self.pyobjs.index(obj)]
@@ -73,13 +74,19 @@
return RAWREFCOUNT_FINALIZER_NONE
def rawrefcount_tuple_maybe_untrack(obj):
- #if foo:
- # gchdr = rawrefcount_pyobj_as_gc(obj)
- # next = gchdr.c_gc_next
- # next.c_gc_prev = gchdr.c_gc_prev
- # gchdr.c_gc_prev.c_gc_next = next
- # return 0
- return 1 # TODO: add tests for 0 ("plain" tuple) and 2 (uninitialized)
+ index = self.pyobjs.index(obj)
+ if self.tupletypes[index] == '0':
+ gchdr = self.gcobjs[index]
+ next = gchdr.c_gc_next
+ next.c_gc_prev = gchdr.c_gc_prev
+ gchdr.c_gc_prev.c_gc_next = next
+ return 0
+ elif self.tupletypes[index] == '1':
+ return 1
+ elif self.tupletypes[index] == '2':
+ return 2
+ else:
+ assert False
self.pyobj_list = lltype.malloc(PYOBJ_GC_HDR_PTR.TO, flavor='raw',
immortal=True)
@@ -146,7 +153,7 @@
return p1, p1ref, check_alive
def _rawrefcount_pyobj(self, create_immortal=False, is_gc=True,
- tracked=True, tuple=tuple):
+ tracked=True, tuple=False, tuple_type=None):
r1 = lltype.malloc(PYOBJ_HDR, flavor='raw',
immortal=create_immortal)
r1.c_ob_refcnt = 0
@@ -157,6 +164,7 @@
self._rawrefcount_add_gc(tracked, tuple)
else:
self.gcobjs.append(lltype.nullptr(PYOBJ_GC_HDR))
+ self.tupletypes.append(tuple_type)
self.pyobjs.append(r1)
self.is_pygc.append(is_gc)
@@ -171,7 +179,7 @@
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,
- tracked=True, tuple=tuple):
+ tracked=True, tuple=False, tuple_type=None):
if is_light:
rc = REFCNT_FROM_PYPY_LIGHT
else:
@@ -207,6 +215,7 @@
self._rawrefcount_add_gc(tracked, tuple)
else:
self.gcobjs.append(lltype.nullptr(PYOBJ_GC_HDR))
+ self.tupletypes.append(tuple_type)
self.pyobjs.append(r1)
self.is_pygc.append(is_gc)
@@ -558,7 +567,8 @@
resurrect = attr['resurrect'] if 'resurrect' in attr else None
delete = attr['delete'] if 'delete' in attr else None
garbage = True if 'garbage' in attr else False
- tuple = attr['tuple'] == "y" if 'tuple' in attr else False
+ tuple = True if 'tuple' in attr else False
+ tuple_type = attr['tuple'] if 'tuple' in attr else None
gc = attr['gc'] == "y" if 'gc' in attr else True
added = attr['added'] if 'added' in attr else None
info = NodeInfo(type, alive, ext_refcnt, finalizer, resurrect,
@@ -569,7 +579,7 @@
add_pyobj_after_snap.append(nodes[name])
else:
r, raddr, check_alive = self._rawrefcount_pyobj(
- tracked=tracked, tuple=tuple)
+ tracked=tracked, tuple=tuple, tuple_type=tuple_type)
r.c_ob_refcnt += ext_refcnt
nodes[name] = CPythonNode(r, raddr, check_alive, info)
elif type == "P":
@@ -600,7 +610,7 @@
self._rawrefcount_pair(42 + i, rooted=rooted,
create_old=True,
tracked=tracked, tuple=tuple,
- is_gc=gc)
+ tuple_type=tuple_type, is_gc=gc)
r.c_ob_refcnt += ext_refcnt
nodes[name] = BorderNode(p, pref, r, raddr, check_alive,
info)
More information about the pypy-commit
mailing list