Author: Carl Friedrich Bolz <[email protected]>
Branch: list-strategies
Changeset: r47822:2a6af948db14
Date: 2011-10-04 14:57 +0200
http://bitbucket.org/pypy/pypy/changeset/2a6af948db14/

Log:    slightly annoying: cast_opaque_ptr killed the tracing heap cache. I
        cannot just remove it, seems the short preamble stuff seems to need
        it. Thus I need to consider equivalences of boxes in the heapcache.

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
@@ -29,6 +29,23 @@
         # cache the length of arrays
         self.length_cache = {}
 
+        # equivalences between boxes
+        self.equivalent = {}
+
+    def get_repr(self, box):
+        res = self.equivalent.get(box, box)
+        if res is not box:
+            res2 = self.get_repr(res)
+            # path compression
+            if res2 is not res:
+                self.equivalent[box] = res2
+                res = res2
+        return res
+
+    def same_boxes(self, box1, box2):
+        assert box1 not in self.equivalent
+        self.equivalent[box1] = self.get_repr(box2)
+
     def invalidate_caches(self, opnum, descr, argboxes):
         self.mark_escaped(opnum, argboxes)
         self.clear_caches(opnum, descr, argboxes)
@@ -98,18 +115,23 @@
         self.heap_array_cache.clear()
 
     def is_class_known(self, box):
+        box = self.get_repr(box)
         return box in self.known_class_boxes
 
     def class_now_known(self, box):
+        box = self.get_repr(box)
         self.known_class_boxes[box] = None
 
     def is_nonstandard_virtualizable(self, box):
+        box = self.get_repr(box)
         return box in self.nonstandard_virtualizables
 
     def nonstandard_virtualizables_now_known(self, box):
+        box = self.get_repr(box)
         self.nonstandard_virtualizables[box] = None
 
     def is_unescaped(self, box):
+        box = self.get_repr(box)
         return self.new_boxes.get(box, False)
 
     def new(self, box):
@@ -120,6 +142,7 @@
         self.arraylen_now_known(box, lengthbox)
 
     def getfield(self, box, descr):
+        box = self.get_repr(box)
         d = self.heap_cache.get(descr, None)
         if d:
             tobox = d.get(box, None)
@@ -128,9 +151,11 @@
         return None
 
     def getfield_now_known(self, box, descr, fieldbox):
+        box = self.get_repr(box)
         self.heap_cache.setdefault(descr, {})[box] = fieldbox
 
     def setfield(self, box, descr, fieldbox):
+        box = self.get_repr(box)
         d = self.heap_cache.get(descr, None)
         new_d = self._do_write_with_aliasing(d, box, fieldbox)
         self.heap_cache[descr] = new_d
@@ -154,6 +179,7 @@
         return new_d
 
     def getarrayitem(self, box, descr, indexbox):
+        box = self.get_repr(box)
         if not isinstance(indexbox, ConstInt):
             return
         index = indexbox.getint()
@@ -164,6 +190,7 @@
                 return indexcache.get(box, None)
 
     def getarrayitem_now_known(self, box, descr, indexbox, valuebox):
+        box = self.get_repr(box)
         if not isinstance(indexbox, ConstInt):
             return
         index = indexbox.getint()
@@ -175,6 +202,7 @@
             cache[index] = {box: valuebox}
 
     def setarrayitem(self, box, descr, indexbox, valuebox):
+        box = self.get_repr(box)
         if not isinstance(indexbox, ConstInt):
             cache = self.heap_array_cache.get(descr, None)
             if cache is not None:
@@ -186,9 +214,11 @@
         cache[index] = self._do_write_with_aliasing(indexcache, box, valuebox)
 
     def arraylen(self, box):
+        box = self.get_repr(box)
         return self.length_cache.get(box, None)
 
     def arraylen_now_known(self, box, lengthbox):
+        box = self.get_repr(box)
         self.length_cache[box] = lengthbox
 
     def _replace_box(self, d, oldbox, newbox):
@@ -202,6 +232,7 @@
         return new_d
 
     def replace_box(self, oldbox, newbox):
+        oldbox = self.get_repr(oldbox)
         for descr, d in self.heap_cache.iteritems():
             self.heap_cache[descr] = self._replace_box(d, oldbox, newbox)
         for descr, d in self.heap_array_cache.iteritems():
diff --git a/pypy/jit/metainterp/pyjitpl.py b/pypy/jit/metainterp/pyjitpl.py
--- a/pypy/jit/metainterp/pyjitpl.py
+++ b/pypy/jit/metainterp/pyjitpl.py
@@ -236,7 +236,10 @@
 
     @arguments("box")
     def opimpl_cast_opaque_ptr(self, box):
-        return self.execute(rop.CAST_OPAQUE_PTR, box)
+        res = self.execute(rop.CAST_OPAQUE_PTR, box)
+        self.metainterp.heapcache.same_boxes(res, box)
+        return res
+
 
     @arguments("box")
     def _opimpl_any_return(self, box):
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
@@ -362,4 +362,16 @@
         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)
+
+    def test_heapcache_fields(self):
+        h = HeapCache()
+        assert h.getfield(box1, descr1) is None
+        assert h.getfield(box1, descr2) is None
+        h.setfield(box1, descr1, box2)
+        assert h.getfield(box1, descr1) is box2
+        assert h.getfield(box1, descr2) is None
+        h.same_boxes(box3, box1)
+        h.same_boxes(box4, box3)
+        assert h.getfield(box4, descr1) is box2
+        assert h.getfield(box4, descr2) is None
diff --git a/pypy/jit/metainterp/test/test_tracingopts.py 
b/pypy/jit/metainterp/test/test_tracingopts.py
--- a/pypy/jit/metainterp/test/test_tracingopts.py
+++ b/pypy/jit/metainterp/test/test_tracingopts.py
@@ -590,4 +590,32 @@
         assert res == 4
         self.check_operations_history(int_add_ovf=0)
         res = self.interp_operations(fn, [sys.maxint])
-        assert res == 12
\ No newline at end of file
+        assert res == 12
+
+
+
+    def test_opaque_list(self):
+        from pypy.rlib.rerased import new_erasing_pair
+        erase, unerase = new_erasing_pair("test_opaque_list")
+        def fn(n, ca, cb):
+            l1 = [n]
+            l2 = [n]
+            a1 = erase(l1)
+            a2 = erase(l1)
+            a = a1
+            if ca:
+                a = a2
+                if n < -100:
+                    unerase(a).append(5)
+            b = a1
+            if cb:
+                b = a
+            return unerase(a)[0] + unerase(b)[0]
+        res = self.interp_operations(fn, [7, 0, 1])
+        assert res == 7 * 2
+        self.check_operations_history(getarrayitem_gc=0,
+                getfield_gc=0)
+        res = self.interp_operations(fn, [-7, 1, 1])
+        assert res == -7 * 2
+        self.check_operations_history(getarrayitem_gc=0,
+                getfield_gc=0)
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to