Author: Carl Friedrich Bolz <[email protected]>
Branch:
Changeset: r78175:294f1462a787
Date: 2015-06-18 13:10 +0200
http://bitbucket.org/pypy/pypy/changeset/294f1462a787/
Log: in the heapcache don't do the same dict lookups twice for every
getfield and setfield that is being traced
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
@@ -60,6 +60,26 @@
if not value.is_unescaped:
del d[value]
+
+class FieldUpdater(object):
+ def __init__(self, heapcache, value, cache, fieldvalue):
+ self.heapcache = heapcache
+ self.value = value
+ self.cache = cache
+ if fieldvalue is not None:
+ self.currfieldbox = fieldvalue.box
+ else:
+ self.currfieldbox = None
+
+ def getfield_now_known(self, fieldbox):
+ fieldvalue = self.heapcache.getvalue(fieldbox)
+ self.cache.read_now_known(self.value, fieldvalue)
+
+ def setfield(self, fieldbox):
+ fieldvalue = self.heapcache.getvalue(fieldbox)
+ self.cache.do_write_with_aliasing(self.value, fieldvalue)
+
+
class HeapCache(object):
def __init__(self):
self.reset()
@@ -311,21 +331,23 @@
return tovalue.box
return None
- def getfield_now_known(self, box, descr, fieldbox):
+ def get_field_updater(self, box, descr):
value = self.getvalue(box)
- fieldvalue = self.getvalue(fieldbox)
cache = self.heap_cache.get(descr, None)
if cache is None:
cache = self.heap_cache[descr] = CacheEntry()
- cache.read_now_known(value, fieldvalue)
+ fieldvalue = None
+ else:
+ fieldvalue = cache.read(value)
+ return FieldUpdater(self, value, cache, fieldvalue)
+
+ def getfield_now_known(self, box, descr, fieldbox):
+ upd = self.get_field_updater(box, descr)
+ upd.getfield_now_known(fieldbox)
def setfield(self, box, fieldbox, descr):
- cache = self.heap_cache.get(descr, None)
- if cache is None:
- cache = self.heap_cache[descr] = CacheEntry()
- value = self.getvalue(box)
- fieldvalue = self.getvalue(fieldbox)
- cache.do_write_with_aliasing(value, fieldvalue)
+ upd = self.get_field_updater(box, descr)
+ upd.setfield(fieldbox)
def getarrayitem(self, box, indexbox, descr):
if not isinstance(indexbox, ConstInt):
diff --git a/rpython/jit/metainterp/pyjitpl.py
b/rpython/jit/metainterp/pyjitpl.py
--- a/rpython/jit/metainterp/pyjitpl.py
+++ b/rpython/jit/metainterp/pyjitpl.py
@@ -649,16 +649,16 @@
@specialize.arg(1)
def _opimpl_getfield_gc_any_pureornot(self, opnum, box, fielddescr):
- tobox = self.metainterp.heapcache.getfield(box, fielddescr)
- if tobox is not None:
+ upd = self.metainterp.heapcache.get_field_updater(box, fielddescr)
+ if upd.currfieldbox is not None:
# sanity check: see whether the current struct value
# corresponds to what the cache thinks the value is
resbox = executor.execute(self.metainterp.cpu, self.metainterp,
rop.GETFIELD_GC, fielddescr, box)
- assert resbox.constbox().same_constant(tobox.constbox())
- return tobox
+ assert resbox.constbox().same_constant(upd.currfieldbox.constbox())
+ return upd.currfieldbox
resbox = self.execute_with_descr(opnum, fielddescr, box)
- self.metainterp.heapcache.getfield_now_known(box, fielddescr, resbox)
+ upd.getfield_now_known(resbox)
return resbox
@arguments("box", "descr", "orgpc")
@@ -679,10 +679,11 @@
@arguments("box", "box", "descr")
def _opimpl_setfield_gc_any(self, box, valuebox, fielddescr):
- tobox = self.metainterp.heapcache.getfield(box, fielddescr)
- if tobox is valuebox:
+ upd = self.metainterp.heapcache.get_field_updater(box, fielddescr)
+ if upd.currfieldbox is valuebox:
return
- self.metainterp.execute_setfield_gc(fielddescr, box, valuebox)
+ self.metainterp.execute_and_record(rop.SETFIELD_GC, fielddescr, box,
valuebox)
+ upd.setfield(valuebox)
# The following logic is disabled because buggy. It is supposed
# to be: not(we're writing null into a freshly allocated object)
# but the bug is that is_unescaped() can be True even after the
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit