Author: Alex Gaynor <[email protected]>
Branch:
Changeset: r67347:d1a0c07b6586
Date: 2013-10-13 21:48 +0200
http://bitbucket.org/pypy/pypy/changeset/d1a0c07b6586/
Log: ARRAYCOPY with constant starts and constant length doesn't escape
its argument
diff --git a/rpython/jit/metainterp/heapcache.py
b/rpython/jit/metainterp/heapcache.py
--- a/rpython/jit/metainterp/heapcache.py
+++ b/rpython/jit/metainterp/heapcache.py
@@ -51,10 +51,10 @@
return self.output_indirections.get(box, box)
def invalidate_caches(self, opnum, descr, argboxes):
- self.mark_escaped(opnum, argboxes)
+ self.mark_escaped(opnum, descr, argboxes)
self.clear_caches(opnum, descr, argboxes)
- def mark_escaped(self, opnum, argboxes):
+ def mark_escaped(self, opnum, descr, argboxes):
if opnum == rop.SETFIELD_GC:
assert len(argboxes) == 2
box, valuebox = argboxes
@@ -69,6 +69,15 @@
self.dependencies.setdefault(box, []).append(valuebox)
else:
self._escape(valuebox)
+ elif (opnum == rop.CALL and
+ descr.get_extra_info().oopspecindex ==
descr.get_extra_info().OS_ARRAYCOPY and
+ isinstance(argboxes[3], ConstInt) and
+ isinstance(argboxes[4], ConstInt) and
+ isinstance(argboxes[5], ConstInt) and
+ len(descr.get_extra_info().write_descrs_arrays) == 1):
+ # ARRAYCOPY with constant starts and constant length doesn't escape
+ # its argument
+ pass
# GETFIELD_GC, MARK_OPAQUE_PTR, PTR_EQ, and PTR_NE don't escape their
# arguments
elif (opnum != rop.GETFIELD_GC and
diff --git a/rpython/jit/metainterp/test/test_heapcache.py
b/rpython/jit/metainterp/test/test_heapcache.py
--- a/rpython/jit/metainterp/test/test_heapcache.py
+++ b/rpython/jit/metainterp/test/test_heapcache.py
@@ -1,6 +1,6 @@
from rpython.jit.metainterp.heapcache import HeapCache
from rpython.jit.metainterp.resoperation import rop
-from rpython.jit.metainterp.history import ConstInt
+from rpython.jit.metainterp.history import ConstInt, BoxInt
box1 = "box1"
box2 = "box2"
@@ -73,7 +73,6 @@
assert not h.is_nonstandard_virtualizable(1)
assert not h.is_nonstandard_virtualizable(2)
-
def test_heapcache_fields(self):
h = HeapCache()
assert h.getfield(box1, descr1) is None
@@ -278,7 +277,6 @@
assert h.getarrayitem(box1, index1, descr1) is None
assert h.getarrayitem(box1, index2, descr1) is None
-
def test_replace_box(self):
h = HeapCache()
h.setfield(box1, box2, descr1)
@@ -423,6 +421,25 @@
[None, box2, box1, index1, index1, index2]
)
+ def test_ll_arraycopy_doesnt_escape_arrays(self):
+ h = HeapCache()
+ h.new_array(box1, lengthbox1)
+ h.new_array(box2, lengthbox2)
+ h.invalidate_caches(
+ rop.CALL,
+ FakeCallDescr(FakeEffectinfo.EF_CANNOT_RAISE,
FakeEffectinfo.OS_ARRAYCOPY, write_descrs_arrays=[descr1]),
+ [None, box2, box1, index1, index1, index2]
+ )
+ assert h.is_unescaped(box1)
+ assert h.is_unescaped(box2)
+ h.invalidate_caches(
+ rop.CALL,
+ FakeCallDescr(FakeEffectinfo.EF_CANNOT_RAISE,
FakeEffectinfo.OS_ARRAYCOPY, write_descrs_arrays=[descr1]),
+ [None, box2, box1, index1, index1, BoxInt()]
+ )
+ assert not h.is_unescaped(box1)
+ assert not h.is_unescaped(box2)
+
def test_unescaped(self):
h = HeapCache()
assert not h.is_unescaped(box1)
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit