[pypy-svn] r61848 - in pypy/branch/oo-jit/pypy: jit/codegen/i386 module/pypyjit translator/cli translator/goal

antocuni at codespeak.net antocuni at codespeak.net
Fri Feb 13 20:32:49 CET 2009


Author: antocuni
Date: Fri Feb 13 20:32:47 2009
New Revision: 61848

Modified:
   pypy/branch/oo-jit/pypy/jit/codegen/i386/ri386.py
   pypy/branch/oo-jit/pypy/module/pypyjit/__init__.py
   pypy/branch/oo-jit/pypy/module/pypyjit/interp_jit.py
   pypy/branch/oo-jit/pypy/module/pypyjit/newbool.py
   pypy/branch/oo-jit/pypy/module/pypyjit/portal.py
   pypy/branch/oo-jit/pypy/translator/cli/opcodes.py
   pypy/branch/oo-jit/pypy/translator/goal/targetpypystandalone.py
Log:
tentative checkin: try to revert the pypy hint to the pre-hotpath
state. Probably broken, I check in this so that I can try a translation
somewhere else



Modified: pypy/branch/oo-jit/pypy/jit/codegen/i386/ri386.py
==============================================================================
--- pypy/branch/oo-jit/pypy/jit/codegen/i386/ri386.py	(original)
+++ pypy/branch/oo-jit/pypy/jit/codegen/i386/ri386.py	Fri Feb 13 20:32:47 2009
@@ -1,5 +1,5 @@
 from pypy.rlib.rarithmetic import intmask
-from pypy.rlib.objectmodel import ComputedIntSymbolic
+from pypy.rlib.objectmodel import ComputedIntSymbolic, CDefinedIntSymbolic
 
 class OPERAND(object):
     _attrs_ = []
@@ -246,6 +246,8 @@
 def imm(value):
     if isinstance(value, ComputedIntSymbolic):
         value = value.compute_fn()
+    elif isinstance(value, CDefinedIntSymbolic):
+        raise TypeError # XXX?
     assert isinstance(value, int)
     if single_byte(value):
         return imm8(value)

Modified: pypy/branch/oo-jit/pypy/module/pypyjit/__init__.py
==============================================================================
--- pypy/branch/oo-jit/pypy/module/pypyjit/__init__.py	(original)
+++ pypy/branch/oo-jit/pypy/module/pypyjit/__init__.py	Fri Feb 13 20:32:47 2009
@@ -5,9 +5,9 @@
     }
 
     interpleveldefs = {
-        'set_param':    'interp_jit.set_param',
+        'enable': 'interp_jit.enable',
     }
 
     def setup_after_space_initialization(self):
-        # force the __extend__ hacks to occur early
+        # force the setup() to run early
         import pypy.module.pypyjit.interp_jit

Modified: pypy/branch/oo-jit/pypy/module/pypyjit/interp_jit.py
==============================================================================
--- pypy/branch/oo-jit/pypy/module/pypyjit/interp_jit.py	(original)
+++ pypy/branch/oo-jit/pypy/module/pypyjit/interp_jit.py	Fri Feb 13 20:32:47 2009
@@ -1,15 +1,17 @@
 """This is not the JIT :-)
 
-This is transformed to become a JIT by code elsewhere: pypy/jit/*
+The pypyjit module helpers set the 'jit_enable' flag on code objects.
+The code below makes two identical copies of the interpreter's main
+loop, and the flag controls which of them is used.  One of them
+(dispatch_jit) is transformed to become a JIT by code elsewhere:
+pypy/jit/*
 """
 import py
 import sys
 from pypy.tool.pairtype import extendabletype
 from pypy.rlib.rarithmetic import r_uint, intmask
-from pypy.rlib.jit import hint, _is_early_constant, JitDriver
+from pypy.rlib.jit import hint, _is_early_constant
 import pypy.interpreter.pyopcode   # for side-effects
-from pypy.interpreter.error import OperationError
-from pypy.interpreter.gateway import ObjSpace, Arguments
 from pypy.interpreter.eval import Frame
 from pypy.interpreter.pycode import PyCode, CO_VARARGS, CO_VARKEYWORDS
 from pypy.interpreter.pyframe import PyFrame
@@ -21,76 +23,110 @@
 PyCode.jit_enable = False     # new default attribute
 super_dispatch = PyFrame.dispatch
 
-class PyPyJitDriver(JitDriver):
-    reds = ['frame', 'ec']
-    greens = ['next_instr', 'pycode']
-
-    def compute_invariants(self, reds, next_instr, pycode):
-        # compute the information that really only depends on next_instr
-        # and pycode
-        frame = reds.frame
-        valuestackdepth = frame.valuestackdepth
-        blockstack = frame.blockstack
-        return (valuestackdepth, blockstack)
+class __extend__(PyFrame):
 
-    def on_enter_jit(self, invariants, reds, next_instr, pycode):
-        # *loads* of nonsense for now
-        (depth, oldblockstack) = invariants
-        frame = reds.frame
+    def dispatch(self, pycode, next_instr, ec):
+        if pycode.jit_enable:
+            return self.dispatch_jit(pycode, next_instr, ec)
+        else:
+            self = hint(self, access_directly=True)
+            return super_dispatch(self, pycode, next_instr, ec)
+            
+    def dispatch_jit(self, pycode, next_instr, ec):
+        hint(None, global_merge_point=True)
         pycode = hint(pycode, deepfreeze=True)
 
+        entry_fastlocals_w = self.jit_enter_frame(pycode, next_instr)
+
+        # For the sequel, force 'next_instr' to be unsigned for performance
+        next_instr = r_uint(next_instr)
+        co_code = pycode.co_code
+
+        try:
+            try:
+                while True:
+                    hint(None, global_merge_point=True)
+                    next_instr = self.handle_bytecode(co_code, next_instr, ec)
+            except Return:
+                w_result = self.popvalue()
+                self.blockstack = None
+                self.valuestack_w = None
+                return w_result
+            except Yield:
+                w_result = self.popvalue()
+                return w_result
+        finally:
+            self.jit_leave_frame(pycode, entry_fastlocals_w)
+
+    def jit_enter_frame(self, pycode, next_instr):
+        # *loads* of nonsense for now
+
         fastlocals_w = [None] * pycode.co_nlocals
 
-        i = pycode.co_nlocals
-        while True:
-            i -= 1
-            if i < 0:
-                break
-            hint(i, concrete=True)
-            w_obj = frame.fastlocals_w[i]
-            fastlocals_w[i] = w_obj
+        if next_instr == 0:
+            # first time we enter this function
+            depth = 0
+            self.blockstack = []
+
+            numargs = pycode.co_argcount
+            if pycode.co_flags & CO_VARARGS:     numargs += 1
+            if pycode.co_flags & CO_VARKEYWORDS: numargs += 1
+            while True:
+                numargs -= 1
+                if numargs < 0:
+                    break
+                hint(numargs, concrete=True)
+                w_obj = self.fastlocals_w[numargs]
+                assert w_obj is not None
+                fastlocals_w[numargs] = w_obj
 
-        frame.pycode = pycode
-        frame.valuestackdepth = depth
+        else:
+            stuff = self.valuestackdepth
+            if len(self.blockstack):
+                stuff |= (-sys.maxint-1)
+
+            stuff = hint(stuff, promote=True)
+            if stuff >= 0:
+                # blockdepth == 0, common case
+                self.blockstack = []
+            depth = stuff & sys.maxint
 
-        frame.fastlocals_w = fastlocals_w
+            i = pycode.co_nlocals
+            while True:
+                i -= 1
+                if i < 0:
+                    break
+                hint(i, concrete=True)
+                w_obj = self.fastlocals_w[i]
+                fastlocals_w[i] = w_obj
+
+        self.pycode = pycode
+        self.valuestackdepth = depth
+
+        entry_fastlocals_w = self.fastlocals_w
+        self.fastlocals_w = fastlocals_w
 
         virtualstack_w = [None] * pycode.co_stacksize
         while depth > 0:
             depth -= 1
             hint(depth, concrete=True)
-            virtualstack_w[depth] = frame.valuestack_w[depth]
-        frame.valuestack_w = virtualstack_w
+            virtualstack_w[depth] = self.valuestack_w[depth]
+        self.valuestack_w = virtualstack_w
+        return entry_fastlocals_w
 
-        # XXX we should also make a completely virtual copy of oldblockstack
+    def jit_leave_frame(self, pycode, entry_fastlocals_w):
+        i = pycode.co_nlocals
+        while True:
+            i -= 1
+            if i < 0:
+                break
+            hint(i, concrete=True)
+            entry_fastlocals_w[i] = self.fastlocals_w[i]
 
-pypyjitdriver = PyPyJitDriver()
+        self.fastlocals_w = entry_fastlocals_w
 
