[pypy-svn] r49204 - in pypy/dist/pypy/rpython/memory: gc test
arigo at codespeak.net
arigo at codespeak.net
Thu Nov 29 14:46:16 CET 2007
Author: arigo
Date: Thu Nov 29 14:46:14 2007
New Revision: 49204
Modified:
pypy/dist/pypy/rpython/memory/gc/base.py
pypy/dist/pypy/rpython/memory/gc/generation.py
pypy/dist/pypy/rpython/memory/test/test_gc.py
Log:
Test and fix for a weakref bug in the GenerationGC.
Modified: pypy/dist/pypy/rpython/memory/gc/base.py
==============================================================================
--- pypy/dist/pypy/rpython/memory/gc/base.py (original)
+++ pypy/dist/pypy/rpython/memory/gc/base.py Thu Nov 29 14:46:14 2007
@@ -167,6 +167,8 @@
if not target:
freeentry = i
else:
+ debug_assert(self.get_type_id(llmemory.cast_ptr_to_adr(target))
+ > 0, "bogus weakref in compute_id()")
# record this entry in the dict
adr = llmemory.cast_ptr_to_adr(target)
self.object_id_dict[adr] = i
Modified: pypy/dist/pypy/rpython/memory/gc/generation.py
==============================================================================
--- pypy/dist/pypy/rpython/memory/gc/generation.py (original)
+++ pypy/dist/pypy/rpython/memory/gc/generation.py Thu Nov 29 14:46:14 2007
@@ -293,9 +293,10 @@
if self.is_forwarded(pointing_to):
(obj + offset).address[0] = self.get_forwarding_address(
pointing_to)
- self.objects_with_weakrefs.append(obj)
else:
(obj + offset).address[0] = NULL
+ continue # no need to remember this weakref any longer
+ self.objects_with_weakrefs.append(obj)
def write_barrier(self, oldvalue, newvalue, addr_struct):
if self.header(addr_struct).tid & GCFLAG_NO_YOUNG_PTRS:
Modified: pypy/dist/pypy/rpython/memory/test/test_gc.py
==============================================================================
--- pypy/dist/pypy/rpython/memory/test/test_gc.py (original)
+++ pypy/dist/pypy/rpython/memory/test/test_gc.py Thu Nov 29 14:46:14 2007
@@ -327,6 +327,29 @@
res = self.interpret(f, [20]) # for GenerationGC, enough for a minor collection
assert res == 20 + 20
+ def test_young_weakref_to_old_object(self):
+ import weakref
+ class A:
+ pass
+ def f(x):
+ a = A()
+ llop.gc__collect(lltype.Void)
+ # 'a' is old, 'ref' is young
+ ref = weakref.ref(a)
+ # now trigger a minor collection
+ all = [None] * x
+ i = 0
+ while i < x:
+ all[i] = [i] * i
+ i += 1
+ # now 'a' is old, but 'ref' did not move
+ assert ref() is a
+ llop.gc__collect(lltype.Void)
+ # now both 'a' and 'ref' have moved
+ 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
More information about the pypy-svn
mailing list