[pypy-svn] r67832 - in pypy/branch/remove-plfbid/pypy/jit/metainterp: . test

arigo at codespeak.net arigo at codespeak.net
Mon Sep 21 19:36:14 CEST 2009


Author: arigo
Date: Mon Sep 21 19:36:14 2009
New Revision: 67832

Modified:
   pypy/branch/remove-plfbid/pypy/jit/metainterp/compile.py
   pypy/branch/remove-plfbid/pypy/jit/metainterp/pyjitpl.py
   pypy/branch/remove-plfbid/pypy/jit/metainterp/test/test_send.py
   pypy/branch/remove-plfbid/pypy/jit/metainterp/test/test_tl.py
Log:
(pedronis, arigo)
Really kill PrepareLoopFromBridgeIsDisabled, and replace
it with a working (if inefficient) solution instead.


Modified: pypy/branch/remove-plfbid/pypy/jit/metainterp/compile.py
==============================================================================
--- pypy/branch/remove-plfbid/pypy/jit/metainterp/compile.py	(original)
+++ pypy/branch/remove-plfbid/pypy/jit/metainterp/compile.py	Mon Sep 21 19:36:14 2009
@@ -365,10 +365,10 @@
                                                                   new_loop)
         # store the new_loop in compiled_merge_points too
         # XXX it's probably useless to do so when optimizing
-        glob = metainterp_sd.globaldata
-        greenargs = glob.unpack_greenkey(greenkey)
-        old_loops = glob.compiled_merge_points.setdefault(greenargs, [])
-        old_loops.append(new_loop)
+        #glob = metainterp_sd.globaldata
+        #greenargs = glob.unpack_greenkey(greenkey)
+        #old_loops = glob.compiled_merge_points.setdefault(greenargs, [])
+        #old_loops.append(new_loop)
 
 
 def compile_fresh_bridge(metainterp, old_loops, resumekey):
@@ -388,7 +388,7 @@
     except InvalidLoop:
         assert 0, "InvalidLoop in optimize_bridge?"
         return None
-    # Did it work?  If not, prepare_loop_from_bridge() will probably be used.
+    # Did it work?
     if target_loop is not None:
         # Yes, we managed to create a bridge.  Dispatch to resumekey to
         # know exactly what we must do (ResumeGuardDescr/ResumeFromInterpDescr)
@@ -407,49 +407,3 @@
         descr = target_loop.finishdescr
         new_op = ResOperation(rop.FAIL, op.args, None, descr=descr)
         new_loop.operations[-1] = new_op
-
-
-def prepare_loop_from_bridge(metainterp, resumekey):
-    # To handle this case, we prepend to the history the unoptimized
-    # operations coming from the loop, in order to make a (fake) complete
-    # unoptimized trace.  (Then we will just compile this loop normally.)
-    raise PrepareLoopFromBridgeIsDisabled
-    if not we_are_translated():
-        log.info("completing the bridge into a stand-alone loop")
-    else:
-        debug_print("completing the bridge into a stand-alone loop")
-    operations = metainterp.history.operations
-    metainterp.history.operations = []
-    assert isinstance(resumekey, ResumeGuardDescr)
-    append_full_operations(metainterp.history,
-                           resumekey.history,
-                           resumekey.history_guard_index)
-    metainterp.history.operations.extend(operations)
-
-def append_full_operations(history, sourcehistory, guard_index):
-    prev = sourcehistory.source_link
-    if isinstance(prev, History):
-        append_full_operations(history, prev, sourcehistory.source_guard_index)
-    history.operations.extend(sourcehistory.operations[:guard_index])
-    op = inverse_guard(sourcehistory.operations[guard_index])
-    history.operations.append(op)
-
-def inverse_guard(guard_op):
-    suboperations = guard_op.suboperations
-    assert guard_op.is_guard()
-    if guard_op.opnum == rop.GUARD_TRUE:
-        guard_op = ResOperation(rop.GUARD_FALSE, guard_op.args, None)
-    elif guard_op.opnum == rop.GUARD_FALSE:
-        guard_op = ResOperation(rop.GUARD_TRUE, guard_op.args, None)
-    else:
-        # XXX other guards have no inverse so far
-        raise InverseTheOtherGuardsPlease(guard_op)
-    #
-    guard_op.suboperations = suboperations
-    return guard_op
-
-class InverseTheOtherGuardsPlease(Exception):
-    pass
-
-class PrepareLoopFromBridgeIsDisabled(Exception):
-    pass

Modified: pypy/branch/remove-plfbid/pypy/jit/metainterp/pyjitpl.py
==============================================================================
--- pypy/branch/remove-plfbid/pypy/jit/metainterp/pyjitpl.py	(original)
+++ pypy/branch/remove-plfbid/pypy/jit/metainterp/pyjitpl.py	Mon Sep 21 19:36:14 2009
@@ -802,17 +802,19 @@
 
     @arguments("orgpc")
     def opimpl_jit_merge_point(self, pc):
-        if self.metainterp.is_blackholing():
-            self.blackhole_reached_merge_point(self.env)
-            return True
-        else:
+        if not self.metainterp.is_blackholing():
             self.generate_merge_point(pc, self.env)
             if DEBUG > 0:
                 self.debug_merge_point()
             if self.metainterp.seen_can_enter_jit:
                 self.metainterp.seen_can_enter_jit = False
