[pypy-svn] r76994 - in pypy/branch/jit-generator/pypy/jit: backend backend/llgraph backend/test backend/x86 metainterp metainterp/test

arigo at codespeak.net arigo at codespeak.net
Fri Sep 10 11:51:09 CEST 2010


Author: arigo
Date: Fri Sep 10 11:51:07 2010
New Revision: 76994

Modified:
   pypy/branch/jit-generator/pypy/jit/backend/llgraph/llimpl.py
   pypy/branch/jit-generator/pypy/jit/backend/llgraph/runner.py
   pypy/branch/jit-generator/pypy/jit/backend/model.py
   pypy/branch/jit-generator/pypy/jit/backend/test/runner_test.py
   pypy/branch/jit-generator/pypy/jit/backend/x86/assembler.py
   pypy/branch/jit-generator/pypy/jit/backend/x86/runner.py
   pypy/branch/jit-generator/pypy/jit/metainterp/compile.py
   pypy/branch/jit-generator/pypy/jit/metainterp/jitdriver.py
   pypy/branch/jit-generator/pypy/jit/metainterp/pyjitpl.py
   pypy/branch/jit-generator/pypy/jit/metainterp/test/test_recursive.py
   pypy/branch/jit-generator/pypy/jit/metainterp/test/test_warmstate.py
   pypy/branch/jit-generator/pypy/jit/metainterp/warmspot.py
   pypy/branch/jit-generator/pypy/jit/metainterp/warmstate.py
Log:
Finish implementing and using redirect_call_assembler.


Modified: pypy/branch/jit-generator/pypy/jit/backend/llgraph/llimpl.py
==============================================================================
--- pypy/branch/jit-generator/pypy/jit/backend/llgraph/llimpl.py	(original)
+++ pypy/branch/jit-generator/pypy/jit/backend/llgraph/llimpl.py	Fri Sep 10 11:51:07 2010
@@ -165,6 +165,9 @@
         self.inputargs = []
         self.operations = []
 
+    def getargtypes(self):
+        return [v.concretetype for v in self.inputargs]
+
     def __repr__(self):
         lines = []
         self.as_text(lines, 1)
@@ -839,6 +842,8 @@
     def op_call_assembler(self, loop_token, *args):
         global _last_exception
         assert not self._forced
+        loop_token = self.cpu._redirected_call_assembler.get(loop_token,
+                                                             loop_token)
         self._may_force = self.opindex
         try:
             inpargs = _from_opaque(loop_token._llgraph_compiled_version).inputargs
@@ -861,6 +866,21 @@
                 vable = args[jd.index_of_virtualizable]
             else:
                 vable = lltype.nullptr(llmemory.GCREF.TO)
+            #
+            # Emulate the fast path
+            if failindex == self.cpu.done_with_this_frame_int_v:
+                reset_vable(jd, vable)
+                return self.cpu.get_latest_value_int(0)
+            if failindex == self.cpu.done_with_this_frame_ref_v:
+                reset_vable(jd, vable)
+                return self.cpu.get_latest_value_ref(0)
+            if failindex == self.cpu.done_with_this_frame_float_v:
+                reset_vable(jd, vable)
+                return self.cpu.get_latest_value_float(0)
+            if failindex == self.cpu.done_with_this_frame_void_v:
+                reset_vable(jd, vable)
+                return None
+            #
             assembler_helper_ptr = jd.assembler_helper_adr.ptr  # fish
             try:
                 return assembler_helper_ptr(failindex, vable)
@@ -1480,6 +1500,17 @@
     else:
         return 0
 
+def reset_vable(jd, vable):
+    if jd.index_of_virtualizable != -1:
+        fielddescr = jd.vable_token_descr
+        do_setfield_gc_int(vable, fielddescr.ofs, 0)
+
+def redirect_call_assembler(cpu, oldlooptoken, newlooptoken):
+    OLD = _from_opaque(oldlooptoken._llgraph_compiled_version).getargtypes()
+    NEW = _from_opaque(newlooptoken._llgraph_compiled_version).getargtypes()
+    assert OLD == NEW
+    cpu._redirected_call_assembler[oldlooptoken] = newlooptoken
+
 # ____________________________________________________________
 
 

Modified: pypy/branch/jit-generator/pypy/jit/backend/llgraph/runner.py
==============================================================================
--- pypy/branch/jit-generator/pypy/jit/backend/llgraph/runner.py	(original)
+++ pypy/branch/jit-generator/pypy/jit/backend/llgraph/runner.py	Fri Sep 10 11:51:07 2010
@@ -102,6 +102,7 @@
         llimpl._llinterp = LLInterpreter(self.rtyper)
         self._future_values = []
         self._descrs = {}
+        self._redirected_call_assembler = {}
 
     def _freeze_(self):
         assert self.translate_support_code
@@ -169,8 +170,8 @@
                 elif isinstance(x, history.ConstFloat):
                     llimpl.compile_add_float_const(c, x.value)
                 else:
-                    raise Exception("%s args contain: %r" % (op.getopname(),
-                                                             x))
+                    raise Exception("'%s' args contain: %r" % (op.getopname(),
+                                                               x))
             if op.is_guard():
                 faildescr = op.descr
                 assert isinstance(faildescr, history.AbstractFailDescr)
@@ -260,6 +261,11 @@
     def clear_latest_values(self, count):
         llimpl.frame_clear_latest_values(self.latest_frame, count)
 
+    def redirect_call_assembler(self, oldlooptoken, newlooptoken):
+        if we_are_translated():
+            raise ValueError("CALL_ASSEMBLER not supported")
+        llimpl.redirect_call_assembler(self, oldlooptoken, newlooptoken)
+
     # ----------
 
     def sizeof(self, S):

