Author: Carl Friedrich Bolz <cfb...@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) _______________________________________________ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit