[pypy-commit] pypy improve-heap-caching-tracing: Add a special case for ll_arraycopy in the tracing heap cache.
alex_gaynor
noreply at buildbot.pypy.org
Wed Sep 7 23:02:29 CEST 2011
Author: Alex Gaynor <alex.gaynor at gmail.com>
Branch: improve-heap-caching-tracing
Changeset: r47153:70d999525e7c
Date: 2011-09-07 14:02 -0700
http://bitbucket.org/pypy/pypy/changeset/70d999525e7c/
Log: Add a special case for ll_arraycopy in the tracing heap cache.
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
@@ -1,5 +1,7 @@
+from pypy.jit.codewriter.effectinfo import EffectInfo
+from pypy.jit.metainterp.history import ConstInt
from pypy.jit.metainterp.resoperation import rop
-from pypy.jit.metainterp.history import ConstInt
+
class HeapCache(object):
def __init__(self):
@@ -21,7 +23,7 @@
# cache the length of arrays
self.length_cache = {}
- def invalidate_caches(self, opnum, descr):
+ def invalidate_caches(self, opnum, descr, argboxes):
if opnum == rop.SETFIELD_GC:
return
if opnum == rop.SETARRAYITEM_GC:
@@ -41,6 +43,20 @@
ef == effectinfo.EF_ELIDABLE_CANNOT_RAISE or \
ef == effectinfo.EF_ELIDABLE_CAN_RAISE:
return
+ # A special case for ll_arraycopy, because it is so common, and its
+ # effects are so well defined.
+ elif effectinfo.oopspecindex == EffectInfo.OS_ARRAYCOPY:
+ # The destination box
+ if argboxes[2] in self.new_boxes:
+ # XXX: no descr here so we invalidate any of them, not just
+ # of the correct type
+ for descr, cache in self.heap_array_cache.iteritems():
+ for idx, cache in cache.iteritems():
+ for frombox in list(cache):
+ if frombox not in self.new_boxes:
+ del cache[frombox]
+ return
+
self.heap_cache.clear()
self.heap_array_cache.clear()
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
@@ -1676,7 +1676,7 @@
# record the operation
profiler = self.staticdata.profiler
profiler.count_ops(opnum, RECORDED_OPS)
- self.heapcache.invalidate_caches(opnum, descr)
+ self.heapcache.invalidate_caches(opnum, descr, argboxes)
op = self.history.record(opnum, argboxes, resbox, descr)
self.attach_debug_info(op)
return resbox
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
@@ -25,15 +25,17 @@
EF_FORCES_VIRTUAL_OR_VIRTUALIZABLE = 5 #can raise and force virtualizables
EF_RANDOM_EFFECTS = 6 #can do whatever
- def __init__(self, extraeffect):
+ def __init__(self, extraeffect, oopspecindex):
self.extraeffect = extraeffect
+ self.oopspecindex = oopspecindex
class FakeCallDescr(object):
- def __init__(self, extraeffect):
+ def __init__(self, extraeffect, oopspecindex=None):
self.extraeffect = extraeffect
+ self.oopspecindex = oopspecindex
def get_extra_info(self):
- return FakeEffektinfo(self.extraeffect)
+ return FakeEffektinfo(self.extraeffect, self.oopspecindex)
class TestHeapCache(object):
def test_known_class_box(self):
@@ -237,25 +239,25 @@
h.setfield(box1, descr1, box2)
h.setarrayitem(box1, descr1, index1, box2)
h.setarrayitem(box1, descr1, index2, box4)
- h.invalidate_caches(rop.INT_ADD, None)
- h.invalidate_caches(rop.INT_ADD_OVF, None)
- h.invalidate_caches(rop.SETFIELD_RAW, None)
- h.invalidate_caches(rop.SETARRAYITEM_RAW, None)
+ h.invalidate_caches(rop.INT_ADD, None, [])
+ h.invalidate_caches(rop.INT_ADD_OVF, None, [])
+ h.invalidate_caches(rop.SETFIELD_RAW, None, [])
+ h.invalidate_caches(rop.SETARRAYITEM_RAW, None, [])
assert h.getfield(box1, descr1) is box2
assert h.getarrayitem(box1, descr1, index1) is box2
assert h.getarrayitem(box1, descr1, index2) is box4
h.invalidate_caches(
- rop.CALL, FakeCallDescr(FakeEffektinfo.EF_ELIDABLE_CANNOT_RAISE))
+ rop.CALL, FakeCallDescr(FakeEffektinfo.EF_ELIDABLE_CANNOT_RAISE), [])
assert h.getfield(box1, descr1) is box2
assert h.getarrayitem(box1, descr1, index1) is box2
assert h.getarrayitem(box1, descr1, index2) is box4
h.invalidate_caches(
- rop.CALL_LOOPINVARIANT, FakeCallDescr(FakeEffektinfo.EF_LOOPINVARIANT))
+ rop.CALL_LOOPINVARIANT, FakeCallDescr(FakeEffektinfo.EF_LOOPINVARIANT), [])
h.invalidate_caches(
- rop.CALL, FakeCallDescr(FakeEffektinfo.EF_RANDOM_EFFECTS))
+ rop.CALL, FakeCallDescr(FakeEffektinfo.EF_RANDOM_EFFECTS), [])
assert h.getfield(box1, descr1) is None
assert h.getarrayitem(box1, descr1, index1) is None
assert h.getarrayitem(box1, descr1, index2) is None
@@ -294,3 +296,33 @@
h.replace_box(lengthbox1, lengthbox2)
assert h.arraylen(box4) is lengthbox2
+
+ def test_ll_arraycopy(self):
+ h = HeapCache()
+ h.new_array(box1, lengthbox1)
+ h.setarrayitem(box1, descr1, index1, box2)
+ h.new_array(box2, lengthbox1)
+ # Just need the destination box for this call
+ h.invalidate_caches(
+ rop.CALL,
+ # XXX: hardcoded oopspecindex
+ FakeCallDescr(FakeEffektinfo.EF_CANNOT_RAISE, 1),
+ [None, None, box2, None, None]
+ )
+ assert h.getarrayitem(box1, descr1, index1) is box2
+ h.invalidate_caches(
+ rop.CALL,
+ FakeCallDescr(FakeEffektinfo.EF_CANNOT_RAISE, 1),
+ [None, None, box3, None, None]
+ )
+ assert h.getarrayitem(box1, descr1, index1) is None
+
+ h.setarrayitem(box4, descr1, index1, box2)
+ assert h.getarrayitem(box4, descr1, index1) is box2
+ h.invalidate_caches(
+ rop.CALL,
+ # XXX: hardcoded oopspecindex
+ FakeCallDescr(FakeEffektinfo.EF_CANNOT_RAISE, 1),
+ [None, None, box2, None, None]
+ )
+ assert h.getarrayitem(box4, descr1, index1) 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
@@ -558,3 +558,18 @@
res = self.interp_operations(fn, [7])
assert res == 7 * 3
self.check_operations_history(arraylen_gc=1)
+
+ def test_arraycopy(self):
+ class Gbl(object):
+ pass
+ g = Gbl()
+ g.a = [0] * 7
+ def fn(n):
+ assert n >= 0
+ a = g.a
+ x = [0] * n
+ x[2] = 21
+ return len(a[:n]) + x[2]
+ res = self.interp_operations(fn, [3])
+ assert res == 24
+ self.check_operations_history(getarrayitem_gc=0)
More information about the pypy-commit
mailing list