Author: Maciej Fijalkowski <[email protected]>
Branch: optresult
Changeset: r77556:d1199c73940a
Date: 2015-05-26 10:16 +0200
http://bitbucket.org/pypy/pypy/changeset/d1199c73940a/

Log:    start fighting with heapcache of arrays

diff --git a/rpython/jit/metainterp/optimizeopt/heap.py 
b/rpython/jit/metainterp/optimizeopt/heap.py
--- a/rpython/jit/metainterp/optimizeopt/heap.py
+++ b/rpython/jit/metainterp/optimizeopt/heap.py
@@ -95,9 +95,15 @@
         if self._lazy_setfield is not None:
             op = self._lazy_setfield
             assert optheap.getptrinfo(op.getarg(0)) is opinfo
-            return optheap.get_box_replacement(op.getarg(1))
+            return optheap.get_box_replacement(self._getvalue(op))
         else:
-            return opinfo.getfield(descr, optheap)
+            return self._getfield(opinfo, descr, optheap)
+
+    def _getvalue(self, op):
+        return op.getarg(1)
+
+    def _getfield(self, opinfo, descr, optheap):
+        return opinfo.getfield(descr, optheap)
 
     def force_lazy_setfield(self, optheap, can_cache=True):
         op = self._lazy_setfield
@@ -109,9 +115,8 @@
             self.invalidate(op.getdescr())
             self._lazy_setfield = None
             if optheap.postponed_op:
-                xxx
                 for a in op.getarglist():
-                    if a is optheap.postponed_op.result:
+                    if a is optheap.postponed_op:
                         optheap.emit_postponed_op()
                         break
             optheap.next_optimization.propagate_forward(op)
@@ -123,17 +128,31 @@
             opinfo = optheap.ensure_ptr_info_arg0(op)
             opinfo.setfield(op.getdescr(),
                             optheap.get_box_replacement(op.getarg(1)))
-            optheap.register_dirty_field(op.getdescr(), opinfo)
         elif not can_cache:
             self.invalidate()
 
+class ArrayCachedField(CachedField):
+    def __init__(self, index):
+        self.index = index
+        CachedField.__init__(self)
+
+    def _getvalue(self, op):
+        xxx
+        return op.getarg(1)
+
+    def _getfield(self, opinfo, descr, optheap):
+        return opinfo.getitem(self.index)
+
 class OptHeap(Optimization):
     """Cache repeated heap accesses"""
 
     def __init__(self):
         # mapping descr -> CachedField
         self.cached_fields = OrderedDict()
-        
+        self.cached_arrayitems = OrderedDict()
+
+        self.postponed_op = None
+
         # XXXX the rest is old
         # cached array items:  {array descr: {index: CachedField}}
         self.cached_arrayitems = {}
@@ -145,7 +164,6 @@
         self._lazy_setfields_and_arrayitems = []
         self._remove_guard_not_invalidated = False
         self._seen_guard_not_invalidated = False
-        self.postponed_op = None
 
     def setup(self):
         self.optimizer.optheap = self
@@ -212,7 +230,7 @@
         try:
             cf = submap[index]
         except KeyError:
-            cf = submap[index] = CachedField()
+            cf = submap[index] = ArrayCachedField(index)
         return cf
 
     def emit_operation(self, op):
@@ -446,7 +464,7 @@
         self.make_nonnull(op.getarg(0))
         self.emit_operation(op)
         # then remember the result of reading the field
-        structinfo.setfield(op.getdescr(), op, self)
+        structinfo.setfield(op.getdescr(), self.get_box_replacement(op), cf)
     optimize_GETFIELD_GC_R = optimize_GETFIELD_GC_I
     optimize_GETFIELD_GC_F = optimize_GETFIELD_GC_I
 
@@ -483,13 +501,14 @@
             # XXXX lgt bound
             #arrayvalue.make_len_gt(MODE_ARRAY, op.getdescr(), 
indexvalue.box.getint())
             # use the cache on (arraydescr, index), which is a constant
