[pypy-commit] pypy unroll-if-alt: a test for the ll_join_chars @jit.look_inside_iff, as well as improvements to jit.isvirtual
alex_gaynor
noreply at buildbot.pypy.org
Tue Sep 20 21:00:55 CEST 2011
Author: Alex Gaynor <alex.gaynor at gmail.com>
Branch: unroll-if-alt
Changeset: r47371:760a2b769dc4
Date: 2011-09-20 15:00 -0400
http://bitbucket.org/pypy/pypy/changeset/760a2b769dc4/
Log: a test for the ll_join_chars @jit.look_inside_iff, as well as
improvements to jit.isvirtual
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
@@ -14,6 +14,9 @@
# escaped the trace or not, its presences in the mapping shows that it
# was allocated inside the trace
self.new_boxes = {}
+ # Tracks which boxes should be marked as escaped when the key box
+ # escapes.
+ self.dependencies = {}
# contains frame boxes that are not virtualizables
self.nonstandard_virtualizables = {}
# heap cache
@@ -31,12 +34,26 @@
def mark_escaped(self, opnum, argboxes):
idx = 0
- for box in argboxes:
- # setfield_gc and setarrayitem_gc don't escape their first argument
- if not (idx == 0 and opnum in [rop.SETFIELD_GC, rop.SETARRAYITEM_GC]):
- if box in self.new_boxes:
- self.new_boxes[box] = False
- idx += 1
+ if opnum == rop.SETFIELD_GC:
+ assert len(argboxes) == 2
+ box, valuebox = argboxes
+ if self.is_unescaped(box) and self.is_unescaped(valuebox):
+ self.dependencies.setdefault(box, []).append(valuebox)
+ else:
+ self._escape(valuebox)
+ else:
+ for box in argboxes:
+ # setarrayitem_gc don't escape their first argument
+ if not (idx == 0 and opnum in [rop.SETARRAYITEM_GC, rop.GETFIELD_GC]):
+ self._escape(box)
+ idx += 1
+
+ def _escape(self, box):
+ if box in self.new_boxes:
+ self.new_boxes[box] = False
+ if box in self.dependencies:
+ for dep in self.dependencies.pop(box):
+ self._escape(dep)
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
@@ -337,6 +337,24 @@
h.invalidate_caches(rop.SETFIELD_GC, None, [box1, box2])
assert not h.is_unescaped(box2)
+ def test_unescaped_testing(self):
+ h = HeapCache()
+ h.new(box1)
+ h.new(box2)
+ assert h.is_unescaped(box1)
+ assert h.is_unescaped(box2)
+ # Putting a virtual inside of another virtual doesn't escape it.
+ h.invalidate_caches(rop.SETFIELD_GC, None, [box1, box2])
+ assert h.is_unescaped(box2)
+ # Reading a field from a virtual doesn't escape it.
+ h.invalidate_caches(rop.GETFIELD_GC, None, [box1])
+ assert h.is_unescaped(box1)
+ # Escaping a virtual transitively escapes anything inside of it.
+ assert not h.is_unescaped(box3)
+ h.invalidate_caches(rop.SETFIELD_GC, None, [box3, box1])
+ assert not h.is_unescaped(box1)
+ assert not h.is_unescaped(box2)
+
def test_unescaped_array(self):
h = HeapCache()
h.new_array(box1, lengthbox1)
diff --git a/pypy/jit/metainterp/test/test_string.py b/pypy/jit/metainterp/test/test_string.py
--- a/pypy/jit/metainterp/test/test_string.py
+++ b/pypy/jit/metainterp/test/test_string.py
@@ -536,3 +536,27 @@
self.check_loops(call_pure=0, call=1,
newunicode=0, unicodegetitem=0,
unicodesetitem=0, copyunicodecontent=0)
+
+ def test_join_chars(self):
+ jitdriver = JitDriver(reds=['a', 'b', 'c', 'i'], greens=[])
+ def f(a, b, c):
+ i = 0
+ while i < 10:
+ jitdriver.jit_merge_point(a=a, b=b, c=c, i=i)
+ x = []
+ if a:
+ x.append("a")
+ if b:
+ x.append("b")
+ if c:
+ x.append("c")
+ i += len("".join(x))
+ return i
+ res = self.meta_interp(f, [1, 1, 1])
+ assert res == f(True, True, True)
+ # The "".join should be unrolled, since the length of x is known since
+ # it is virtual, ensure there are no calls to ll_join_chars, or
+ # allocations.
+ self.check_loops({
+ "guard_true": 5, "int_is_true": 3, "int_lt": 2, "int_add": 2, "jump": 2,
+ }, everywhere=True)
More information about the pypy-commit
mailing list