Commits

Carl Friedrich Bolz committed 4303dff

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

Comments (0)

Files changed (2)

pypy/jit/metainterp/pyjitpl.py

     @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")
         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
                 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)

pypy/jit/metainterp/test/test_ajit.py

         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