-                self.metainterp.reached_can_enter_jit(self.env)
-            return False
+                try:
+                    self.metainterp.reached_can_enter_jit(self.env)
+                except GiveUp:
+                    self.metainterp.switch_to_blackhole()
+        if self.metainterp.is_blackholing():
+            self.blackhole_reached_merge_point(self.env)
+        return True
 
     def debug_merge_point(self):
         # debugging: produce a DEBUG_MERGE_POINT operation
@@ -1287,18 +1289,21 @@
             op.pc = self.framestack[-1].pc
             op.name = self.framestack[-1].jitcode.name
 
+    def switch_to_blackhole(self):
+        self.history = None   # start blackholing
+        if not we_are_translated():
+            self.staticdata.stats.aborted_count += 1
+            history.log.event('ABORTING TRACING')
+        elif DEBUG:
+            debug_print('~~~ ABORTING TRACING')
+        self.staticdata.profiler.end_tracing()
+        self.staticdata.profiler.start_blackhole()
+
     def switch_to_blackhole_if_trace_too_long(self):
         if not self.is_blackholing():
             warmrunnerstate = self.staticdata.state
             if len(self.history.operations) > warmrunnerstate.trace_limit:
-                self.history = None   # start blackholing
-                if not we_are_translated():
-                    self.staticdata.stats.aborted_count += 1
-                    history.log.event('ABORTING TRACING')
-                elif DEBUG:
-                    debug_print('~~~ ABORTING TRACING')
-                self.staticdata.profiler.end_tracing()
-                self.staticdata.profiler.start_blackhole()
+                self.switch_to_blackhole()
 
     def _interpret(self):
         # Execute the frames forward until we raise a DoneWithThisFrame,
@@ -1425,16 +1430,7 @@
                 else:
                     assert start == 0
                     if self.extra_rebuild_operations >= 0:
-                        # The history only starts at a bridge, not at the
-                        # full loop header.  Complete it as a full loop by
-                        # inserting a copy of the operations from the old
-                        # loop branch before the guard that failed.
-                        start = self.extra_rebuild_operations
-                        assert start >= 0
-                        # clean up, but without shifting the end of the list
-                        for i in range(start):
-                            self.history.operations[i] = None
-                        compile.prepare_loop_from_bridge(self, self.resumekey)
+                        raise GiveUp
                 loop = self.compile(original_boxes, live_arg_boxes, start)
                 if loop is not None:
                     raise GenerateMergePoint(live_arg_boxes, loop)
@@ -1443,7 +1439,7 @@
                 # exactly its old list of operations...
                 # xxx maybe we could patch history.operations with
                 # Nones after calling self.compile() instead of
-                # before...
+                # before...  xxx maybe we should just raise GiveUp
                 del self.history.operations[:]
                 self.history.operations.extend(oldops)
 
@@ -1605,9 +1601,7 @@
             else:
                 self.history = history.History(self.cpu)
                 extra = len(suboperations) - 1
-                assert extra >= 0
-                for i in range(extra):
-                    self.history.operations.append(suboperations[i])
+                assert extra == 0     # for now
                 self.extra_rebuild_operations = extra
         if must_compile:
             self.staticdata.profiler.start_tracing()
@@ -1814,3 +1808,6 @@
         assert target_loop is not None
         self.argboxes = args
         self.target_loop = target_loop
+
+class GiveUp(Exception):
+    pass

Modified: pypy/branch/remove-plfbid/pypy/jit/metainterp/test/test_send.py
==============================================================================
--- pypy/branch/remove-plfbid/pypy/jit/metainterp/test/test_send.py	(original)
+++ pypy/branch/remove-plfbid/pypy/jit/metainterp/test/test_send.py	Mon Sep 21 19:36:14 2009
@@ -374,6 +374,35 @@
         self.check_loops(new_with_vtable=0)
         self.check_loop_count(2)
 
+    def test_behavior_change_after_a_while(self):
+        myjitdriver = JitDriver(greens = [], reds = ['x', 'y'])
+        class Base:
+            def __init__(self, value):
+                self.value = value
+        class Int1(Base):
+            pass
+        class Int2(Base):
+            pass
+        cases = [False, True, True, True, True]*40
+        def f(y):
+            x = Int1(0)
+            while y > 0:
+                myjitdriver.can_enter_jit(x=x, y=y)
+                myjitdriver.jit_merge_point(x=x, y=y)
+                y -= 1
+                value = x.value + 1
+                if cases[y]:
+                    x = Int1(value)
+                else:
+                    x = Int2(value)
+            return x.value
+        res = self.meta_interp(f, [len(cases)])
+        assert res == 200
+        # for now, we really expect only 1 loop.  This is known to be kind
+        # of wrong.  XXX later...
+        self.check_loop_count(2)        # 1 loop + 1 bridge
+        self.check_tree_loop_count(2)   # 1 loop + 1 entry bridge  (argh)
+
     def test_three_cases(self):
         class Node:
             def __init__(self, x):

Modified: pypy/branch/remove-plfbid/pypy/jit/metainterp/test/test_tl.py
==============================================================================
--- pypy/branch/remove-plfbid/pypy/jit/metainterp/test/test_tl.py	(original)
+++ pypy/branch/remove-plfbid/pypy/jit/metainterp/test/test_tl.py	Mon Sep 21 19:36:14 2009
@@ -133,7 +133,7 @@
               PUSH 1
               ADD
               PICK 0
-              PUSH 3
+              PUSH 5
               LE
               BR_COND inside
               PUSH 1



More information about the Pypy-commit mailing list