Author: Armin Rigo <[email protected]>
Branch:
Changeset: r59858:50c910edeafa
Date: 2013-01-07 23:07 +0100
http://bitbucket.org/pypy/pypy/changeset/50c910edeafa/
Log: Test and fix for issue #1353: weakref to prebuilt object.
diff --git a/pypy/rpython/memory/gc/minimark.py
b/pypy/rpython/memory/gc/minimark.py
--- a/pypy/rpython/memory/gc/minimark.py
+++ b/pypy/rpython/memory/gc/minimark.py
@@ -2000,6 +2000,17 @@
(obj + offset).address[0] = llmemory.NULL
continue # no need to remember this weakref any longer
#
+ elif self.header(pointing_to).tid & GCFLAG_NO_HEAP_PTRS:
+ # see test_weakref_to_prebuilt: it's not useful to put
+ # weakrefs into 'old_objects_with_weakrefs' if they point
+ # to a prebuilt object (they are immortal). If moreover
+ # the 'pointing_to' prebuilt object still has the
+ # GCFLAG_NO_HEAP_PTRS flag, then it's even wrong, because
+ # 'pointing_to' will not get the GCFLAG_VISITED during
+ # the next major collection. Solve this by not registering
+ # the weakref into 'old_objects_with_weakrefs'.
+ continue
+ #
self.old_objects_with_weakrefs.append(obj)
def invalidate_old_weakrefs(self):
@@ -2013,6 +2024,9 @@
continue # weakref itself dies
offset = self.weakpointer_offset(self.get_type_id(obj))
pointing_to = (obj + offset).address[0]
+ ll_assert((self.header(pointing_to).tid & GCFLAG_NO_HEAP_PTRS)
+ == 0, "registered old weakref should not "
+ "point to a NO_HEAP_PTRS obj")
if self.header(pointing_to).tid & GCFLAG_VISITED:
new_with_weakref.append(obj)
else:
diff --git a/pypy/rpython/memory/test/test_gc.py
b/pypy/rpython/memory/test/test_gc.py
--- a/pypy/rpython/memory/test/test_gc.py
+++ b/pypy/rpython/memory/test/test_gc.py
@@ -557,6 +557,19 @@
res = self.interpret(f, [20]) # for GenerationGC, enough for a minor
collection
assert res == True
+ def test_weakref_to_prebuilt(self):
+ import weakref
+ class A:
+ pass
+ a = A()
+ def f(x):
+ ref = weakref.ref(a)
+ assert ref() is a
+ llop.gc__collect(lltype.Void)
+ return ref() is a
+ res = self.interpret(f, [20]) # for GenerationGC, enough for a minor
collection
+ assert res == True
+
def test_many_weakrefs(self):
# test for the case where allocating the weakref itself triggers
# a collection
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit