[pypy-commit] pypy py3.7: implement opcode tracing, make it possible to turn off line tracing

cfbolz pypy.commits at gmail.com
Fri Jan 31 16:48:09 EST 2020


Author: Carl Friedrich Bolz-Tereick <cfbolz at gmx.de>
Branch: py3.7
Changeset: r98617:e446a354c3d0
Date: 2020-01-31 22:04 +0100
http://bitbucket.org/pypy/pypy/changeset/e446a354c3d0/

Log:	implement opcode tracing, make it possible to turn off line tracing

diff --git a/pypy/interpreter/executioncontext.py b/pypy/interpreter/executioncontext.py
--- a/pypy/interpreter/executioncontext.py
+++ b/pypy/interpreter/executioncontext.py
@@ -183,7 +183,8 @@
         if d.instr_lb <= frame.last_instr < d.instr_ub:
             if frame.last_instr < d.instr_prev_plus_one:
                 # We jumped backwards in the same line.
-                self._trace(frame, 'line', self.space.w_None)
+                if d.f_trace_lines:
+                    self._trace(frame, 'line', self.space.w_None)
         else:
             size = len(code.co_lnotab) / 2
             addr = 0
@@ -219,7 +220,10 @@
 
             if d.instr_lb == frame.last_instr: # At start of line!
                 d.f_lineno = line
-                self._trace(frame, 'line', self.space.w_None)
+                if d.f_trace_lines:
+                    self._trace(frame, 'line', self.space.w_None)
+        if d.f_trace_opcodes:
+            self._trace(frame, 'opcode', self.space.w_None)
 
         d.instr_prev_plus_one = frame.last_instr + 1
 
diff --git a/pypy/interpreter/pyframe.py b/pypy/interpreter/pyframe.py
--- a/pypy/interpreter/pyframe.py
+++ b/pypy/interpreter/pyframe.py
@@ -36,6 +36,8 @@
     f_lineno                 = 0      # current lineno for tracing
     is_being_profiled        = False
     is_in_line_tracing       = False
+    f_trace_lines            = True
+    f_trace_opcodes          = False
     w_locals                 = None
     hidden_operationerr      = None
 
@@ -148,6 +150,18 @@
             return None
         return d.w_locals
 
+    def get_f_trace_lines(self):
+        d = self.getdebug()
+        if d is None:
+            return True
+        return d.f_trace_lines
+
+    def get_f_trace_opcodes(self):
+        d = self.getdebug()
+        if d is None:
+            return False
+        return d.f_trace_opcodes
+
     @not_rpython
     def __repr__(self):
         # useful in tracebacks
@@ -898,10 +912,17 @@
     def fdel_f_trace(self, space):
         self.getorcreatedebug().w_f_trace = None
 
-    def fget_f_restricted(self, space):
-        if space.config.objspace.honor__builtins__:
-            return space.newbool(self.builtin is not space.builtin)
-        return space.w_False
+    def fget_f_trace_lines(self, space):
+        return space.newbool(self.get_f_trace_lines())
+
+    def fset_f_trace_lines(self, space, w_trace):
+        self.getorcreatedebug().f_trace_lines = space.is_true(w_trace)
+
+    def fget_f_trace_opcodes(self, space):
+        return space.newbool(self.get_f_trace_opcodes())
+
+    def fset_f_trace_opcodes(self, space, w_trace):
+        self.getorcreatedebug().f_trace_opcodes = space.is_true(w_trace)
 
     def get_generator(self):
         if self.space.config.translation.rweakref:
diff --git a/pypy/interpreter/test/apptest_pyframe.py b/pypy/interpreter/test/apptest_pyframe.py
--- a/pypy/interpreter/test/apptest_pyframe.py
+++ b/pypy/interpreter/test/apptest_pyframe.py
@@ -584,6 +584,63 @@
     sys.settrace(None)
     assert res == 10
 
+def test_disable_line_tracing():
+    import sys
+    assert sys._getframe().f_trace_lines
+
+    l = []
+    def trace(frame, event, arg):
+        l.append((frame.f_code.co_name, event, arg, frame.f_lineno - frame.f_code.co_firstlineno))
+        frame.f_trace_lines = False
+        return trace
+    def g(n):
+        return n + 2
+    def f(n):
+        n = g(n)
+        return n * 7
+    sys.settrace(trace)
+    x = f(4)
+    sys.settrace(None)
+    print(l)
+    assert l == [('f', 'call', None, 0), ('g', 'call', None, 0), ('g', 'return', 6, 1), ('f', 'return', 42, 2)]
+
+test_disable_line_tracing()
+
+def test_opcode_tracing():
+    import sys
+    assert not sys._getframe().f_trace_opcodes
+
+    l = []
+    def trace(frame, event, arg):
+        l.append((frame.f_code.co_name, event, arg, frame.f_lasti, frame.f_lineno - frame.f_code.co_firstlineno))
+        frame.f_trace_opcodes = True
+        return trace
+    def g(n):
+        return n + 2
+    def f(n):
+        return g(n)
+    sys.settrace(trace)
+    x = f(4)
+    sys.settrace(None)
+    print(l)
+    assert l == [
+        ('f', 'call', None, -1, 0),
+        ('f', 'line', None, 0, 1),
+        ('f', 'opcode', None, 0, 1),
+        ('f', 'opcode', None, 2, 1),
+        ('f', 'opcode', None, 4, 1),
+        ('g', 'call', None, -1, 0),
+        ('g', 'line', None, 0, 1),
+        ('g', 'opcode', None, 0, 1),
+        ('g', 'opcode', None, 2, 1),
+        ('g', 'opcode', None, 4, 1),
+        ('g', 'opcode', None, 6, 1),
+        ('g', 'return', 6, 6, 1),
+        ('f', 'opcode', None, 6, 1),
+        ('f', 'return', 6, 6, 1)]
+
+test_opcode_tracing()
+
 def test_preserve_exc_state_in_generators():
     import sys
     def yield_raise():
diff --git a/pypy/interpreter/typedef.py b/pypy/interpreter/typedef.py
--- a/pypy/interpreter/typedef.py
+++ b/pypy/interpreter/typedef.py
@@ -654,7 +654,8 @@
     f_lasti = GetSetProperty(PyFrame.fget_f_lasti),
     f_trace = GetSetProperty(PyFrame.fget_f_trace, PyFrame.fset_f_trace,
                              PyFrame.fdel_f_trace),
-    f_restricted = GetSetProperty(PyFrame.fget_f_restricted),
+    f_trace_lines = GetSetProperty(PyFrame.fget_f_trace_lines, PyFrame.fset_f_trace_lines),
+    f_trace_opcodes = GetSetProperty(PyFrame.fget_f_trace_opcodes, PyFrame.fset_f_trace_opcodes),
     f_code = GetSetProperty(PyFrame.fget_code),
     f_locals = GetSetProperty(PyFrame.fget_getdictscope),
     f_globals = GetSetProperty(PyFrame.fget_w_globals),


More information about the pypy-commit mailing list