[pypy-commit] pypy gc-del: Add a test that fails consistently, and fix.
arigo
noreply at buildbot.pypy.org
Mon Mar 25 23:25:29 CET 2013
Author: Armin Rigo <arigo at tunes.org>
Branch: gc-del
Changeset: r62763:e7ca33c2ef41
Date: 2013-03-25 23:25 +0100
http://bitbucket.org/pypy/pypy/changeset/e7ca33c2ef41/
Log: Add a test that fails consistently, and fix.
diff --git a/rpython/memory/gc/minimark.py b/rpython/memory/gc/minimark.py
--- a/rpython/memory/gc/minimark.py
+++ b/rpython/memory/gc/minimark.py
@@ -1492,6 +1492,7 @@
# We will fix such references to point to the copy of the young
# objects when we walk 'old_objects_pointing_to_young'.
self.old_objects_pointing_to_young.append(newobj)
+ #debug_print("adding", newobj)
_trace_drag_out._always_inline_ = True
def _visit_young_rawmalloced_object(self, obj):
@@ -1922,11 +1923,11 @@
we also need to copy them out of the nursery. The tricky part
here is to enqueue them in topological order, if possible.
"""
- pending = self.old_objects_pointing_to_young
- ll_assert(not pending.non_empty(),
+ ll_assert(not self.old_objects_pointing_to_young.non_empty(),
"deal_with_young_objects_with_finalizers: "
"old_objects_pointing_to_young should be empty")
finalizer_funcs = self.AddressDict()
+ self.finalizers_scheduled = self.AddressStack()
#
while self.young_objects_with_finalizers.non_empty():
func = self.young_objects_with_finalizers.pop()
@@ -1940,19 +1941,44 @@
root.address[0] = obj
self._trace_drag_out1(root)
objcopy = root.address[0]
+ #debug_print("finalizer for", obj)
+ #debug_print("object moving to", objcopy)
#
# Remember the finalizer in the dict
finalizer_funcs.setitem(objcopy, func)
+ #
+ # Now follow all the refs
+ self._follow_references_from_young_object_with_finalizer()
#
- # Now follow all the refs
- finalizers_scheduled = self.AddressStack()
+ # Copy the objects scheduled into 'run_finalizers_queue', in
+ # reverse order.
+ while self.finalizers_scheduled.non_empty():
+ obj = self.finalizers_scheduled.pop()
+ func = finalizer_funcs.get(obj)
+ ll_assert(func != NULL, "lost finalizer [1]")
+ self.run_finalizers_queue.append(obj)
+ self.run_finalizers_funcs.append(func)
+ finalizer_funcs.setitem(obj, NULL)
+ self.finalizers_scheduled.delete()
+ #
+ # The non-NULL entries remaining in 'finalizer_funcs' correspond
+ # to objects that survived, because they have not been traced by
+ # this function but already before.
+ finalizer_funcs.foreach(self._move_to_old_finalizer,
+ self.old_objects_with_finalizers)
+ finalizer_funcs.delete()
+
+ def _follow_references_from_young_object_with_finalizer(self):
+ pending = self.old_objects_pointing_to_young
while pending.non_empty():
assert not self.old_objects_with_cards_set.non_empty(), "XXX"
obj = pending.pop()
+ #debug_print("popping", obj)
if obj:
#
if self.header(obj).tid & GCFLAG_HAS_FINALIZER:
self.header(obj).tid &= ~GCFLAG_HAS_FINALIZER
+ #debug_print("this object has a finalizer")
pending.append(obj)
pending.append(NULL) # marker
#
@@ -1964,25 +1990,8 @@
else:
# seen a NULL marker
obj = pending.pop()
- finalizers_scheduled.append(obj)
- #
- # Copy the objects scheduled into 'run_finalizers_queue', in
- # reverse order.
- while finalizers_scheduled.non_empty():
- obj = finalizers_scheduled.pop()
- func = finalizer_funcs.get(obj)
- ll_assert(func != NULL, "lost finalizer [1]")
- self.run_finalizers_queue.append(obj)
- self.run_finalizers_funcs.append(func)
- finalizer_funcs.setitem(obj, NULL)
- finalizers_scheduled.delete()
- #
- # The non-NULL entries remaining in 'finalizer_funcs' correspond
- # to objects that survived, because they have not been traced by
- # this function but already before.
- finalizer_funcs.foreach(self._move_to_old_finalizer,
- self.old_objects_with_finalizers)
- finalizer_funcs.delete()
+ #debug_print("adding to scheduled", obj)
+ self.finalizers_scheduled.append(obj)
@staticmethod
def _move_to_old_finalizer(obj, finalizer, old_objects_with_finalizers):
diff --git a/rpython/memory/test/snippet.py b/rpython/memory/test/snippet.py
--- a/rpython/memory/test/snippet.py
+++ b/rpython/memory/test/snippet.py
@@ -2,6 +2,7 @@
from rpython.tool.udir import udir
from rpython.rtyper.lltypesystem import lltype
from rpython.rtyper.lltypesystem.lloperation import llop
+from rpython.rlib.debug import debug_print
from rpython.rlib import rgc
@@ -10,6 +11,11 @@
def definestr_finalizer_order(cls):
import random
+ x = random.randrange(0,10000)
+ print "R"*1000
+ print x
+ print '-'*60
+ random.seed(x)
from rpython.tool.algo import graphlib
cls.finalizer_order_examples = examples = []
@@ -72,8 +78,12 @@
def f(_):
i = 0
while i < len(examples):
+ debug_print("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<")
input, components, strict = examples[i]
build_example(input)
+ if i & 1:
+ rgc.collect()
+ debug_print(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>")
while state.time < 2 * len(letters):
state.progress = False
llop.gc__collect(lltype.Void)
@@ -98,16 +108,17 @@
% (c, d))
# check that two instances in the same strong component
# are never finalized during the same collection
- for component in components:
- seen = {}
- for c in component:
- age = state.age[c]
- if age in seen:
- d = seen[age]
- return error(i, summary,
- "%s and %s should not be finalized"
- " at the same time" % (c, d))
- seen[age] = c
+ # <<< disabled now >>>
+ #for component in components:
+ # seen = {}
+ # for c in component:
+ # age = state.age[c]
+ # if age in seen:
+ # d = seen[age]
+ # return error(i, summary,
+ # "%s and %s should not be finalized"
+ # " at the same time" % (c, d))
+ # seen[age] = c
i += 1
return "ok"
diff --git a/rpython/memory/test/test_gc.py b/rpython/memory/test/test_gc.py
--- a/rpython/memory/test/test_gc.py
+++ b/rpython/memory/test/test_gc.py
@@ -1058,3 +1058,10 @@
class TestMiniMarkGCCardMarking(TestMiniMarkGC):
GC_PARAMS = {'card_page_indices': 4}
+
+class TestMiniMarkGCLargeNursery(TestMiniMarkGC):
+ GC_PARAMS = {'nursery_size': 1024*WORD}
+ def setup_class(cls):
+ py.test.skip("takes a lot of extra time to run")
+ def teardown_class(cls):
+ pass
More information about the pypy-commit
mailing list