[pypy-svn] r79874 - in pypy/trunk/pypy: interpreter interpreter/test module/_lsprof module/_lsprof/test

arigo at codespeak.net arigo at codespeak.net
Tue Dec 7 18:28:59 CET 2010


Author: arigo
Date: Tue Dec  7 18:28:57 2010
New Revision: 79874

Modified:
   pypy/trunk/pypy/interpreter/baseobjspace.py
   pypy/trunk/pypy/interpreter/executioncontext.py
   pypy/trunk/pypy/interpreter/test/test_executioncontext.py
   pypy/trunk/pypy/module/_lsprof/interp_lsprof.py
   pypy/trunk/pypy/module/_lsprof/test/test_cprofile.py
Log:
Fix for issue423, with extra tests.


Modified: pypy/trunk/pypy/interpreter/baseobjspace.py
==============================================================================
--- pypy/trunk/pypy/interpreter/baseobjspace.py	(original)
+++ pypy/trunk/pypy/interpreter/baseobjspace.py	Tue Dec  7 18:28:57 2010
@@ -862,14 +862,14 @@
 
     def call_args_and_c_profile(self, frame, w_func, args):
         ec = self.getexecutioncontext()
-        ec.c_call_trace(frame, w_func)
+        ec.c_call_trace(frame, w_func, args)
         try:
             w_res = self.call_args(w_func, args)
         except OperationError, e:
             w_value = e.get_w_value(self)
             ec.c_exception_trace(frame, w_value)
             raise
-        ec.c_return_trace(frame, w_func)
+        ec.c_return_trace(frame, w_func, args)
         return w_res
 
     def call_method(self, w_obj, methname, *arg_w):

Modified: pypy/trunk/pypy/interpreter/executioncontext.py
==============================================================================
--- pypy/trunk/pypy/interpreter/executioncontext.py	(original)
+++ pypy/trunk/pypy/interpreter/executioncontext.py	Tue Dec  7 18:28:57 2010
@@ -123,19 +123,30 @@
             return lst
         # coroutine: I think this is all, folks!
 
-    def c_call_trace(self, frame, w_func):
+    def c_call_trace(self, frame, w_func, args=None):
         "Profile the call of a builtin function"
-        if self.profilefunc is None:
-            frame.is_being_profiled = False
-        else:
-            self._trace(frame, 'c_call', w_func)
+        self._c_call_return_trace(frame, w_func, args, 'c_call')
 
-    def c_return_trace(self, frame, w_retval):
+    def c_return_trace(self, frame, w_func, args=None):
         "Profile the return from a builtin function"
+        self._c_call_return_trace(frame, w_func, args, 'c_return')
+
+    def _c_call_return_trace(self, frame, w_func, args, event):
         if self.profilefunc is None:
             frame.is_being_profiled = False
         else:
-            self._trace(frame, 'c_return', w_retval)
+            # undo the effect of the CALL_METHOD bytecode, which would be
+            # that even on a built-in method call like '[].append()',
+            # w_func is actually the unbound function 'append'.
+            from pypy.interpreter.function import FunctionWithFixedCode
+            if isinstance(w_func, FunctionWithFixedCode) and args is not None:
+                w_firstarg = args.firstarg()
+                if w_firstarg is not None:
+                    from pypy.interpreter.function import descr_function_get
+                    w_func = descr_function_get(self.space, w_func, w_firstarg,
+                                                self.space.type(w_firstarg))
+            #
+            self._trace(frame, event, w_func)
 
     def c_exception_trace(self, frame, w_exc):
         "Profile function called upon OperationError."

Modified: pypy/trunk/pypy/interpreter/test/test_executioncontext.py
==============================================================================
--- pypy/trunk/pypy/interpreter/test/test_executioncontext.py	(original)
+++ pypy/trunk/pypy/interpreter/test/test_executioncontext.py	Tue Dec  7 18:28:57 2010
@@ -7,6 +7,10 @@
 
 
 class TestExecutionContext:
+    keywords = {}
+
+    def setup_class(cls):
+        cls.space = gettestobjspace(**cls.keywords)
 
     def test_action(self):
 
@@ -77,29 +81,43 @@
         assert l == ['call', 'return', 'call', 'return']
 
     def test_llprofile_c_call(self):
+        from pypy.interpreter.function import Function, Method
         l = []
+        seen = []
+        space = self.space
         
-        def profile_func(space, w_arg, frame, event, w_aarg):
+        def profile_func(space, w_arg, frame, event, w_func):
             assert w_arg is space.w_None
             l.append(event)
+            if event == 'c_call':
+                seen.append(w_func)
 
-        space = self.space
-        space.getexecutioncontext().setllprofile(profile_func, space.w_None)
-
-        def check_snippet(snippet):
+        def check_snippet(snippet, expected_c_call):
+            del l[:]
+            del seen[:]
+            space.getexecutioncontext().setllprofile(profile_func,
+                                                     space.w_None)
             space.appexec([], """():
             %s
             return
             """ % snippet)
             space.getexecutioncontext().setllprofile(None, None)
             assert l == ['call', 'return', 'call', 'c_call', 'c_return', 'return']
-
-        check_snippet('l = []; l.append(42)')
-        check_snippet('max(1, 2)')
-        check_snippet('args = (1, 2); max(*args)')
-        check_snippet('max(1, 2, **{})')
-        check_snippet('args = (1, 2); max(*args, **{})')
-        check_snippet('abs(val=0)')
+            if isinstance(seen[0], Method):
+                found = 'method %s of %s' % (
+                    seen[0].w_function.name,
+                    seen[0].w_class.getname(space, '?'))
+            else:
+                assert isinstance(seen[0], Function)
+                found = 'builtin %s' % seen[0].name
+            assert found == expected_c_call
+
+        check_snippet('l = []; l.append(42)', 'method append of list')
+        check_snippet('max(1, 2)', 'builtin max')
+        check_snippet('args = (1, 2); max(*args)', 'builtin max')
+        check_snippet('max(1, 2, **{})', 'builtin max')
+        check_snippet('args = (1, 2); max(*args, **{})', 'builtin max')
+        check_snippet('abs(val=0)', 'builtin abs')
         
     def test_llprofile_c_exception(self):
         l = []
@@ -243,6 +261,13 @@
         """)
 
 
+class TestExecutionContextWithCallLikelyBuiltin(TestExecutionContext):
+    keywords = {'objspace.opcodes.CALL_LIKELY_BUILTIN': True}
+
+class TestExecutionContextWithCallMethod(TestExecutionContext):
+    keywords = {'objspace.opcodes.CALL_METHOD': True}
+
+
 class AppTestDelNotBlocked:
 
     def setup_method(self, meth):

Modified: pypy/trunk/pypy/module/_lsprof/interp_lsprof.py
==============================================================================
--- pypy/trunk/pypy/module/_lsprof/interp_lsprof.py	(original)
+++ pypy/trunk/pypy/module/_lsprof/interp_lsprof.py	Tue Dec  7 18:28:57 2010
@@ -163,8 +163,11 @@
     if isinstance(w_arg, Method):
         w_function = w_arg.w_function
         class_name = w_arg.w_class.getname(space, '?')
-        assert isinstance(w_function, Function)
-        return "{method '%s' of '%s' objects}" % (w_function.name, class_name)
+        if isinstance(w_function, Function):
+            name = w_function.name
+        else:
+            name = '?'
+        return "{method '%s' of '%s' objects}" % (name, class_name)
     elif isinstance(w_arg, Function):
         if w_arg.w_module is None:
             module = ''
@@ -176,7 +179,8 @@
                 module += '.'
         return '{%s%s}' % (module, w_arg.name)
     else:
-        return '{!!!unknown!!!}'
+        class_name = w_arg.w_class.getname(space, '?')
+        return "{'%s' object}" % (class_name,)
     
 def lsprof_call(space, w_self, frame, event, w_arg):
     assert isinstance(w_self, W_Profiler)

Modified: pypy/trunk/pypy/module/_lsprof/test/test_cprofile.py
==============================================================================
--- pypy/trunk/pypy/module/_lsprof/test/test_cprofile.py	(original)
+++ pypy/trunk/pypy/module/_lsprof/test/test_cprofile.py	Tue Dec  7 18:28:57 2010
@@ -150,7 +150,7 @@
             sys.path.pop(0)
 
 
-class AppTestDifferentBytecode(AppTestCProfile):
+class AppTestWithDifferentBytecodes(AppTestCProfile):
     keywords = {'objspace.opcodes.CALL_LIKELY_BUILTIN': True,
                 'objspace.opcodes.CALL_METHOD': True}
 



More information about the Pypy-commit mailing list