Author: Stefan Beyer <[email protected]>
Branch: cpyext-gc-cycle
Changeset: r96225:5d1c0b97ef5a
Date: 2019-03-08 14:23 +0100
http://bitbucket.org/pypy/pypy/changeset/5d1c0b97ef5a/
Log: Implemented garbage_pypy and improved tests
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
@@ -3141,6 +3141,7 @@
self.rrc_pyobj_isolate_list = self._rrc_gc_list_new()
self.rrc_pyobj_dead_list = self._rrc_gc_list_new()
self.rrc_pyobj_garbage_list = self._rrc_gc_list_new()
+ self.rrc_garbage_to_trace = self.AddressStack()
self.rrc_gc_as_pyobj = gc_as_pyobj
self.rrc_pyobj_as_gc = pyobj_as_gc
self.rrc_finalizer_type = finalizer_type
@@ -3246,15 +3247,14 @@
self.rrc_state = self.RAWREFCOUNT_STATE_DEFAULT
def rawrefcount_next_garbage_pypy(self):
- # We assume that next_garbage_pypy is always called before
- # next_garbage_pyobj. As pypy objects can only be in garbage, if there
- # is at least one pyobj in garbage, we can use this optimization.
- if self._rrc_gc_list_is_empty(self.rrc_pyobj_garbage_list):
- return lltype.nullptr(llmemory.GCREF.TO)
+ if self.rrc_garbage_to_trace.non_empty():
+ # remove one object from the wavefront and move the wavefront
+ obj = self.rrc_garbage_to_trace.pop()
+ if self._rrc_garbage_visit(obj):
+ return llmemory.cast_adr_to_ptr(obj, llmemory.GCREF)
+ else:
+ return lltype.nullptr(llmemory.GCREF.TO)
else:
- # TODO: return the next pypy object which is marked with
GCFLAG_GARBAGE and
- # remove the flag from this object. We can safely assume
that objects
- # do not move, as this can only happen to old objects.
return lltype.nullptr(llmemory.GCREF.TO)
def rawrefcount_next_garbage_pyobj(self):
@@ -3620,9 +3620,28 @@
if pyobj.c_ob_pypy_link <> 0:
intobj = pyobj.c_ob_pypy_link
obj = llmemory.cast_int_to_adr(intobj)
+ self.rrc_garbage_to_trace.append(obj)
self.objects_to_trace.append(obj)
self.visit_all_objects()
+ def _rrc_collect_obj(self, obj, ignored):
+ llop.debug_nonnull_pointer(lltype.Void, obj)
+ self.rrc_garbage_to_trace.append(obj)
+ _rrc_collect_obj._always_inline_ = True
+
+ def _rrc_collect_ref_rec(self, root, ignored):
+ self._rrc_collect_obj(root.address[0], None)
+
+ def _rrc_garbage_visit(self, obj):
+ # If GCFLAG_GARBAGE is set, remove the flag and trace the object
+ hdr = self.header(obj)
+ if not (hdr.tid & GCFLAG_GARBAGE):
+ return False
+ hdr.tid &= ~GCFLAG_GARBAGE
+ if self.has_gcptr(llop.extract_ushort(llgroup.HALFWORD, hdr.tid)):
+ self.trace(obj, self._rrc_collect_ref_rec, None)
+ return True
+
def _rrc_check_finalizer(self):
# Check, if the cyclic isolate from the last collection cycle
# is reachable from outside, after the finalizers have been
diff --git a/rpython/memory/gc/test/dot/garbage_cross_simple_1.dot
b/rpython/memory/gc/test/dot/garbage_cross_simple_1.dot
--- a/rpython/memory/gc/test/dot/garbage_cross_simple_1.dot
+++ b/rpython/memory/gc/test/dot/garbage_cross_simple_1.dot
@@ -3,8 +3,12 @@
"b" [type=B, alive=y, garbage=y];
"c" [type=P, alive=y, garbage=y];
"d" [type=P, alive=y, rooted=y];
+ "e" [type=C, alive=y, garbage=y];
+ "f" [type=C, alive=y, ext_refcnt=1];
"a" -> "b";
"b" -> "a";
"b" -> "c";
"c" -> "d";
+ "a" -> "e";
+ "a" -> "f";
}
\ No newline at end of file
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
@@ -672,10 +672,15 @@
# have been added to the garbage list
for name in nodes:
n = nodes[name]
+ garbage = n.info.garbage
if n.info.alive:
if n.info.type == "C":
- assert n.info.garbage != (n.raddr not in garbage_pyobj)
+ assert garbage != (n.raddr not in garbage_pyobj), \
+ "PyObject should " + ("" if garbage else "not ") + \
+ "be in garbage"
else:
- assert n.info.garbage != (n.pref not in garbage_pypy)
+ assert garbage != (n.pref not in garbage_pypy), \
+ "Object should " + ("" if garbage else "not ") + \
+ "be in garbage"
else:
- assert not n.info.garbage
\ No newline at end of file
+ assert not garbage, "Object is dead, but should be in garbage"
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit