[pypy-commit] pypy jit-simplify-backendintf: Switch to a less magical way of specializing execute_token(),

arigo noreply at buildbot.pypy.org
Sun Dec 11 22:42:26 CET 2011


Author: Armin Rigo <arigo at tunes.org>
Branch: jit-simplify-backendintf
Changeset: r50398:82684fd1231e
Date: 2011-12-11 22:24 +0100
http://bitbucket.org/pypy/pypy/changeset/82684fd1231e/

Log:	Switch to a less magical way of specializing execute_token(), one
	which has a chance to work in a real backend too.

diff --git a/pypy/jit/backend/llgraph/runner.py b/pypy/jit/backend/llgraph/runner.py
--- a/pypy/jit/backend/llgraph/runner.py
+++ b/pypy/jit/backend/llgraph/runner.py
@@ -260,32 +260,31 @@
         self.latest_frame = frame
         return fail_index
 
-    def execute_token(self, loop_token, *args):
-        """Calls the assembler generated for the given loop.
-        Returns the ResOperation that failed, of type rop.FAIL.
-        """
-        if we_are_translated():
-            assert len(args) <= 10
-            iterator = unrolling_iterable_10
-        else:
-            iterator = range(len(args))
+    def make_execute_token(self, *argkinds):
+        nb_args = len(argkinds)
+        unroll_argkinds = unrolling_iterable(list(enumerate(argkinds)))
         #
-        for index in iterator:
-            if index == len(args):
-                break
-            x = args[index]
-            TYPE = lltype.typeOf(x)
-            if TYPE == lltype.Signed:
-                llimpl.set_future_value_int(index, x)
-            elif TYPE == llmemory.GCREF:
-                llimpl.set_future_value_ref(index, x)
-            elif TYPE == longlong.FLOATSTORAGE:
-                llimpl.set_future_value_float(index, x)
-            else:
-                raise ValueError(TYPE)
+        def execute_token(loop_token, *args):
+            assert len(args) == nb_args
+            for index, kind in unroll_argkinds:
+                x = args[index]
+                TYPE = lltype.typeOf(x)
+                if kind == INT:
+                    assert TYPE == lltype.Signed
+                    llimpl.set_future_value_int(index, x)
+                elif kind == REF:
+                    assert TYPE == llmemory.GCREF
+                    llimpl.set_future_value_ref(index, x)
+                elif kind == FLOAT:
+                    assert TYPE == longlong.FLOATSTORAGE
+                    llimpl.set_future_value_float(index, x)
+                else:
+                    assert 0
+            #
+            fail_index = self._execute_token(loop_token)
+            return self.get_fail_descr_from_number(fail_index)
         #
-        fail_index = self._execute_token(loop_token)
-        return self.get_fail_descr_from_number(fail_index)
+        return execute_token
 
     def get_latest_value_int(self, index):
         return llimpl.frame_int_getvalue(self.latest_frame, index)
@@ -700,8 +699,6 @@
         return x
 
 
-unrolling_iterable_10 = unrolling_iterable(range(10))
-
 def make_getargs(ARGS):
     argsiter = unrolling_iterable(ARGS)
     args_n = len([ARG for ARG in ARGS if ARG is not ootype.Void])
diff --git a/pypy/jit/backend/model.py b/pypy/jit/backend/model.py
--- a/pypy/jit/backend/model.py
+++ b/pypy/jit/backend/model.py
@@ -85,12 +85,18 @@
         raise NotImplementedError
 
     def execute_token(self, looptoken, *args):
-        """Execute the generated code referenced by the looptoken.
+        """NOT_RPYTHON (for tests only)
+        Execute the generated code referenced by the looptoken.
         Returns the descr of the last executed operation: either the one
         attached to the failing guard, or the one attached to the FINISH.
         Use get_latest_value_xxx() afterwards to read the result(s).
-        (This method is automatically specialized by the front-end if
-        needed, for various types and numbers of *args.)
+        """
+        execute = self.make_execute_token(*[history.getkind(x) for x in args])
+        return execute(looptoken, *args)
+
+    def make_execute_token(self, *argkinds):
+        """Must make and return an execute_token() function that will be
+        called with the given argtypes.
         """
         raise NotImplementedError
 
diff --git a/pypy/jit/metainterp/jitdriver.py b/pypy/jit/metainterp/jitdriver.py
--- a/pypy/jit/metainterp/jitdriver.py
+++ b/pypy/jit/metainterp/jitdriver.py
@@ -11,6 +11,7 @@
     #    self.portal_calldescr  ... pypy.jit.metainterp.warmspot
     #    self.num_green_args    ... pypy.jit.metainterp.warmspot
     #    self.num_red_args      ... pypy.jit.metainterp.warmspot
+    #    self.red_args_types    ... pypy.jit.metainterp.warmspot
     #    self.result_type       ... pypy.jit.metainterp.warmspot
     #    self.virtualizable_info... pypy.jit.metainterp.warmspot
     #    self.greenfield_info   ... pypy.jit.metainterp.warmspot
diff --git a/pypy/jit/metainterp/warmspot.py b/pypy/jit/metainterp/warmspot.py
--- a/pypy/jit/metainterp/warmspot.py
+++ b/pypy/jit/metainterp/warmspot.py
@@ -522,9 +522,9 @@
         greens_v, reds_v = support.decode_hp_hint_args(op)
         ALLARGS = [v.concretetype for v in (greens_v + reds_v)]
         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.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)
+        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)
diff --git a/pypy/jit/metainterp/warmstate.py b/pypy/jit/metainterp/warmstate.py
--- a/pypy/jit/metainterp/warmstate.py
+++ b/pypy/jit/metainterp/warmstate.py
@@ -282,15 +282,14 @@
         confirm_enter_jit = self.confirm_enter_jit
         range_red_args = unrolling_iterable(
             range(num_green_args, num_green_args + jitdriver_sd.num_red_args))
-        # hack: make a new copy of the method
-        func_execute_token = self.cpu.execute_token.im_func
-        func_execute_token = func_with_new_name(func_execute_token,
-                                                "execute_token_spec")
+        # get a new specialized copy of the method
+        func_execute_token = self.cpu.make_execute_token(
+            *[kind[0] for kind in jitdriver_sd.red_args_types])
 
         def execute_assembler(loop_token, *args):
             # Call the backend to run the 'looptoken' with the given
             # input args.
-            fail_descr = func_execute_token(self.cpu, loop_token, *args)
+            fail_descr = func_execute_token(loop_token, *args)
             #
             # If we have a virtualizable, we have to reset its
             # 'vable_token' field afterwards


More information about the pypy-commit mailing list