[pypy-svn] r47676 - in pypy/dist/pypy: rpython/memory/gctransform rpython/memory/test translator/goal

arigo at codespeak.net arigo at codespeak.net
Sun Oct 21 18:00:47 CEST 2007


Author: arigo
Date: Sun Oct 21 18:00:47 2007
New Revision: 47676

Removed:
   pypy/dist/pypy/translator/goal/targetcrashstandalone.py
Modified:
   pypy/dist/pypy/rpython/memory/gctransform/framework.py
   pypy/dist/pypy/rpython/memory/test/test_transformed_gc.py
Log:
Test and fix for the issue of weakrefs getting bogus object references,
part 2: the gc transformer.


Modified: pypy/dist/pypy/rpython/memory/gctransform/framework.py
==============================================================================
--- pypy/dist/pypy/rpython/memory/gctransform/framework.py	(original)
+++ pypy/dist/pypy/rpython/memory/gctransform/framework.py	Sun Oct 21 18:00:47 2007
@@ -551,15 +551,15 @@
         args = [self.c_const_gc, c_type_id, c_size, c_can_collect,
                 c_has_finalizer, c_has_weakptr]
 
-        v_instance, = op.args
-        v_addr = hop.genop("cast_ptr_to_adr", [v_instance],
-                           resulttype=llmemory.Address)
-        livevars = self.push_roots(hop)
+        livevars = self.push_roots(hop, keep_current_args=True)
         v_result = hop.genop("direct_call", [malloc_ptr] + args,
                              resulttype=llmemory.GCREF)
         v_result = hop.genop("cast_opaque_ptr", [v_result],
                             resulttype=WEAKREFPTR)
         self.pop_roots(hop, livevars)
+        v_instance, = op.args
+        v_addr = hop.genop("cast_ptr_to_adr", [v_instance],
+                           resulttype=llmemory.Address)
         hop.genop("bare_setfield",
                   [v_result, rmodel.inputconst(lltype.Void, "weakptr"), v_addr])
         v_weakref = hop.genop("cast_ptr_to_weakrefptr", [v_result],
@@ -623,10 +623,10 @@
     def pop_alive_nopyobj(self, var, llops):
         pass
 
-    def push_roots(self, hop):
+    def push_roots(self, hop, keep_current_args=False):
         if self.incr_stack_ptr is None:
             return
-        if self.gcdata.gc.moving_gc:
+        if self.gcdata.gc.moving_gc and not keep_current_args:
             # moving GCs don't borrow, so the caller does not need to keep
             # the arguments alive
             livevars = [var for var in hop.livevars_after_op()

Modified: pypy/dist/pypy/rpython/memory/test/test_transformed_gc.py
==============================================================================
--- pypy/dist/pypy/rpython/memory/test/test_transformed_gc.py	(original)
+++ pypy/dist/pypy/rpython/memory/test/test_transformed_gc.py	Sun Oct 21 18:00:47 2007
@@ -821,3 +821,20 @@
         run = self.runner(f, nbargs=0)
         res = run([])
         assert res == 84
+
+
+    def test_many_weakrefs(self):
+        # test for the case where allocating the weakref itself triggers
+        # a collection
+        import weakref
+        class A:
+            pass
+        def f():
+            a = A()
+            i = 0
+            while i < 17:
+                ref = weakref.ref(a)
+                assert ref() is a
+                i += 1
+        run = self.runner(f, nbargs=0)
+        run([])



More information about the Pypy-commit mailing list