[pypy-svn] r56453 - in pypy/branch/builtin-profiling/pypy/interpreter: . test

antocuni at codespeak.net antocuni at codespeak.net
Fri Jul 11 16:26:19 CEST 2008


Author: antocuni
Date: Fri Jul 11 16:26:19 2008
New Revision: 56453

Modified:
   pypy/branch/builtin-profiling/pypy/interpreter/baseobjspace.py
   pypy/branch/builtin-profiling/pypy/interpreter/executioncontext.py
   pypy/branch/builtin-profiling/pypy/interpreter/function.py
   pypy/branch/builtin-profiling/pypy/interpreter/pyframe.py
   pypy/branch/builtin-profiling/pypy/interpreter/pyopcode.py
   pypy/branch/builtin-profiling/pypy/interpreter/test/test_executioncontext.py
Log:
(antocuni, arigo, stephan)
(in-progress)

trace calls/returns/exceptions of builtin functions. It still doesn't cover all the possible cases



Modified: pypy/branch/builtin-profiling/pypy/interpreter/baseobjspace.py
==============================================================================
--- pypy/branch/builtin-profiling/pypy/interpreter/baseobjspace.py	(original)
+++ pypy/branch/builtin-profiling/pypy/interpreter/baseobjspace.py	Fri Jul 11 16:26:19 2008
@@ -694,9 +694,42 @@
         return self.call_args(w_func, args)
 
     def call_valuestack(self, w_func, nargs, frame):
+        from pypy.interpreter.function import Function, Method
+        from pypy.interpreter.gateway import BuiltinCode
+        if frame.is_being_profiled:
+            ec = self.getexecutioncontext()
+            is_c_call = False
+            if isinstance(w_func, Method):
+                code = w_func.w_function.getcode()
+            elif isinstance(w_func, Function):
+                code = w_func.getcode()
+            if isinstance(code, BuiltinCode):
+                is_c_call = True
+
+            # XXX: this code is copied&pasted :-( from the slow path
+            # below. The profiling info could be not very accurate
+            # because by doing this we disable fast paths when calling
+            # the function
+            args = frame.make_arguments(nargs)
+            try:
+                try:
+                    if is_c_call:
+                        ec.c_call_trace(frame, w_func)
+                    w_res = self.call_args(w_func, args)
+                    if is_c_call:
+                        ec.c_return_trace(frame, w_res)
+                    return w_res
+                except OperationError, e:
+                    if is_c_call:
+                        ec.c_exception_trace(frame, e)
+                    raise
+            finally:
+                if isinstance(args, ArgumentsFromValuestack):
+                    args.frame = None
+
+        
         if not self.config.objspace.disable_call_speedhacks:
             # XXX start of hack for performance
-            from pypy.interpreter.function import Function, Method
             hint(w_func.__class__, promote=True)
             if isinstance(w_func, Method):
                 w_inst = w_func.w_instance

Modified: pypy/branch/builtin-profiling/pypy/interpreter/executioncontext.py
==============================================================================
--- pypy/branch/builtin-profiling/pypy/interpreter/executioncontext.py	(original)
+++ pypy/branch/builtin-profiling/pypy/interpreter/executioncontext.py	Fri Jul 11 16:26:19 2008
@@ -136,6 +136,8 @@
         "Trace the call of a function"
         if self.w_tracefunc is not None or self.profilefunc is not None:
             self._trace(frame, 'call', self.space.w_None)
+            if self.profilefunc:
+                frame.is_being_profiled = True
 
     def return_trace(self, frame, w_retval):
         "Trace the return from a function"
@@ -240,7 +242,7 @@
 
         # Profile cases
         if self.profilefunc is not None:
-            if event not in ['leaveframe', 'call', 'c_call', 'c_return']:
+            if event not in ['leaveframe', 'call', 'c_call', 'c_return', 'c_exception']:
                 return
 
             last_exception = None