Modified: pypy/branch/jit-generator/pypy/jit/backend/model.py
==============================================================================
--- pypy/branch/jit-generator/pypy/jit/backend/model.py	(original)
+++ pypy/branch/jit-generator/pypy/jit/backend/model.py	Fri Sep 10 11:51:07 2010
@@ -107,6 +107,12 @@
         GUARD_NO_EXCEPTION.  (Returns a GCREF)"""        # XXX remove me
         raise NotImplementedError
 
+    def redirect_call_assembler(self, oldlooptoken, newlooptoken):
+        """Redirect oldlooptoken to newlooptoken.  More precisely, it is
+        enough to redirect all CALL_ASSEMBLERs already compiled that call
+        oldlooptoken so that from now own they will call newlooptoken."""
+        raise NotImplementedError
+
     @staticmethod
     def sizeof(S):
         raise NotImplementedError

Modified: pypy/branch/jit-generator/pypy/jit/backend/test/runner_test.py
==============================================================================
--- pypy/branch/jit-generator/pypy/jit/backend/test/runner_test.py	(original)
+++ pypy/branch/jit-generator/pypy/jit/backend/test/runner_test.py	Fri Sep 10 11:51:07 2010
@@ -1824,6 +1824,7 @@
         f2 = float_add(f0, f1)
         finish(f2)'''
         loop = parse(ops)
+        done_number = self.cpu.get_fail_descr_number(loop.operations[-1].descr)
         looptoken = LoopToken()
         looptoken.outermost_jitdriver_sd = FakeJitDriverSD()
         self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken)
@@ -1846,6 +1847,20 @@
         assert self.cpu.get_latest_value_float(0) == 13.5
         assert called
 
+        # test the fast path, which should not call assembler_helper()
+        del called[:]
+        self.cpu.done_with_this_frame_float_v = done_number
+        try:
+            othertoken = LoopToken()
+            self.cpu.compile_loop(loop.inputargs, loop.operations, othertoken)
+            self.cpu.set_future_value_float(0, 1.2)
+            self.cpu.set_future_value_float(1, 3.2)
+            res = self.cpu.execute_token(othertoken)
+            assert self.cpu.get_latest_value_float(0) == 1.2 + 3.2
+            assert not called
+        finally:
+            del self.cpu.done_with_this_frame_float_v
+
     def test_raw_malloced_getarrayitem(self):
         ARRAY = rffi.CArray(lltype.Signed)
         descr = self.cpu.arraydescrof(ARRAY)
@@ -1870,6 +1885,78 @@
         assert a[5] == 12345
         lltype.free(a, flavor='raw')
 
+    def test_redirect_call_assembler(self):
+        called = []
+        def assembler_helper(failindex, virtualizable):
+            assert self.cpu.get_latest_value_float(0) == 1.25 + 3.25
+            called.append(failindex)
+            return 13.5
+
+        FUNCPTR = lltype.Ptr(lltype.FuncType([lltype.Signed, llmemory.GCREF],
+                                             lltype.Float))
+        class FakeJitDriverSD:
+            index_of_virtualizable = -1
+            _assembler_helper_ptr = llhelper(FUNCPTR, assembler_helper)
+            assembler_helper_adr = llmemory.cast_ptr_to_adr(
+                _assembler_helper_ptr)
+
+        ARGS = [lltype.Float, lltype.Float]
+        RES = lltype.Float
+        FakeJitDriverSD.portal_calldescr = self.cpu.calldescrof(
+            lltype.Ptr(lltype.FuncType(ARGS, RES)), ARGS, RES)
+        
+        ops = '''
+        [f0, f1]
+        f2 = float_add(f0, f1)
+        finish(f2)'''
+        loop = parse(ops)
+        looptoken = LoopToken()
+        looptoken.outermost_jitdriver_sd = FakeJitDriverSD()
+        self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken)
+        self.cpu.set_future_value_float(0, 1.25)
+        self.cpu.set_future_value_float(1, 2.35)
+        res = self.cpu.execute_token(looptoken)
+        assert self.cpu.get_latest_value_float(0) == 1.25 + 2.35
+        assert not called
+
+        ops = '''
+        [f4, f5]
+        f3 = call_assembler(f4, f5, descr=looptoken)
+        guard_not_forced()[]
+        finish(f3)
+        '''
+        loop = parse(ops, namespace=locals())
+        othertoken = LoopToken()
+        self.cpu.compile_loop(loop.inputargs, loop.operations, othertoken)
+
+        # normal call_assembler: goes to looptoken
+        self.cpu.set_future_value_float(0, 1.25)
+        self.cpu.set_future_value_float(1, 3.25)
+        res = self.cpu.execute_token(othertoken)
+        assert self.cpu.get_latest_value_float(0) == 13.5
+        assert called
+        del called[:]
+
+        # compile a replacement
+        ops = '''
+        [f0, f1]
+        f2 = float_sub(f0, f1)
+        finish(f2)'''
+        loop = parse(ops)
+        looptoken2 = LoopToken()
+        looptoken2.outermost_jitdriver_sd = FakeJitDriverSD()
+        self.cpu.compile_loop(loop.inputargs, loop.operations, looptoken2)
+
+        # install it
+        self.cpu.redirect_call_assembler(looptoken, looptoken2)
+
+        # now, our call_assembler should go to looptoken2
+        self.cpu.set_future_value_float(0, 6.0)
+        self.cpu.set_future_value_float(1, 1.5)    # 6.0-1.5 == 1.25+3.25
+        res = self.cpu.execute_token(othertoken)
+        assert self.cpu.get_latest_value_float(0) == 13.5
+        assert called
+
 
 class OOtypeBackendTest(BaseBackendTest):
 

Modified: pypy/branch/jit-generator/pypy/jit/backend/x86/assembler.py
==============================================================================
--- pypy/branch/jit-generator/pypy/jit/backend/x86/assembler.py	(original)
+++ pypy/branch/jit-generator/pypy/jit/backend/x86/assembler.py	Fri Sep 10 11:51:07 2010
@@ -326,8 +326,10 @@
         looptoken._x86_param_depth = param_depth
 
         looptoken._x86_direct_bootstrap_code = self.mc.tell()
-        self._assemble_bootstrap_direct_call(arglocs, curadr,
-                                             frame_depth+param_depth)
+        finaljmp = self._assemble_bootstrap_direct_call(arglocs, curadr,
+                                                       frame_depth+param_depth)
+        looptoken._x86_redirect_call_assembler = finaljmp
+        #
         debug_print("Loop #", looptoken.number, "has address",
                     looptoken._x86_loop_code, "to", self.mc.tell())
         self.mc.end_function()
@@ -527,7 +529,24 @@
                 assert isinstance(loc, StackLoc)
                 self.mc.MOVSD_bx(loc.value, xmmtmp.value)
         self.mc.JMP_l(jmpadr)
-        return adr_stackadjust
+        return self.mc.tell()
+
+    def redirect_call_assembler(self, oldlooptoken, newlooptoken):
+        # some minimal sanity checking
+        oldnonfloatlocs, oldfloatlocs = oldlooptoken._x86_arglocs
+        newnonfloatlocs, newfloatlocs = newlooptoken._x86_arglocs
+        assert len(oldnonfloatlocs) == len(newnonfloatlocs)
+        assert len(oldfloatlocs) == len(newfloatlocs)
+        # must patch the JMP at the end of the oldlooptoken's bootstrap-
+        # -direct-call code to go to the new loop's body
+        adr = oldlooptoken._x86_redirect_call_assembler
+        target = newlooptoken._x86_loop_code
+        if IS_X86_64:
+            self.redirect_call_assembler_64(oldlooptoken, newlooptoken)
+        else:
+            mc = codebuf.InMemoryCodeBuilder(adr - 4, adr)
+            mc.writeimm32(target - adr)
+            mc.done()
 
     def _assemble_bootstrap_direct_call_64(self, arglocs, jmpadr, stackdepth):
         # XXX: Very similar to _emit_call_64
@@ -580,9 +599,19 @@
                 # clobber the scratch register
                 self.mc.MOV(loc, X86_64_SCRATCH_REG)
 
+        finaljmp = self.mc.tell()
         self.mc.JMP(imm(jmpadr))
-
-        return adr_stackadjust
+        # leave a total of 16 bytes, enough for all encodings of JMP
+        for i in range(self.mc.tell() - finaljmp, 16):
+            self.mc.NOP()
+        return finaljmp
+
+    def redirect_call_assembler_64(self, adr, target):
+        # we have a total of 16 bytes free to overwrite the JMP,
+        # reserved by _assemble_bootstrap_direct_call_64()
+        mc = codebuf.InMemoryCodeBuilder(adr, adr + 16)
+        mc.JMP(imm(target))
+        mc.done()
 
     def _assemble_bootstrap_code(self, inputargs, arglocs):
         nonfloatlocs, floatlocs = arglocs

Modified: pypy/branch/jit-generator/pypy/jit/backend/x86/runner.py
==============================================================================
--- pypy/branch/jit-generator/pypy/jit/backend/x86/runner.py	(original)
+++ pypy/branch/jit-generator/pypy/jit/backend/x86/runner.py	Fri Sep 10 11:51:07 2010
@@ -134,6 +134,9 @@
         assert fail_index == fail_index_2
         return faildescr
 
+    def redirect_call_assembler(self, oldlooptoken, newlooptoken):
+        self.assembler.redirect_call_assembler(oldlooptoken, newlooptoken)
+
 class CPU386(AbstractX86CPU):
     WORD = 4
     NUM_REGS = 8

Modified: pypy/branch/jit-generator/pypy/jit/metainterp/compile.py
==============================================================================
--- pypy/branch/jit-generator/pypy/jit/metainterp/compile.py	(original)
+++ pypy/branch/jit-generator/pypy/jit/metainterp/compile.py	Fri Sep 10 11:51:07 2010
@@ -559,18 +559,20 @@
 
 propagate_exception_descr = PropagateExceptionDescr()
 
-def compile_tmp_callback(cpu, jitdriver_sd, greenkey, redboxes):
+def compile_tmp_callback(cpu, jitdriver_sd, greenboxes, redboxes):
     """Make a LoopToken that corresponds to assembler code that just
     calls back the interpreter.  Used temporarily: a fully compiled
     version of the code may end up replacing it.
     """
-    # 'redboxes' is only used to know the types of red arguments
+    # 'redboxes' is only used to know the types of red arguments.
     inputargs = [box.clonebox() for box in redboxes]
     loop_token = make_loop_token(len(inputargs), jitdriver_sd)
-    #
+    # 'nb_red_args' might be smaller than len(redboxes),
+    # because it doesn't include the virtualizable boxes.
+    nb_red_args = jitdriver_sd.num_red_args
     k = jitdriver_sd.portal_runner_adr
     funcbox = history.ConstInt(heaptracker.adr2int(k))
-    callargs = [funcbox] + greenkey + inputargs
+    callargs = [funcbox] + greenboxes + inputargs[:nb_red_args]
     #
     result_type = jitdriver_sd.result_type
     if result_type == history.INT:
@@ -584,9 +586,9 @@
     else:
         assert 0, "bad result_type"
     if result is not None:
-        finishargs = []
-    else:
         finishargs = [result]
+    else:
+        finishargs = []
     #
     jd = jitdriver_sd
     faildescr = propagate_exception_descr

Modified: pypy/branch/jit-generator/pypy/jit/metainterp/jitdriver.py
==============================================================================
--- pypy/branch/jit-generator/pypy/jit/metainterp/jitdriver.py	(original)
+++ pypy/branch/jit-generator/pypy/jit/metainterp/jitdriver.py	Fri Sep 10 11:51:07 2010
@@ -10,6 +10,7 @@
     #    self.portal_runner_adr ... pypy.jit.metainterp.warmspot
     #    self.portal_calldescr  ... pypy.jit.metainterp.warmspot
     #    self.num_green_args    ... pypy.jit.metainterp.warmspot
+    #    self.num_red_args      ... pypy.jit.metainterp.warmspot
     #    self.result_type       ... pypy.jit.metainterp.warmspot
     #    self.virtualizable_info... pypy.jit.metainterp.warmspot
     #    self.warmstate         ... pypy.jit.metainterp.warmspot

Modified: pypy/branch/jit-generator/pypy/jit/metainterp/pyjitpl.py
==============================================================================
--- pypy/branch/jit-generator/pypy/jit/metainterp/pyjitpl.py	(original)
+++ pypy/branch/jit-generator/pypy/jit/metainterp/pyjitpl.py	Fri Sep 10 11:51:07 2010
@@ -690,25 +690,27 @@
         targetjitdriver_sd = self.metainterp.staticdata.jitdrivers_sd[jdindex]
         allboxes = greenboxes + redboxes
         warmrunnerstate = targetjitdriver_sd.warmstate
-        token = None
+        assembler_call = False
         if warmrunnerstate.inlining:
             if warmrunnerstate.can_inline_callable(greenboxes):
                 portal_code = targetjitdriver_sd.mainjitcode
                 return self.metainterp.perform_call(portal_code, allboxes,
                                                     greenkey=greenboxes)
-            token = warmrunnerstate.get_assembler_token(greenboxes, redboxes)
+            assembler_call = True
             # verify that we have all green args, needed to make sure
             # that assembler that we call is still correct
             self.verify_green_args(targetjitdriver_sd, greenboxes)
         #
-        return self.do_recursive_call(targetjitdriver_sd, allboxes, token)
+        return self.do_recursive_call(targetjitdriver_sd, allboxes,
+                                      assembler_call)
 
-    def do_recursive_call(self, targetjitdriver_sd, allboxes, token=None):
+    def do_recursive_call(self, targetjitdriver_sd, allboxes,
+                          assembler_call=False):
         portal_code = targetjitdriver_sd.mainjitcode
         k = targetjitdriver_sd.portal_runner_adr
         funcbox = ConstInt(heaptracker.adr2int(k))
-        return self.do_residual_call(funcbox, portal_code.calldescr,
-                                     allboxes, assembler_call_token=token,
+        return self.do_residual_call(funcbox, portal_code.calldescr, allboxes,
+                                     assembler_call=assembler_call,
                                      assembler_call_jd=targetjitdriver_sd)
 
     opimpl_recursive_call_i = _opimpl_recursive_call
@@ -828,8 +830,6 @@
             self.metainterp.reached_loop_header(greenboxes, redboxes)
             self.pc = saved_pc
         else:
-            warmrunnerstate = jitdriver_sd.warmstate
-            token = warmrunnerstate.get_assembler_token(greenboxes, redboxes)
             # warning! careful here.  We have to return from the current
             # frame containing the jit_merge_point, and then use
             # do_recursive_call() to follow the recursive call.  This is
@@ -843,7 +843,8 @@
             except ChangeFrame:
                 pass
             frame = self.metainterp.framestack[-1]
-            frame.do_recursive_call(jitdriver_sd, greenboxes + redboxes, token)
+            frame.do_recursive_call(jitdriver_sd, greenboxes + redboxes,
+                                    assembler_call=True)
             raise ChangeFrame
 
     def debug_merge_point(self, jitdriver_sd, greenkey):
@@ -1058,7 +1059,7 @@
         return resbox
 
     def do_residual_call(self, funcbox, descr, argboxes,
-                         assembler_call_token=None,
+                         assembler_call=False,
                          assembler_call_jd=None):
         # First build allboxes: it may need some reordering from the
         # list provided in argboxes, depending on the order in which
@@ -1096,16 +1097,15 @@
         if (effectinfo is None or
                 effectinfo.extraeffect ==
                              effectinfo.EF_FORCES_VIRTUAL_OR_VIRTUALIZABLE or
-                assembler_call_token is not None):
+                assembler_call):
             # residual calls require attention to keep virtualizables in-sync
             self.metainterp.clear_exception()
             self.metainterp.vable_and_vrefs_before_residual_call()
             resbox = self.metainterp.execute_and_record_varargs(
                 rop.CALL_MAY_FORCE, allboxes, descr=descr)
             self.metainterp.vrefs_after_residual_call()
-            if assembler_call_token is not None:
-                self.metainterp.direct_assembler_call(assembler_call_token,
-                                                      assembler_call_jd)
+            if assembler_call:
+                self.metainterp.direct_assembler_call(assembler_call_jd)
             if resbox is not None:
                 self.make_result_of_lastop(resbox)
             self.metainterp.vable_after_residual_call()
@@ -2104,20 +2104,24 @@
         op.args = [resbox_as_const] + op.args
         return resbox
 
-    def direct_assembler_call(self, token, targetjitdriver_sd):
+    def direct_assembler_call(self, targetjitdriver_sd):
         """ Generate a direct call to assembler for portal entry point,
         patching the CALL_MAY_FORCE that occurred just now.
         """
         op = self.history.operations.pop()
         assert op.opnum == rop.CALL_MAY_FORCE
         num_green_args = targetjitdriver_sd.num_green_args
-        args = op.args[num_green_args + 1:]
+        greenargs = op.args[1:num_green_args+1]
+        args = op.args[num_green_args+1:]
+        assert len(args) == targetjitdriver_sd.num_red_args
         vinfo = targetjitdriver_sd.virtualizable_info
         if vinfo is not None:
             index = targetjitdriver_sd.index_of_virtualizable
             vbox = args[index]
             args = args + self.gen_load_from_other_virtualizable(vinfo, vbox)
             # ^^^ and not "+=", which makes 'args' a resizable list
+        warmrunnerstate = targetjitdriver_sd.warmstate
+        token = warmrunnerstate.get_assembler_token(greenargs, args)
         op.opnum = rop.CALL_ASSEMBLER
         op.args = args
         op.descr = token

Modified: pypy/branch/jit-generator/pypy/jit/metainterp/test/test_recursive.py
==============================================================================
--- pypy/branch/jit-generator/pypy/jit/metainterp/test/test_recursive.py	(original)
+++ pypy/branch/jit-generator/pypy/jit/metainterp/test/test_recursive.py	Fri Sep 10 11:51:07 2010
@@ -612,9 +612,32 @@
                 driver.can_enter_jit(codeno=codeno, i=i, j=j)
 
         portal(2, 50)
-        self.meta_interp(portal, [2, 20], inline=True)
-        self.check_loops(call_assembler=0, call_may_force=1,
-                         everywhere=True)
+
+        from pypy.jit.metainterp import compile, pyjitpl
+        pyjitpl._warmrunnerdesc = None
+        trace = []
+        def my_ctc(*args):
+            looptoken = original_ctc(*args)
+            trace.append(looptoken)
+            return looptoken
+        original_ctc = compile.compile_tmp_callback
+        try:
+            compile.compile_tmp_callback = my_ctc
+            self.meta_interp(portal, [2, 20], inline=True)
+            self.check_loops(call_assembler=1, call_may_force=0,
+                             everywhere=True)
+        finally:
+            compile.compile_tmp_callback = original_ctc
+        # check that we made a temporary callback
+        assert len(trace) == 1
+        # and that we later redirected it to something else
+        try:
+            redirected = pyjitpl._warmrunnerdesc.cpu._redirected_call_assembler
+        except AttributeError:
+            pass    # not the llgraph backend
+        else:
+            print redirected
+            assert redirected.keys() == trace
 
     def test_directly_call_assembler_return(self):
         driver = JitDriver(greens = ['codeno'], reds = ['i', 'k'],

Modified: pypy/branch/jit-generator/pypy/jit/metainterp/test/test_warmstate.py
==============================================================================
--- pypy/branch/jit-generator/pypy/jit/metainterp/test/test_warmstate.py	(original)
+++ pypy/branch/jit-generator/pypy/jit/metainterp/test/test_warmstate.py	Fri Sep 10 11:51:07 2010
@@ -162,6 +162,8 @@
     assert cell1.entry_loop_token == "entry loop token"
 
 def test_make_jitdriver_callbacks_1():
+    class FakeWarmRunnerDesc:
+        cpu = None
     class FakeJitDriverSD:
         _green_args_spec = [lltype.Signed, lltype.Float]
         _get_printable_location_ptr = None
@@ -169,7 +171,7 @@
         _can_never_inline_ptr = None
     class FakeCell:
         dont_trace_here = False
-    state = WarmEnterState(None, FakeJitDriverSD())
+    state = WarmEnterState(FakeWarmRunnerDesc(), FakeJitDriverSD())
     def jit_getter(build, *args):
         return FakeCell()
     state.jit_getter = jit_getter
@@ -186,6 +188,7 @@
                                               lltype.Ptr(rstr.STR)))
     class FakeWarmRunnerDesc:
         rtyper = None
+        cpu = None
     class FakeJitDriverSD:
         _green_args_spec = [lltype.Signed, lltype.Float]
         _get_printable_location_ptr = llhelper(GET_LOCATION, get_location)
@@ -207,6 +210,7 @@
                                             lltype.Signed], lltype.Bool))
     class FakeWarmRunnerDesc:
         rtyper = None
+        cpu = None
     class FakeJitDriverSD:
         _green_args_spec = [lltype.Signed, lltype.Float]
         _get_printable_location_ptr = None
@@ -228,6 +232,7 @@
         [lltype.Signed, lltype.Float], lltype.Bool))
     class FakeWarmRunnerDesc:
         rtyper = None
+        cpu = None
     class FakeJitDriverSD:
         _green_args_spec = [lltype.Signed, lltype.Float]
         _get_printable_location_ptr = None

Modified: pypy/branch/jit-generator/pypy/jit/metainterp/warmspot.py
==============================================================================
--- pypy/branch/jit-generator/pypy/jit/metainterp/warmspot.py	(original)
+++ pypy/branch/jit-generator/pypy/jit/metainterp/warmspot.py	Fri Sep 10 11:51:07 2010
@@ -457,6 +457,7 @@
         jd._green_args_spec = [v.concretetype for v in greens_v]
         jd._red_args_types = [history.getkind(v.concretetype) for v in reds_v]
         jd.num_green_args = len(jd._green_args_spec)
+        jd.num_red_args = len(jd._red_args_types)
         RESTYPE = graph.getreturnvar().concretetype
         (jd._JIT_ENTER_FUNCTYPE,
          jd._PTR_JIT_ENTER_FUNCTYPE) = self.cpu.ts.get_FuncType(ALLARGS, lltype.Void)

Modified: pypy/branch/jit-generator/pypy/jit/metainterp/warmstate.py
==============================================================================
--- pypy/branch/jit-generator/pypy/jit/metainterp/warmstate.py	(original)
+++ pypy/branch/jit-generator/pypy/jit/metainterp/warmstate.py	Fri Sep 10 11:51:07 2010
@@ -211,7 +211,11 @@
                                               entry_loop_token):
         cell = self.jit_cell_at_key(greenkey)
         cell.counter = -1
+        old_token = cell.entry_loop_token
         cell.entry_loop_token = entry_loop_token
+        if old_token is not None:
+            cpu = self.warmrunnerdesc.cpu
+            cpu.redirect_call_assembler(old_token, entry_loop_token)
 
     # ----------
 
@@ -492,7 +496,7 @@
         unwrap_greenkey = self.make_unwrap_greenkey()
         jit_getter = self.make_jitcell_getter()
         jd = self.jitdriver_sd
-        cpu = warmrunnerdesc.cpu
+        cpu = self.warmrunnerdesc.cpu
 
         def can_inline_greenargs(*greenargs):
             if can_never_inline(*greenargs):



More information about the Pypy-commit mailing list