[pypy-commit] pypy default: (cfbolz, arigo around): dont record guard_class operations on the same box

cfbolz noreply at buildbot.pypy.org
Thu Jul 7 15:08:56 CEST 2011


Author: Carl Friedrich Bolz <cfbolz at gmx.de>
Branch: 
Changeset: r45406:4303dff32d79
Date: 2011-07-07 15:17 +0200
http://bitbucket.org/pypy/pypy/changeset/4303dff32d79/

Log:	(cfbolz, arigo around): dont record guard_class operations on the
	same box repeatedly. saves a luarge percentage of guards.

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
@@ -845,7 +845,9 @@
     @arguments("orgpc", "box")
     def opimpl_guard_class(self, orgpc, box):
         clsbox = self.cls_of_box(box)
-        self.generate_guard(rop.GUARD_CLASS, box, [clsbox], resumepc=orgpc)
+        if box not in self.metainterp.known_class_boxes:
+            self.generate_guard(rop.GUARD_CLASS, box, [clsbox], resumepc=orgpc)
+            self.metainterp.known_class_boxes[box] = None
         return clsbox
 
     @arguments("int", "orgpc")
@@ -1449,6 +1451,8 @@
         self.last_exc_value_box = None
         self.retracing_loop_from = None
         self.call_pure_results = args_dict_box()
+        # contains boxes where the class is already known
+        self.known_class_boxes = {}
 
     def perform_call(self, jitcode, boxes, greenkey=None):
         # causes the metainterp to enter the given subfunction
@@ -1789,6 +1793,8 @@
                 duplicates[box] = None
 
     def reached_loop_header(self, greenboxes, redboxes, resumedescr):
+        self.known_class_boxes = {}
+
         duplicates = {}
         self.remove_consts_and_duplicates(redboxes, len(redboxes),
                                           duplicates)
diff --git a/pypy/jit/metainterp/test/test_ajit.py b/pypy/jit/metainterp/test/test_ajit.py
--- a/pypy/jit/metainterp/test/test_ajit.py
+++ b/pypy/jit/metainterp/test/test_ajit.py
@@ -1021,6 +1021,24 @@
         res = self.meta_interp(main, [])
         assert res == 55
 
+
+    def test_dont_record_guard_class(self):
+        class A:
+            pass
+        class B(A):
+            pass
+        def fn(n):
+            if n:
+                obj = A()
+            else:
+                obj = B()
+            return isinstance(obj, B) + isinstance(obj, B) + isinstance(obj, B) + isinstance(obj, B)
+        res = self.interp_operations(fn, [0])
+        assert res
+        self.check_operations_history(guard_class=1)
+        res = self.interp_operations(fn, [1])
+        assert not res
+
     def test_assert_isinstance(self):
         class A:
             pass


More information about the pypy-commit mailing list