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