[pypy-commit] pypy jit-frontend-unescaped: add some primitive escaped tracking in the frontend, it doesn't handle any sort of recursive structures, but that's ok.
alex_gaynor
noreply at buildbot.pypy.org
Sat Sep 17 05:13:13 CEST 2011
Author: Alex Gaynor <alex.gaynor at gmail.com>
Branch: jit-frontend-unescaped
Changeset: r47314:86e1dad57504
Date: 2011-09-16 23:11 -0400
http://bitbucket.org/pypy/pypy/changeset/86e1dad57504/
Log: add some primitive escaped tracking in the frontend, it doesn't
handle any sort of recursive structures, but that's ok.
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
@@ -9,7 +9,10 @@
def reset(self):
# contains boxes where the class is already known
self.known_class_boxes = {}
- # store the boxes that contain newly allocated objects:
+ # store the boxes that contain newly allocated objects, this maps the
+ # boxes to a bool, the bool indicates whether or not the object has
+ # escaped the trace or not, its presences in the mapping shows that it
+ # was allocated inside the trace
self.new_boxes = {}
# contains frame boxes that are not virtualizables
self.nonstandard_virtualizables = {}
@@ -23,6 +26,17 @@
self.length_cache = {}
def invalidate_caches(self, opnum, descr, argboxes):
+ self.mark_escaped(opnum, argboxes)
+ self.clear_caches(opnum, descr, argboxes)
+
+ def mark_escaped(self, opnum, argboxes):
+ for idx, box in enumerate(argboxes):
+ # setfield_gc and setarrayitem_gc don't escape their first argument
+ if not (idx == 0 and opnum in [rop.SETFIELD_GC, rop.SETARRAYITEM_GC]):
+ if box in self.new_boxes:
+ self.new_boxes[box] = False
+
+ def clear_caches(self, opnum, descr, argboxes):
if opnum == rop.SETFIELD_GC:
return
if opnum == rop.SETARRAYITEM_GC:
@@ -73,8 +87,11 @@
def nonstandard_virtualizables_now_known(self, box):
self.nonstandard_virtualizables[box] = None
+ def is_unescaped(self, box):
+ return self.new_boxes.get(box, False)
+
def new(self, box):
- self.new_boxes[box] = None
+ self.new_boxes[box] = True
def new_array(self, box, lengthbox):
self.new(box)
@@ -146,7 +163,6 @@
indexcache = cache.get(index, None)
cache[index] = self._do_write_with_aliasing(indexcache, box, valuebox)
-
def arraylen(self, box):
return self.length_cache.get(box, None)
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
@@ -326,3 +326,22 @@
[None, None, box2, None, None]
)
assert h.getarrayitem(box4, descr1, index1) is None
+
+ def test_unescaped(self):
+ h = HeapCache()
+ assert not h.is_unescaped(box1)
+ h.new(box2)
+ assert h.is_unescaped(box2)
+ h.invalidate_caches(rop.SETFIELD_GC, None, [box2, box1])
+ assert h.is_unescaped(box2)
+ h.invalidate_caches(rop.SETFIELD_GC, None, [box1, box2])
+ assert not h.is_unescaped(box2)
+
+ def test_unescaped_array(self):
+ h = HeapCache()
+ h.new_array(box1, lengthbox1)
+ assert h.is_unescaped(box1)
+ h.invalidate_caches(rop.SETARRAYITEM_GC, None, [box1, index1, box2])
+ assert h.is_unescaped(box1)
+ h.invalidate_caches(rop.SETARRAYITEM_GC, None, [box2, index1, box1])
+ assert not h.is_unescaped(box1)
\ No newline at end of file
More information about the pypy-commit
mailing list