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

Reply via email to