-            #cf = self.arrayitem_cache(op.getdescr(), indexvalue.box.getint())
-            #fieldvalue = cf.getfield_from_cache(self, arrayvalue)
-            fieldvalue = None
-            if fieldvalue is not None:
-                self.make_equal_to(op, fieldvalue)
+            index = indexb.getint()
+            cf = self.arrayitem_cache(op.getdescr(), index)
+            field = cf.getfield_from_cache(self, arrayinfo, op.getdescr())
+            if field is not None:
+                self.make_equal_to(op, field)
                 return
         else:
+            xxx
             # variable index, so make sure the lazy setarrayitems are done
             self.force_lazy_setarrayitem(op.getdescr(), op.getarg(1))
         # default case: produce the operation
@@ -497,8 +516,7 @@
         self.emit_operation(op)
         # the remember the result of reading the array item
         if cf is not None:
-            fieldvalue = self.getvalue(op)
-            cf.remember_field_value(arrayvalue, fieldvalue, op, self.optimizer)
+            arrayinfo.setitem(indexb.getint(), self.get_box_replacement(op), 
cf)
     optimize_GETARRAYITEM_GC_R = optimize_GETARRAYITEM_GC_I
     optimize_GETARRAYITEM_GC_F = optimize_GETARRAYITEM_GC_I
 
diff --git a/rpython/jit/metainterp/optimizeopt/info.py 
b/rpython/jit/metainterp/optimizeopt/info.py
--- a/rpython/jit/metainterp/optimizeopt/info.py
+++ b/rpython/jit/metainterp/optimizeopt/info.py
@@ -85,11 +85,11 @@
         self.flags = 0
         self._fields = [None] * len(self._fields)
 
-    def setfield(self, descr, op, optheap=None):
+    def setfield(self, descr, op, cf=None):
         self._fields[descr.index] = op
-        if optheap is not None:
+        if cf is not None:
             assert not self.is_virtual()
-            optheap.register_dirty_field(descr, self)
+            cf.register_dirty_field(self)
 
     def getfield(self, descr, optheap=None):
         return self._fields[descr.index]
@@ -128,17 +128,19 @@
             self.flags = FLAG_VIRTUAL
     
 class ArrayPtrInfo(AbstractVirtualPtrInfo):
-    _attrs_ = ('length', '_items', '_descr', 'lengthbound')
+    _attrs_ = ('length', '_items', '_descr', 'lenbound')
+
+    flags = 0
+    _items = None
+    lenbound = None
+    length = -1
 
     def __init__(self, descr, const=None, size=0, clear=False,
                  is_virtual=False):
         self._descr = descr
-        self.lengthbound = None
         if is_virtual:
             self.flags = FLAG_VIRTUAL
             self._init_items(const, size, clear)
-        else:
-            self._items = None
 
     def _init_items(self, const, size, clear):
         self.length = size
@@ -162,10 +164,19 @@
                 count += 1
         return count
 
-    def setitem_virtual(self, index, item):
+    def setitem(self, index, item, cf):
+        if self._items is None:
+            self._items = [None] * (index + 1)
+        if index >= len(self._items):
+            self._items = self._items + [None] * (index - len(self._items) + 1)
         self._items[index] = item
+        if cf is not None:
+            assert not self.is_virtual()
+            cf.register_dirty_field(self)
 
-    def getitem_virtual(self, index):
+    def getitem(self, index):
+        if self._items is None or index >= len(self._items):
+            return None
         return self._items[index]
 
     def getlength(self):
diff --git a/rpython/jit/metainterp/optimizeopt/rewrite.py 
b/rpython/jit/metainterp/optimizeopt/rewrite.py
--- a/rpython/jit/metainterp/optimizeopt/rewrite.py
+++ b/rpython/jit/metainterp/optimizeopt/rewrite.py
@@ -7,8 +7,7 @@
 from rpython.jit.metainterp.optimizeopt.intutils import IntBound
 from rpython.jit.metainterp.optimizeopt.optimizer import (Optimization, 
REMOVED,
     CONST_0, CONST_1)
-from rpython.jit.metainterp.optimizeopt.info import INFO_NONNULL, INFO_NULL,\
-     ArrayPtrInfo
+from rpython.jit.metainterp.optimizeopt.info import INFO_NONNULL, INFO_NULL
 from rpython.jit.metainterp.optimizeopt.util import _findall, 
make_dispatcher_method
 from rpython.jit.metainterp.resoperation import rop, ResOperation, opclasses,\
      OpHelpers
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to