-class __extend__(PyFrame):
 
-    def dispatch(self, pycode, next_instr, ec):
-        next_instr = r_uint(next_instr)
-        try:
-            while True:
-                pypyjitdriver.jit_merge_point(
-                    frame=self, ec=ec, next_instr=next_instr, pycode=pycode)
-                pycode = hint(pycode, deepfreeze=True)
-                co_code = pycode.co_code
-                next_instr = self.handle_bytecode(co_code, next_instr, ec)
-        except Return:
-            w_result = self.popvalue()
-            self.blockstack = None
-            self.valuestack_w = None
-            return w_result
-        except Yield:
-            w_result = self.popvalue()
-            return w_result
-
-    def JUMP_ABSOLUTE(f, jumpto, next_instr, *ignored):
-        ec = f.space.getexecutioncontext()
-        pypyjitdriver.can_enter_jit(frame=f, ec=ec, next_instr=jumpto,
-                                    pycode=f.getcode())
-        return jumpto
+PORTAL = PyFrame.dispatch_jit
 
 class __extend__(Function):
     __metaclass__ = extendabletype
@@ -111,46 +147,15 @@
 #
 # Public interface
 
-def jit_startup(space, argv):
+def enable(space, w_code, w_enabled=True):
     # save the app-level sys.executable in JITInfo, where the machine
-    # code backend can fish for it.  A bit hackish.
+    # code backend can fish for it - XXX the following import will look
+    # less obscure once codebuf.py is moved to a general
+    # processor-independent place
     from pypy.jit.codegen.hlinfo import highleveljitinfo
-    highleveljitinfo.sys_executable = argv[0]
-
-    # recognize the option  --jit PARAM=VALUE,PARAM=VALUE...
-    # if it is at the beginning.  A bit ad-hoc.
-    if len(argv) > 2 and argv[1] == '--jit':
-        argv.pop(1)
-        try:
-            pypyjitdriver.set_user_param(argv.pop(1))
-        except ValueError:
-            from pypy.rlib.debug import debug_print
-            debug_print("WARNING: invalid --jit parameters string")
-
-
-def set_param(space, args):
-    '''Configure the tunable JIT parameters.
-        * set_param(name=value, ...)            # as keyword arguments
-        * set_param("name=value,name=value")    # as a user-supplied string
-    '''
-    args_w, kwds_w = args.unpack()
-    if len(args_w) > 1:
-        msg = ("set_param() takes at most 1 non-keyword argument, %d given"
-               % len(args_w))
-        raise OperationError(space.w_TypeError, space.wrap(msg))
-    if len(args_w) == 1:
-        text = space.str_w(args_w[0])
-        try:
-            pypyjitdriver.set_user_param(text)
-        except ValueError:
-            raise OperationError(space.w_ValueError,
-                                 space.wrap("error in JIT parameters string"))
-    for key, w_value in kwds_w.items():
-        intval = space.int_w(w_value)
-        try:
-            pypyjitdriver.set_param(key, intval)
-        except ValueError:
-            raise OperationError(space.w_TypeError,
-                                 space.wrap("no JIT parameter '%s'" % (key,)))
+    if highleveljitinfo.sys_executable is None:
+        highleveljitinfo.sys_executable = space.str_w(
+            space.sys.get('executable'))
 
-set_param.unwrap_spec = [ObjSpace, Arguments]
+    code = space.interp_w(PyCode, w_code)
+    code.jit_enable = space.is_true(w_enabled)

Modified: pypy/branch/oo-jit/pypy/module/pypyjit/newbool.py
==============================================================================
--- pypy/branch/oo-jit/pypy/module/pypyjit/newbool.py	(original)
+++ pypy/branch/oo-jit/pypy/module/pypyjit/newbool.py	Fri Feb 13 20:32:47 2009
@@ -62,7 +62,8 @@
         else:
             if reverse:
                 gv_bool = jitstate.curbuilder.genop1("bool_not", gv_bool)
-            return rvalue.IntRedBox(self.boolkind, gv_bool)
+            #return rvalue.IntRedBox(self.boolkind, gv_bool)
+            return rvalue.IntRedBox(gv_bool)
 
     def genbooleq(self, jitstate, gv_bool1, gv_bool2, reverse=False):
         if gv_bool1.is_const:
@@ -80,6 +81,7 @@
                 gv_res = curbuilder.genop2("int_ne", gv_int1, gv_int2)
             else:
                 gv_res = curbuilder.genop2("int_eq", gv_int1, gv_int2)
+            #return rvalue.IntRedBox(self.boolkind, gv_res)
             return rvalue.IntRedBox(self.boolkind, gv_res)
 
 

Modified: pypy/branch/oo-jit/pypy/module/pypyjit/portal.py
==============================================================================
--- pypy/branch/oo-jit/pypy/module/pypyjit/portal.py	(original)
+++ pypy/branch/oo-jit/pypy/module/pypyjit/portal.py	Fri Feb 13 20:32:47 2009
@@ -1,11 +1,12 @@
 import pypy
-#from pypy.module.pypyjit.newbool import NewBoolDesc
+from pypy.module.pypyjit.interp_jit import PORTAL
+from pypy.module.pypyjit.newbool import NewBoolDesc
 from pypy.translator.translator import graphof
 from pypy.annotation.specialize import getuniquenondirectgraph
 from pypy.jit.hintannotator.policy import ManualGraphPolicy
 
 class PyPyHintAnnotatorPolicy(ManualGraphPolicy):
-    hotpath = True
+    PORTAL = PORTAL
     
     def look_inside_graph_of_module(self, graph, func, mod):
         if mod.startswith('pypy.objspace'):
@@ -101,7 +102,7 @@
         self.seegraph(pypy.interpreter.pyframe.PyFrame.execute_frame, False)
         # --------------------
         # special timeshifting logic for newbool
-        #self.seegraph(pypy.objspace.std.Space.newbool, NewBoolDesc)
+        self.seegraph(pypy.objspace.std.Space.newbool, NewBoolDesc)
         self.seepath(pypy.interpreter.pyframe.PyFrame.JUMP_IF_TRUE,
                      pypy.objspace.std.Space.is_true)
         self.seepath(pypy.interpreter.pyframe.PyFrame.JUMP_IF_FALSE,
@@ -126,6 +127,9 @@
 
 def get_portal(drv):
     t = drv.translator
+    portal = getattr(PORTAL, 'im_func', PORTAL)
+    portal_graph = graphof(t, portal)
+
     policy = PyPyHintAnnotatorPolicy()
     policy.seetranslator(t)
-    return None, policy
+    return portal, policy

Modified: pypy/branch/oo-jit/pypy/translator/cli/opcodes.py
==============================================================================
--- pypy/branch/oo-jit/pypy/translator/cli/opcodes.py	(original)
+++ pypy/branch/oo-jit/pypy/translator/cli/opcodes.py	Fri Feb 13 20:32:47 2009
@@ -106,6 +106,7 @@
     'ullong_is_true':            [PushAllArgs, 'ldc.i8 0', 'cgt.un'],
     'ullong_invert':             'not',
 
+    # XXX: why nop nop nop?
     'ooisnull':                 [PushAllArgs, 'nop', 'nop', 'nop', 'ldnull', 'ceq'],
     'oononnull':                [PushAllArgs, 'nop', 'nop', 'nop', 'nop', 'ldnull', 'ceq']+Not,
 

Modified: pypy/branch/oo-jit/pypy/translator/goal/targetpypystandalone.py
==============================================================================
--- pypy/branch/oo-jit/pypy/translator/goal/targetpypystandalone.py	(original)
+++ pypy/branch/oo-jit/pypy/translator/goal/targetpypystandalone.py	Fri Feb 13 20:32:47 2009
@@ -47,12 +47,12 @@
             try:
                 space.call_function(w_run_toplevel, w_call_startup_gateway)
 
-                if space.config.objspace.usemodules.pypyjit:
-                    # initial setup of the JIT and handling of the
-                    # '--jit PARAM=VALUE,PARAM=VALUE...' command-line option
-                    # (for now it's a bit ad-hoc)
-                    from pypy.module.pypyjit.interp_jit import jit_startup
-                    jit_startup(space, argv)
+##                 if space.config.objspace.usemodules.pypyjit:
+##                     # initial setup of the JIT and handling of the
+##                     # '--jit PARAM=VALUE,PARAM=VALUE...' command-line option
+##                     # (for now it's a bit ad-hoc)
+##                     from pypy.module.pypyjit.interp_jit import jit_startup
+##                     jit_startup(space, argv)
 
                 w_executable = space.wrap(argv[0])
                 w_argv = space.newlist([space.wrap(s) for s in argv[1:]])



More information about the Pypy-commit mailing list