Author: Stefan Beyer <[email protected]>
Branch: cpyext-gc-cycle
Changeset: r96185:38a9f6496360
Date: 2019-02-23 15:34 +0100
http://bitbucket.org/pypy/pypy/changeset/38a9f6496360/
Log: Implemented interface for gc.garbage list
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
@@ -78,7 +78,9 @@
if not self.space.config.translating:
def dealloc_trigger():
from pypy.module.cpyext.pyobject import PyObject, decref, \
- incref, cts, finalize
+ incref, cts, finalize, from_ref
+ w_list = space.getattr(space.builtin_modules['gc'],
+ space.newtext('garbage'))
print 'dealloc_trigger...'
while True:
ob = rawrefcount.next_dead(PyObject)
@@ -113,6 +115,12 @@
if adr_int == llmemory.cast_adr_to_int(
llmemory.cast_ptr_to_adr(head)):
rawrefcount.cyclic_garbage_remove()
+ while True:
+ py_obj = rawrefcount.next_garbage(PyObject)
+ if not py_obj:
+ break
+ w_obj = from_ref(space, py_obj)
+ w_list.append(w_obj)
print 'dealloc_trigger DONE'
return "RETRY"
def tp_traverse(pyobj_ptr, callback, args):
@@ -274,7 +282,12 @@
def _rawrefcount_perform(space):
- from pypy.module.cpyext.pyobject import PyObject, incref, decref, finalize
+ from pypy.module.cpyext.pyobject import (PyObject, incref, decref,
+ finalize, from_ref)
+
+ w_list = space.getattr(space.builtin_modules['gc'],
+ space.newtext('garbage'))
+
while True:
py_obj = rawrefcount.next_dead(PyObject)
if not py_obj:
@@ -291,18 +304,23 @@
py_obj = rawrefcount.cyclic_garbage_head(PyObject)
if not py_obj:
break
-
pyobj = rffi.cast(PyObject, py_obj)
adr_int = llmemory.cast_adr_to_int(llmemory.cast_ptr_to_adr(pyobj))
if pyobj.c_ob_type.c_tp_clear:
incref(space, py_obj)
pyobj.c_ob_type.c_tp_clear(pyobj)
decref(space, py_obj)
-
head = rawrefcount.cyclic_garbage_head(PyObject)
if adr_int == llmemory.cast_adr_to_int(llmemory.cast_ptr_to_adr(head)):
rawrefcount.cyclic_garbage_remove()
+ while True:
+ py_obj = rawrefcount.next_garbage(PyObject)
+ if not py_obj:
+ break
+ w_obj = from_ref(space, py_obj)
+ w_list.append(w_obj)
+
class PyObjDeallocAction(executioncontext.AsyncAction):
"""An action that invokes _Py_Dealloc() on the dying PyObjects.
"""
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
@@ -3217,6 +3217,10 @@
gchdr.c_gc_next = next
next.c_gc_prev = gchdr
+ def rawrefcount_next_garbage(self):
+ return llmemory.NULL
+
+
def rrc_invoke_callback(self):
if self.rrc_enabled and (self.rrc_dealloc_pending.non_empty() or
self.rrc_pyobj_isolate_list.c_gc_next <>
diff --git a/rpython/memory/gctransform/framework.py
b/rpython/memory/gctransform/framework.py
--- a/rpython/memory/gctransform/framework.py
+++ b/rpython/memory/gctransform/framework.py
@@ -518,6 +518,9 @@
self.rawrefcount_cyclic_garbage_remove_ptr = getfn(
GCClass.rawrefcount_cyclic_garbage_remove, [s_gc],
annmodel.s_None, inline = True)
+ self.rawrefcount_next_garbage_ptr = getfn(
+ GCClass.rawrefcount_next_garbage, [s_gc],
+ SomeAddress(), inline = True)
if GCClass.can_usually_pin_objects:
self.pin_ptr = getfn(GCClass.pin,
@@ -1426,6 +1429,12 @@
[self.rawrefcount_cyclic_garbage_remove_ptr,
self.c_const_gc])
+ def gct_gc_rawrefcount_next_garbage(self, hop):
+ assert hop.spaceop.result.concretetype == llmemory.Address
+ hop.genop("direct_call",
+ [self.rawrefcount_next_garbage_ptr, self.c_const_gc],
+ resultvar=hop.spaceop.result)
+
def _set_into_gc_array_part(self, op):
if op.opname == 'setarrayitem':
return op.args[1]
diff --git a/rpython/rlib/rawrefcount.py b/rpython/rlib/rawrefcount.py
--- a/rpython/rlib/rawrefcount.py
+++ b/rpython/rlib/rawrefcount.py
@@ -146,6 +146,10 @@
return lltype.nullptr(OB_PTR_TYPE.TO)
@not_rpython
+def next_garbage(OB_PTR_TYPE):
+ return lltype.nullptr(OB_PTR_TYPE.TO)
+
+@not_rpython
def _collect(track_allocation=True):
"""for tests only. Emulates a GC collection.
Will invoke dealloc_trigger_callback() once if there are objects
@@ -367,7 +371,8 @@
return _spec_p(hop, v_p)
class Entry(ExtRegistryEntry):
- _about_ = (next_dead, cyclic_garbage_head, next_cyclic_isolate)
+ _about_ = (next_dead, cyclic_garbage_head, next_cyclic_isolate,
+ next_garbage)
def compute_result_annotation(self, s_OB_PTR_TYPE):
from rpython.rtyper.llannotation import lltype_to_annotation
@@ -381,6 +386,8 @@
name = 'gc_rawrefcount_cyclic_garbage_head'
elif self.instance is next_cyclic_isolate:
name = 'gc_rawrefcount_next_cyclic_isolate'
+ elif self.instance is next_garbage:
+ name = 'gc_rawrefcount_next_garbage'
hop.exception_cannot_occur()
v_ob = hop.genop(name, [], resulttype = llmemory.Address)
return _spec_ob(hop, v_ob)
diff --git a/rpython/rtyper/llinterp.py b/rpython/rtyper/llinterp.py
--- a/rpython/rtyper/llinterp.py
+++ b/rpython/rtyper/llinterp.py
@@ -995,6 +995,9 @@
def op_gc_rawrefcount_cyclic_garbage_remove(self, *args):
raise NotImplementedError("gc_rawrefcount_cyclic_garbage_remove")
+ def op_gc_rawrefcount_next_garbage(self, *args):
+ raise NotImplementedError("gc_rawrefcount_next_garbage")
+
def op_do_malloc_fixedsize(self):
raise NotImplementedError("do_malloc_fixedsize")
def op_do_malloc_fixedsize_clear(self):
diff --git a/rpython/rtyper/lltypesystem/lloperation.py
b/rpython/rtyper/lltypesystem/lloperation.py
--- a/rpython/rtyper/lltypesystem/lloperation.py
+++ b/rpython/rtyper/lltypesystem/lloperation.py
@@ -532,6 +532,7 @@
'gc_rawrefcount_next_cyclic_isolate': LLOp(),
'gc_rawrefcount_cyclic_garbage_head': LLOp(sideeffects=False),
'gc_rawrefcount_cyclic_garbage_remove': LLOp(),
+ 'gc_rawrefcount_next_garbage': LLOp(),
'gc_move_out_of_nursery': LLOp(),
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit