[pypy-svn] r62774 - pypy/trunk/pypy/jit/metainterp

arigo at codespeak.net arigo at codespeak.net
Mon Mar 9 19:05:26 CET 2009


Author: arigo
Date: Mon Mar  9 19:05:26 2009
New Revision: 62774

Modified:
   pypy/trunk/pypy/jit/metainterp/codewriter.py
   pypy/trunk/pypy/jit/metainterp/pyjitpl.py
Log:
Redo this optimization.  Fijal, feel free to revert again
if I didn't fix the problem.


Modified: pypy/trunk/pypy/jit/metainterp/codewriter.py
==============================================================================
--- pypy/trunk/pypy/jit/metainterp/codewriter.py	(original)
+++ pypy/trunk/pypy/jit/metainterp/codewriter.py	Mon Mar  9 19:05:26 2009
@@ -17,8 +17,10 @@
 
 
 class JitCode(history.AbstractValue):
-    def __init__(self, name):
+    def __init__(self, name, cfnptr=None, calldescr=0):
         self.name = name
+        self.cfnptr = cfnptr
+        self.calldescr = calldescr
 
     def setup(self, code, constants):
         self.code = code
@@ -68,6 +70,7 @@
 
 
 class CodeWriter(object):
+    portal_graph = None
 
     def __init__(self, metainterp, policy):
         self.all_prebuilt_values = {}
@@ -82,6 +85,7 @@
 
     def make_portal_bytecode(self, graph):
         log.info("making JitCodes...")
+        self.portal_graph = graph
         jitcode = self.make_one_bytecode(graph, True)
         while self.unfinished_graphs:
             graph = self.unfinished_graphs.pop()
@@ -100,11 +104,22 @@
     def get_jitcode(self, graph):
         if graph in self.all_graphs:
             return self.all_graphs[graph]
-        bytecode = JitCode(graph.name)     # 'graph.name' is for dump()
+        extra = self.get_jitcode_calldescr(graph)
+        bytecode = JitCode(graph.name, *extra)     # 'graph.name' is for dump()
         self.all_graphs[graph] = bytecode
         self.unfinished_graphs.append(graph)
         return bytecode
 
+    def get_jitcode_calldescr(self, graph):
+        if self.portal_graph is None or graph is self.portal_graph:
+            return ()
+        fnptr = self.rtyper.getcallable(graph)
+        cfnptr = history.ConstAddr(llmemory.cast_ptr_to_adr(fnptr), self.cpu)
+        FUNC = lltype.typeOf(fnptr).TO
+        NON_VOID_ARGS = [ARG for ARG in FUNC.ARGS if ARG is not lltype.Void]
+        calldescr = self.cpu.calldescrof(NON_VOID_ARGS, FUNC.RESULT)
+        return (cfnptr, calldescr)
+
     def get_indirectcallset(self, graphs):
         key = tuple(sorted(graphs))
         try:

Modified: pypy/trunk/pypy/jit/metainterp/pyjitpl.py
==============================================================================
--- pypy/trunk/pypy/jit/metainterp/pyjitpl.py	(original)
+++ pypy/trunk/pypy/jit/metainterp/pyjitpl.py	Mon Mar  9 19:05:26 2009
@@ -396,9 +396,18 @@
 
     @arguments("bytecode", "varargs")
     def opimpl_call(self, callee, varargs):
-        f = self.metainterp.newframe(callee)
-        f.setup_call(varargs)
-        return True
+        if (isinstance(self.metainterp.history, history.BlackHole) and
+            callee.cfnptr is not None):
+            # when producing only a BlackHole, we can implement this by
+            # calling the subfunction directly instead of interpreting it
+            varargs = [callee.cfnptr] + varargs
+            return self.execute_with_exc(rop.CALL, varargs,
+                                         descr=callee.calldescr)
+        else:
+            # when tracing, this bytecode causes the subfunction to be entered
+            f = self.metainterp.newframe(callee)
+            f.setup_call(varargs)
+            return True
 
     @arguments("int", "varargs")
     def opimpl_residual_call(self, calldescr, varargs):



More information about the Pypy-commit mailing list