[pypy-commit] pypy default: Bad Alex, no cookies: deal with recursive virtuals.

cfbolz noreply at buildbot.pypy.org
Mon Oct 10 14:14:52 CEST 2011


Author: Carl Friedrich Bolz <cfbolz at gmx.de>
Branch: 
Changeset: r47919:cc2e72d09e18
Date: 2011-10-09 21:10 +0200
http://bitbucket.org/pypy/pypy/changeset/cc2e72d09e18/

Log:	Bad Alex, no cookies: deal with recursive virtuals.

	(you should have read the Allocation Removal paper better: the last
	optimization rule on page 7 *clearly* indicates that you need to
	remove the object from the static heap *before* recursively escaping
	an object :-) )

diff --git a/pypy/jit/metainterp/heapcache.py b/pypy/jit/metainterp/heapcache.py
--- a/pypy/jit/metainterp/heapcache.py
+++ b/pypy/jit/metainterp/heapcache.py
@@ -54,9 +54,10 @@
         if box in self.new_boxes:
             self.new_boxes[box] = False
         if box in self.dependencies:
-            for dep in self.dependencies[box]:
+            deps = self.dependencies[box]
+            del self.dependencies[box]
+            for dep in deps:
                 self._escape(dep)
-            del self.dependencies[box]
 
     def clear_caches(self, opnum, descr, argboxes):
         if opnum == rop.SETFIELD_GC:
diff --git a/pypy/jit/metainterp/test/test_heapcache.py b/pypy/jit/metainterp/test/test_heapcache.py
--- a/pypy/jit/metainterp/test/test_heapcache.py
+++ b/pypy/jit/metainterp/test/test_heapcache.py
@@ -355,6 +355,14 @@
         assert not h.is_unescaped(box1)
         assert not h.is_unescaped(box2)
 
+    def test_circular_virtuals(self):
+        h = HeapCache()
+        h.new(box1)
+        h.new(box2)
+        h.invalidate_caches(rop.SETFIELD_GC, None, [box1, box2])
+        h.invalidate_caches(rop.SETFIELD_GC, None, [box2, box1])
+        h.invalidate_caches(rop.SETFIELD_GC, None, [box3, box1]) # does not crash
+
     def test_unescaped_array(self):
         h = HeapCache()
         h.new_array(box1, lengthbox1)
@@ -362,4 +370,4 @@
         h.invalidate_caches(rop.SETARRAYITEM_GC, None, [box1, index1, box2])
         assert h.is_unescaped(box1)
         h.invalidate_caches(rop.SETARRAYITEM_GC, None, [box2, index1, box1])
-        assert not h.is_unescaped(box1)
\ No newline at end of file
+        assert not h.is_unescaped(box1)


More information about the pypy-commit mailing list