Author: Carl Friedrich Bolz <[email protected]>
Branch: 
Changeset: r78989:e226d71c9665
Date: 2015-08-14 19:11 +0200
http://bitbucket.org/pypy/pypy/changeset/e226d71c9665/

Log:    optimize nullity in the heapcache

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
@@ -9,6 +9,7 @@
 
     def reset_keep_likely_virtual(self):
         self.known_class = False
+        self.known_nullity = False
         # did we see the allocation during tracing?
         self.seen_allocation = False
         self.is_unescaped = False
@@ -290,6 +291,15 @@
     def class_now_known(self, box):
         self.getvalue(box).known_class = True
 
+    def is_nullity_known(self, box):
+        value = self.getvalue(box, create=False)
+        if value:
+            return value.known_nullity
+        return False
+
+    def nullity_now_known(self, box):
+        self.getvalue(box).known_nullity = True
+
     def is_nonstandard_virtualizable(self, box):
         value = self.getvalue(box, create=False)
         if value:
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
@@ -369,7 +369,10 @@
         ).compile()
 
     def _establish_nullity(self, box, orgpc):
+        heapcache = self.metainterp.heapcache
         value = box.nonnull()
+        if heapcache.is_nullity_known(box):
+            return value
         if value:
             if not self.metainterp.heapcache.is_class_known(box):
                 self.metainterp.generate_guard(rop.GUARD_NONNULL, box,
@@ -380,6 +383,7 @@
                                                resumepc=orgpc)
                 promoted_box = box.constbox()
                 self.metainterp.replace_box(box, promoted_box)
+        heapcache.nullity_now_known(box)
         return value
 
     @arguments("box", "label", "orgpc")
diff --git a/rpython/jit/metainterp/test/test_heapcache.py 
b/rpython/jit/metainterp/test/test_heapcache.py
--- a/rpython/jit/metainterp/test/test_heapcache.py
+++ b/rpython/jit/metainterp/test/test_heapcache.py
@@ -69,6 +69,19 @@
         assert not h.is_class_known(1)
         assert not h.is_class_known(2)
 
+    def test_known_nullity(self):
+        h = HeapCache()
+        assert not h.is_nullity_known(1)
+        assert not h.is_nullity_known(2)
+        h.nullity_now_known(1)
+        assert h.is_nullity_known(1)
+        assert not h.is_nullity_known(2)
+
+        h.reset()
+        assert not h.is_nullity_known(1)
+        assert not h.is_nullity_known(2)
+
+
     def test_nonstandard_virtualizable(self):
         h = HeapCache()
         assert not h.is_nonstandard_virtualizable(1)
diff --git a/rpython/jit/metainterp/test/test_tracingopts.py 
b/rpython/jit/metainterp/test/test_tracingopts.py
--- a/rpython/jit/metainterp/test/test_tracingopts.py
+++ b/rpython/jit/metainterp/test/test_tracingopts.py
@@ -107,6 +107,28 @@
         assert res == -7 * 2
         self.check_operations_history(getfield_gc=1)
 
+    def test_heap_caching_nonnull(self):
+        class A:
+            def __init__(self, x=None):
+                self.next = x
+        a0 = A()
+        a1 = A()
+        a2 = A(a1)
+        def fn(n):
+            if n > 0:
+                a = a1
+            else:
+                a = a2
+            if a.next:
+                a = A(a.next)
+                result = a.next is not None
+                a0.next = a
+                return result
+            return False
+        res = self.interp_operations(fn, [-7])
+        assert res == True
+        self.check_operations_history(guard_nonnull=1)
+
     def test_heap_caching_while_tracing_invalidation(self):
         class A:
             pass
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to