[pypy-commit] pypy improve-heap-caching-tracing: add the knowledge that two boxes with that were the result of a "new" operation
cfbolz
noreply at buildbot.pypy.org
Fri Sep 2 15:13:33 CEST 2011
Author: Carl Friedrich Bolz <cfbolz at gmx.de>
Branch: improve-heap-caching-tracing
Changeset: r47022:604e55dccba6
Date: 2011-09-02 15:13 +0200
http://bitbucket.org/pypy/pypy/changeset/604e55dccba6/
Log: add the knowledge that two boxes with that were the result of a
"new" operation can never alias each other.
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
@@ -8,6 +8,8 @@
def reset(self):
# contains boxes where the class is already known
self.known_class_boxes = {}
+ # store the boxes that contain newly allocated objects:
+ self.new_boxes = {}
# contains frame boxes that are not virtualizables
self.nonstandard_virtualizables = {}
# heap cache
@@ -46,6 +48,8 @@
def nonstandard_virtualizables_now_known(self, box):
self.nonstandard_virtualizables[box] = None
+ def new(self, box):
+ self.new_boxes[box] = None
def getfield(self, box, descr):
d = self.heap_cache.get(descr, None)
@@ -59,7 +63,15 @@
self.heap_cache.setdefault(descr, {})[box] = fieldbox
def setfield(self, box, descr, fieldbox):
- self.heap_cache[descr] = {box: fieldbox}
+ d = self.heap_cache.get(descr, None)
+ new_d = {box: fieldbox}
+ if not d or box not in self.new_boxes:
+ self.heap_cache[descr] = new_d
+ return
+ for frombox, tobox in d.iteritems():
+ if frombox in self.new_boxes:
+ new_d[frombox] = tobox
+ self.heap_cache[descr] = new_d
def getarrayitem(self, box, descr, indexbox):
if not isinstance(indexbox, ConstInt):
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
@@ -374,6 +374,7 @@
cpu = self.metainterp.cpu
cls = heaptracker.descr2vtable(cpu, sizedescr)
resbox = self.execute(rop.NEW_WITH_VTABLE, ConstInt(cls))
+ self.metainterp.heapcache.new(resbox)
self.metainterp.heapcache.class_now_know(resbox)
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
@@ -81,7 +81,7 @@
assert h.getfield(box1, descr2) is None
assert h.getfield(box3, descr1) is None
- def test_heapcache_fields_multiple(self):
+ def test_heapcache_read_fields_multiple(self):
h = HeapCache()
h.getfield_now_known(box1, descr1, box2)
h.getfield_now_known(box3, descr1, box4)
@@ -96,6 +96,31 @@
assert h.getfield(box3, descr1) is None
assert h.getfield(box3, descr2) is None
+ def test_heapcache_write_fields_multiple(self):
+ h = HeapCache()
+ h.setfield(box1, descr1, box2)
+ assert h.getfield(box1, descr1) is box2
+ h.setfield(box3, descr1, box4)
+ assert h.getfield(box3, descr1) is box4
+ assert h.getfield(box1, descr1) is None # box1 and box3 can alias
+
+ h = HeapCache()
+ h.new(box1)
+ h.setfield(box1, descr1, box2)
+ assert h.getfield(box1, descr1) is box2
+ h.setfield(box3, descr1, box4)
+ assert h.getfield(box3, descr1) is box4
+ assert h.getfield(box1, descr1) is None # box1 and box3 can alias
+
+ h = HeapCache()
+ h.new(box1)
+ h.new(box3)
+ h.setfield(box1, descr1, box2)
+ assert h.getfield(box1, descr1) is box2
+ h.setfield(box3, descr1, box4)
+ assert h.getfield(box3, descr1) is box4
+ assert h.getfield(box1, descr1) is box2 # box1 and box3 cannot alias
+
def test_heapcache_arrays(self):
h = HeapCache()
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
@@ -423,8 +423,8 @@
return a1.x + a2.x + a1.x + a2.x
res = self.interp_operations(fn, [7])
assert res == 2 * 7 + 2 * 6
- self.check_operations_history(getfield_gc=2)
+ self.check_operations_history(getfield_gc=0)
res = self.interp_operations(fn, [-7])
assert res == 2 * -7 + 2 * -8
- self.check_operations_history(getfield_gc=2)
+ self.check_operations_history(getfield_gc=0)
More information about the pypy-commit
mailing list