Author: Armin Rigo <[email protected]>
Branch: gc-del-3
Changeset: r84132:585ea21d4f7f
Date: 2016-05-02 19:31 +0200
http://bitbucket.org/pypy/pypy/changeset/585ea21d4f7f/
Log: in-progress
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
@@ -1565,6 +1565,13 @@
self.header(shadow).tid |= GCFLAG_VISITED
new_shadow_object_dict.setitem(obj, shadow)
+ def register_finalizer(self, fq_index, gcobj):
+ from rpython.rtyper.lltypesystem import rffi
+ obj = llmemory.cast_ptr_to_adr(gcobj)
+ self.probably_young_objects_with_finalizers.append(obj)
+ fq_index = rffi.cast(llmemory.Address, fq_index)
+ self.probably_young_objects_with_finalizers.append(fq_index)
+
# ----------
# Nursery collection
@@ -2617,12 +2624,12 @@
def deal_with_young_objects_with_finalizers(self):
while self.probably_young_objects_with_finalizers.non_empty():
obj = self.probably_young_objects_with_finalizers.popleft()
- fin_nr = self.probably_young_objects_with_finalizers.popleft()
- singleaddr.address[0] = obj
- self._trace_drag_out1(singleaddr)
- obj = singleaddr.address[0]
- self.old_objects_with_light_finalizers.append(obj)
- self.old_objects_with_light_finalizers.append(fin_nr)
+ fq_nr = self.probably_young_objects_with_finalizers.popleft()
+ self.singleaddr.address[0] = obj
+ self._trace_drag_out1(self.singleaddr)
+ obj = self.singleaddr.address[0]
+ self.old_objects_with_finalizers.append(obj)
+ self.old_objects_with_finalizers.append(fq_nr)
def deal_with_objects_with_finalizers(self):
# Walk over list of objects with finalizers.
@@ -2635,14 +2642,17 @@
marked = self.AddressDeque()
pending = self.AddressStack()
self.tmpstack = self.AddressStack()
- while self.objects_with_finalizers.non_empty():
- x = self.objects_with_finalizers.popleft()
+ while self.old_objects_with_finalizers.non_empty():
+ x = self.old_objects_with_finalizers.popleft()
+ fq_nr = self.old_objects_with_finalizers.popleft()
ll_assert(self._finalization_state(x) != 1,
"bad finalization state 1")
if self.header(x).tid & GCFLAG_VISITED:
new_with_finalizer.append(x)
+ new_with_finalizer.append(fq_nr)
continue
marked.append(x)
+ marked.append(fq_nr)
pending.append(x)
while pending.non_empty():
y = pending.pop()
@@ -2662,9 +2672,11 @@
while marked.non_empty():
x = marked.popleft()
+ fq_nr = marked.popleft()
state = self._finalization_state(x)
ll_assert(state >= 2, "unexpected finalization state < 2")
if state == 2:
+ # XXX use fq_nr here
self.run_finalizers.append(x)
# we must also fix the state from 2 to 3 here, otherwise
# we leave the GCFLAG_FINALIZATION_ORDERING bit behind
@@ -2672,12 +2684,13 @@
self._recursively_bump_finalization_state_from_2_to_3(x)
else:
new_with_finalizer.append(x)
+ new_with_finalizer.append(fq_nr)
self.tmpstack.delete()
pending.delete()
marked.delete()
- self.objects_with_finalizers.delete()
- self.objects_with_finalizers = new_with_finalizer
+ self.old_objects_with_finalizers.delete()
+ self.old_objects_with_finalizers = new_with_finalizer
def _append_if_nonnull(pointer, stack):
stack.append(pointer.address[0])
diff --git a/rpython/memory/gcwrapper.py b/rpython/memory/gcwrapper.py
--- a/rpython/memory/gcwrapper.py
+++ b/rpython/memory/gcwrapper.py
@@ -4,6 +4,7 @@
from rpython.rtyper.annlowlevel import llhelper
from rpython.memory import gctypelayout
from rpython.flowspace.model import Constant
+from rpython.rlib import rgc
class GCManagedHeap(object):
@@ -20,6 +21,7 @@
self.llinterp = llinterp
self.prepare_graphs(flowgraphs)
self.gc.setup()
+ self.finalizer_queues = {}
self.has_write_barrier_from_array = hasattr(self.gc,
'write_barrier_from_array')
@@ -187,6 +189,20 @@
def thread_run(self):
pass
+ def get_finalizer_queue_index(self, fq_tag):
+ assert fq_tag.expr == 'FinalizerQueue TAG'
+ fq = fq_tag.default
+ return self.finalizer_queues.setdefault(fq, len(self.finalizer_queues))
+
+ def gc_fq_next_dead(self, fq_tag):
+ index = self.get_finalizer_queue_index(fq_tag)
+ xxx
+
+ def gc_fq_register(self, fq_tag, ptr):
+ index = self.get_finalizer_queue_index(fq_tag)
+ ptr = lltype.cast_opaque_ptr(llmemory.GCREF, ptr)
+ self.gc.register_finalizer(index, ptr)
+
# ____________________________________________________________
class LLInterpRootWalker:
diff --git a/rpython/memory/test/gc_test_base.py
b/rpython/memory/test/gc_test_base.py
--- a/rpython/memory/test/gc_test_base.py
+++ b/rpython/memory/test/gc_test_base.py
@@ -128,7 +128,7 @@
assert res == concat(100)
#assert simulator.current_size - curr < 16000 * INT_SIZE / 4
- def test_finalizer(self):
+ def test_destructor(self):
class B(object):
pass
b = B()
@@ -152,6 +152,36 @@
res = self.interpret(f, [5])
assert res == 6
+ def test_finalizer(self):
+ class B(object):
+ pass
+ b = B()
+ b.nextid = 0
+ b.num_deleted = 0
+ class A(object):
+ def __init__(self):
+ self.id = b.nextid
+ b.nextid += 1
+ fq.register_finalizer(self)
+ class FQ(rgc.FinalizerQueue):
+ Class = A
+ def finalizer_trigger(self):
+ while self.next_dead() is not None:
+ b.num_deleted += 1
+ fq = FQ()
+ def f(x):
+ a = A()
+ i = 0
+ while i < x:
+ i += 1
+ a = A()
+ a = None
+ llop.gc__collect(lltype.Void)
+ llop.gc__collect(lltype.Void)
+ return b.num_deleted
+ res = self.interpret(f, [5])
+ assert res == 6
+
def test_finalizer_calls_malloc(self):
class B(object):
pass
diff --git a/rpython/rlib/rgc.py b/rpython/rlib/rgc.py
--- a/rpython/rlib/rgc.py
+++ b/rpython/rlib/rgc.py
@@ -5,6 +5,7 @@
from rpython.rlib import jit
from rpython.rlib.objectmodel import we_are_translated, enforceargs, specialize
+from rpython.rlib.objectmodel import CDefinedIntSymbolic
from rpython.rtyper.extregistry import ExtRegistryEntry
from rpython.rtyper.lltypesystem import lltype, llmemory
@@ -389,7 +390,7 @@
from rpython.rtyper.lltypesystem.lloperation import llop
from rpython.rtyper.rclass import OBJECTPTR
from rpython.rtyper.annlowlevel import cast_base_ptr_to_instance
- ptr = llop.gc_fq_next_dead(OBJECTPTR, self)
+ ptr = llop.gc_fq_next_dead(OBJECTPTR, self._get_tag())
return cast_base_ptr_to_instance(self.Class, ptr)
try:
return self._queue.popleft()
@@ -404,9 +405,16 @@
from rpython.rtyper.rclass import OBJECTPTR
from rpython.rtyper.annlowlevel import cast_instance_to_base_ptr
ptr = cast_instance_to_base_ptr(obj)
- llop.gc_fq_register(lltype.Void, self, ptr)
+ llop.gc_fq_register(lltype.Void, self._get_tag(), ptr)
return
+ else:
+ self._untranslated_register_finalizer(obj)
+ @specialize.memo()
+ def _get_tag(self):
+ return CDefinedIntSymbolic('FinalizerQueue TAG', default=self)
+
+ def _untranslated_register_finalizer(self, obj):
if hasattr(obj, '__enable_del_for_id'):
return # already called
diff --git a/rpython/rtyper/llinterp.py b/rpython/rtyper/llinterp.py
--- a/rpython/rtyper/llinterp.py
+++ b/rpython/rtyper/llinterp.py
@@ -720,6 +720,12 @@
def op_gc_add_memory_pressure(self, size):
self.heap.add_memory_pressure(size)
+ def op_gc_fq_next_dead(self, fq_tag):
+ return self.heap.gc_fq_next_dead(fq_tag)
+
+ def op_gc_fq_register(self, fq_tag, obj):
+ self.heap.gc_fq_register(fq_tag, obj)
+
def op_gc_gettypeid(self, obj):
return lloperation.llop.combine_ushort(lltype.Signed,
self.heap.gettypeid(obj), 0)
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
@@ -504,6 +504,8 @@
'gc_gettypeid' : LLOp(),
'gc_gcflag_extra' : LLOp(),
'gc_add_memory_pressure': LLOp(),
+ 'gc_fq_next_dead' : LLOp(),
+ 'gc_fq_register' : LLOp(),
'gc_rawrefcount_init': LLOp(),
'gc_rawrefcount_create_link_pypy': LLOp(),
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit