[pypy-svn] r23074 - in pypy/dist/pypy: interpreter translator/microbench

ac at codespeak.net ac at codespeak.net
Mon Feb 6 16:40:00 CET 2006


Author: ac
Date: Mon Feb  6 16:39:57 2006
New Revision: 23074

Modified:
   pypy/dist/pypy/interpreter/nestedscope.py
   pypy/dist/pypy/interpreter/pycode.py
   pypy/dist/pypy/interpreter/pyframe.py
   pypy/dist/pypy/translator/microbench/test_count1.py
Log:
Enhance performance for calling functions with nested functions.

Modified: pypy/dist/pypy/interpreter/nestedscope.py
==============================================================================
--- pypy/dist/pypy/interpreter/nestedscope.py	(original)
+++ pypy/dist/pypy/interpreter/nestedscope.py	Mon Feb  6 16:39:57 2006
@@ -99,25 +99,11 @@
             else:
                 cell.set(w_value)
 
-    def init_cells(self, num_vars):
-        if self.pycode.co_cellvars:
-            # the first few cell vars could shadow already-set arguments,
-            # in the same order as they appear in co_varnames
-            code     = self.pycode
-            argvars  = code.co_varnames
-            cellvars = code.co_cellvars
-            next     = 0
-            nextname = cellvars[0]
-            for i in range(num_vars):
-                if argvars[i] == nextname:
-                    # argument i has the same name as the next cell var
-                    w_value = self.fastlocals_w[i]
-                    self.cells[next] = Cell(w_value)
-                    next += 1
-                    try:
-                        nextname = cellvars[next]
-                    except IndexError:
-                        break   # all cell vars initialized this way
+    def init_cells(self):
+        args_to_copy = self.pycode._args_as_cellvars
+        for i in range(len(args_to_copy)):
+            argnum = args_to_copy[i]
+            self.cells[i] = Cell(self.fastlocals_w[argnum])
 
     def getfreevarname(self, index):
         freevarnames = self.pycode.co_cellvars + self.pycode.co_freevars

Modified: pypy/dist/pypy/interpreter/pycode.py
==============================================================================
--- pypy/dist/pypy/interpreter/pycode.py	(original)
+++ pypy/dist/pypy/interpreter/pycode.py	Mon Feb  6 16:39:57 2006
@@ -107,6 +107,31 @@
         self.magic = magic
         self._compute_fastcall()
         self._signature = cpython_code_signature(self)
+        # Precompute what arguments need to be copied into cellvars
+        self._args_as_cellvars = []
+        
+        if self.co_cellvars:
+            argcount = self.co_argcount
+            assert argcount >= 0     # annotator hint
+            if self.co_flags & CO_VARARGS:
+                argcount += 1
+            if self.co_flags & CO_VARKEYWORDS:
+                argcount += 1
+            # the first few cell vars could shadow already-set arguments,
+            # in the same order as they appear in co_varnames
+            argvars  = self.co_varnames
+            cellvars = self.co_cellvars
+            next     = 0
+            nextname = cellvars[0]
+            for i in range(argcount):
+                if argvars[i] == nextname:
+                    # argument i has the same name as the next cell var
+                    self._args_as_cellvars.append(i)
+                    next += 1
+                    try:
+                        nextname = cellvars[next]
+                    except IndexError:
+                        break   # all cell vars initialized this way
 
     def signature(self):
         return self._signature
@@ -223,7 +248,7 @@
         # speed hack
         args_matched = args.parse_into_scope(frame.fastlocals_w, func.name,
                                              sig, func.defs_w)
-        frame.init_cells(args_matched)
+        frame.init_cells()
         return frame.run()
 
     def create_frame(self, space, w_globals, closure=None):
@@ -239,8 +264,6 @@
         Frame = frame_classes[choose]
         return Frame(space, self, w_globals, closure)
 
-    signature = cpython_code_signature
-    
     def getvarnames(self):
         return self.co_varnames
 

Modified: pypy/dist/pypy/interpreter/pyframe.py
==============================================================================
--- pypy/dist/pypy/interpreter/pyframe.py	(original)
+++ pypy/dist/pypy/interpreter/pyframe.py	Mon Feb  6 16:39:57 2006
@@ -77,12 +77,13 @@
     def setfastscope(self, scope_w):
         """Initialize the fast locals from a list of values,
         where the order is according to self.pycode.signature()."""
-        if len(scope_w) > len(self.fastlocals_w):
+        scope_len = len(scope_w)
+        if scope_len > len(self.fastlocals_w):
             raise ValueError, "new fastscope is longer than the allocated area"
-        self.fastlocals_w[:len(scope_w)] = scope_w
-        self.init_cells(len(scope_w))
+        self.fastlocals_w[:scope_len] = scope_w
+        self.init_cells()
 
-    def init_cells(self, numvars):
+    def init_cells(self):
         """Initialize cellvars from self.fastlocals_w
         This is overridden in PyNestedScopeFrame"""
         pass

Modified: pypy/dist/pypy/translator/microbench/test_count1.py
==============================================================================
--- pypy/dist/pypy/translator/microbench/test_count1.py	(original)
+++ pypy/dist/pypy/translator/microbench/test_count1.py	Mon Feb  6 16:39:57 2006
@@ -142,4 +142,30 @@
     while x < n:
         x = c.my_method(x) 
 
+
+def func_with_arg_in_cellvars(x, y, z):
+    return 
+    def nested():
+        return x, y, z
+
+def func_without_arg_in_cellvars(x, y, z):
+    return 
+    i = None
+    def nested():
+        return i
+    
+def test_call_function_with_arguments_in_cellvars():
+    n = N
+    c = 0
+    while c < n:
+        func_with_arg_in_cellvars(c, n, test_call_function_with_arguments_in_cellvars)
+        c = c + 1
+
+def test_call_function_without_arguments_in_cellvars():
+    n = N
+    c = 0
+    while c < n:
+        func_without_arg_in_cellvars(c, n, test_call_function_without_arguments_in_cellvars)
+        c = c + 1
+
 #



More information about the Pypy-commit mailing list