Modified: pypy/branch/builtin-profiling/pypy/interpreter/function.py
==============================================================================
--- pypy/branch/builtin-profiling/pypy/interpreter/function.py	(original)
+++ pypy/branch/builtin-profiling/pypy/interpreter/function.py	Fri Jul 11 16:26:19 2008
@@ -30,7 +30,7 @@
     def __repr__(self):
         # return "function %s.%s" % (self.space, self.name)
         # maybe we want this shorter:
-        return "<Function %s>" % self.name
+        return "<%s %s>" % (self.__class__.__name__, self.name)
 
     def call_args(self, args):
         return self.code.funcrun(self, args) # delegate activation to code

Modified: pypy/branch/builtin-profiling/pypy/interpreter/pyframe.py
==============================================================================
--- pypy/branch/builtin-profiling/pypy/interpreter/pyframe.py	(original)
+++ pypy/branch/builtin-profiling/pypy/interpreter/pyframe.py	Fri Jul 11 16:26:19 2008
@@ -44,6 +44,7 @@
     instr_lb                 = 0
     instr_ub                 = -1
     instr_prev               = -1
+    is_being_profiled        = False
 
     def __init__(self, space, code, w_globals, closure):
         self = hint(self, access_directly=True)

Modified: pypy/branch/builtin-profiling/pypy/interpreter/pyopcode.py
==============================================================================
--- pypy/branch/builtin-profiling/pypy/interpreter/pyopcode.py	(original)
+++ pypy/branch/builtin-profiling/pypy/interpreter/pyopcode.py	Fri Jul 11 16:26:19 2008
@@ -872,6 +872,8 @@
     def CALL_FUNCTION(f, oparg, *ignored):
         from pypy.rlib import rstack # for resume points
 
+        import pdb;pdb.set_trace()
+
         # XXX start of hack for performance
         if (oparg >> 8) & 0xff == 0:
             # Only positional arguments

Modified: pypy/branch/builtin-profiling/pypy/interpreter/test/test_executioncontext.py
==============================================================================
--- pypy/branch/builtin-profiling/pypy/interpreter/test/test_executioncontext.py	(original)
+++ pypy/branch/builtin-profiling/pypy/interpreter/test/test_executioncontext.py	Fri Jul 11 16:26:19 2008
@@ -66,19 +66,60 @@
         
         def profile_func(space, w_arg, frame, event, w_aarg):
             assert w_arg is space.w_None
-            l.append((event, frame, w_aarg))
+            l.append(event)
         
         space = self.space
         space.getexecutioncontext().setllprofile(profile_func, space.w_None)
         space.appexec([], """():
-        l = []
-        l.append(3)
-
-        return l
+        pass
         """)
         space.getexecutioncontext().setllprofile(None, None)
-        from pprint import pprint
-        pprint(l)
-        #pprint([(x, y, z) for x,y,z in l if x in ('call','c_call')])
-        assert l == ['call', 'return', 'call', 'c_call', 'c_return', 'return']
+        assert l == ['call', 'return', 'call', 'return']
+
+    def test_llprofile_c_call(self):
+        l = []
+        
+        def profile_func(space, w_arg, frame, event, w_aarg):
+            assert w_arg is space.w_None
+            l.append(event)
+
+        space = self.space
+        space.getexecutioncontext().setllprofile(profile_func, space.w_None)
+
+        def check_snippet(snippet):
+            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, **{})')
+        
+    def test_llprofile_c_exception(self):
+        l = []
+        
+        def profile_func(space, w_arg, frame, event, w_aarg):
+            assert w_arg is space.w_None
+            l.append(event)
+
+        space = self.space
+        space.getexecutioncontext().setllprofile(profile_func, space.w_None)
+
+        def check_snippet(snippet):
+            space.appexec([], """():
+            try:
+                %s
+            except:
+                pass
+            return
+            """ % snippet)
+            space.getexecutioncontext().setllprofile(None, None)
+            assert l == ['call', 'return', 'call', 'c_call', 'c_exception', 'return']
+
+        check_snippet('d = {}; d.__getitem__(42)')
 



More information about the Pypy-commit mailing list