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

Reply via email to