Author: Armin Rigo <ar...@tunes.org>
Branch: 
Changeset: r95435:b010806d20bf
Date: 2018-12-07 11:19 +0200
http://bitbucket.org/pypy/pypy/changeset/b010806d20bf/

Log:    Fix for 708fbffab6a0

diff --git a/rpython/jit/metainterp/optimizeopt/rewrite.py 
b/rpython/jit/metainterp/optimizeopt/rewrite.py
--- a/rpython/jit/metainterp/optimizeopt/rewrite.py
+++ b/rpython/jit/metainterp/optimizeopt/rewrite.py
@@ -389,6 +389,8 @@
     def optimize_GUARD_SUBCLASS(self, op):
         info = self.getptrinfo(op.getarg(0))
         optimizer = self.optimizer
+        # must raise 'InvalidLoop' in all cases where 'info' shows the
+        # class cannot possibly match (see test_issue2926)
         if info and info.is_constant():
             c = self.get_box_replacement(op.getarg(0))
             vtable = optimizer.cpu.ts.cls_of_box(c).getint()
@@ -398,13 +400,29 @@
         if info is not None and info.is_about_object():
             known_class = info.get_known_class(optimizer.cpu)
             if known_class:
+                # Class of 'info' is exactly 'known_class'.
+                # We know statically if the 'guard_subclass' will pass or fail.
                 if optimizer._check_subclass(known_class.getint(),
                                              op.getarg(1).getint()):
                     return
+                else:
+                    raise InvalidLoop(
+                        "GUARD_SUBCLASS(known_class) proven to always fail")
             elif info.get_descr() is not None:
-                if optimizer._check_subclass(info.get_descr().get_vtable(),
+                # Class of 'info' is either get_descr() or a subclass of it.
+                # We're keeping the 'guard_subclass' at runtime only in the
+                # case where get_descr() is some strict parent class of
+                # the argument to 'guard_subclass'.
+                info_base_descr = info.get_descr().get_vtable()
+                if optimizer._check_subclass(info_base_descr,
                                              op.getarg(1).getint()):
-                    return
+                    return    # guard_subclass always passing
+                elif optimizer._check_subclass(op.getarg(1).getint(),
+                                               info_base_descr):
+                    pass      # don't know, must keep the 'guard_subclass'
+                else:
+                    raise InvalidLoop(
+                        "GUARD_SUBCLASS(base_class) proven to always fail")
         return self.emit(op)
 
     def optimize_GUARD_NONNULL(self, op):
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to