[pypy-commit] pypy remove-frame-debug-attrs: Initial commit - a branch to try and remove the debug attributes on frames
fijal
noreply at buildbot.pypy.org
Mon May 4 09:27:08 CEST 2015
Author: Maciej Fijalkowski <fijall at gmail.com>
Branch: remove-frame-debug-attrs
Changeset: r77024:f371dc154666
Date: 2015-05-04 09:26 +0200
http://bitbucket.org/pypy/pypy/changeset/f371dc154666/
Log: Initial commit - a branch to try and remove the debug attributes on
frames that are only used for tracing and replace it with a debug
object thats created on-demand
diff --git a/pypy/interpreter/baseobjspace.py b/pypy/interpreter/baseobjspace.py
--- a/pypy/interpreter/baseobjspace.py
+++ b/pypy/interpreter/baseobjspace.py
@@ -1091,7 +1091,7 @@
def call_valuestack(self, w_func, nargs, frame):
from pypy.interpreter.function import Function, Method, is_builtin_code
- if frame.is_being_profiled and is_builtin_code(w_func):
+ if frame.get_is_being_profiled() and is_builtin_code(w_func):
# XXX: this code is copied&pasted :-( from the slow path below
# call_valuestack().
args = frame.make_arguments(nargs)
diff --git a/pypy/interpreter/executioncontext.py b/pypy/interpreter/executioncontext.py
--- a/pypy/interpreter/executioncontext.py
+++ b/pypy/interpreter/executioncontext.py
@@ -145,7 +145,7 @@
Like bytecode_trace() but doesn't invoke any other events besides the
trace function.
"""
- if (frame.w_f_trace is None or self.is_tracing or
+ if (frame.get_w_f_trace() is None or self.is_tracing or
self.gettrace() is None):
return
self.run_trace_func(frame)
@@ -154,8 +154,9 @@
@jit.unroll_safe
def run_trace_func(self, frame):
code = frame.pycode
- if frame.instr_lb <= frame.last_instr < frame.instr_ub:
- if frame.last_instr < frame.instr_prev_plus_one:
+ d = frame.getorcreatedebug()
+ 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)
else:
@@ -170,7 +171,7 @@
break
addr += c
if c:
- frame.instr_lb = addr
+ d.instr_lb = addr
line += ord(lineno[p + 1])
p += 2
@@ -185,15 +186,15 @@
if ord(lineno[p + 1]):
break
p += 2
- frame.instr_ub = addr
+ d.instr_ub = addr
else:
- frame.instr_ub = sys.maxint
+ d.instr_ub = sys.maxint
- if frame.instr_lb == frame.last_instr: # At start of line!
- frame.f_lineno = line
+ if d.instr_lb == frame.last_instr: # At start of line!
+ d.f_lineno = line
self._trace(frame, 'line', self.space.w_None)
- frame.instr_prev_plus_one = frame.last_instr + 1
+ d.instr_prev_plus_one = frame.last_instr + 1
def bytecode_trace_after_exception(self, frame):
"Like bytecode_trace(), but without increasing the ticker."
@@ -309,7 +310,7 @@
if event == 'call':
w_callback = self.gettrace()
else:
- w_callback = frame.w_f_trace
+ w_callback = frame.get_w_f_trace()
if w_callback is not None and event != "leaveframe":
if operr is not None:
@@ -320,15 +321,16 @@
frame.fast2locals()
self.is_tracing += 1
try:
+ d = frame.getorcreatedebug()
try:
w_result = space.call_function(w_callback, space.wrap(frame), space.wrap(event), w_arg)
if space.is_w(w_result, space.w_None):
- frame.w_f_trace = None
+ d.w_f_trace = None
else:
- frame.w_f_trace = w_result
+ d.w_f_trace = w_result
except:
self.settrace(space.w_None)
- frame.w_f_trace = None
+ d.w_f_trace = None
raise
finally:
self.is_tracing -= 1
diff --git a/pypy/interpreter/pyframe.py b/pypy/interpreter/pyframe.py
--- a/pypy/interpreter/pyframe.py
+++ b/pypy/interpreter/pyframe.py
@@ -23,6 +23,15 @@
globals()[op] = stdlib_opcode.opmap[op]
HAVE_ARGUMENT = stdlib_opcode.HAVE_ARGUMENT
+class FrameDebugData(object):
+ """ A small object that holds debug data for tracing
+ """
+ w_f_trace = None
+ instr_lb = 0
+ instr_ub = 0
+ instr_prev_plus_one = 0
+ f_lineno = -1 # current lineno
+ is_being_profiled = False
class PyFrame(W_Root):
"""Represents a frame for a regular Python function
@@ -49,15 +58,9 @@
last_instr = -1
last_exception = None
f_backref = jit.vref_None
- # For tracing
- w_f_trace = None
- instr_lb = 0
- instr_ub = 0
- instr_prev_plus_one = 0
- # end of tracing
- is_being_profiled = False
escaped = False # see mark_as_escaped()
+ debugdata = None
w_globals = None
w_locals = None # dict containing locals, if forced or necessary
@@ -65,13 +68,12 @@
locals_stack_w = None # the list of all locals and valuestack
valuestackdepth = -1 # number of items on valuestack
lastblock = None
- # default to False
- f_lineno = -1 # current lineno
cells = None # cells
# other fields:
- # builtin - builtin cache, only if honor__builtins__ is True,
+ # builtin - builtin cache, only if honor__builtins__ is True
+ # defaults to False
# there is also self.space which is removed by the annotator
@@ -97,7 +99,26 @@
# regular functions always have CO_OPTIMIZED and CO_NEWLOCALS.
# class bodies only have CO_NEWLOCALS.
self.initialize_frame_scopes(outer_func, code)
- self.f_lineno = code.co_firstlineno
+
+ def getdebug(self):
+ return self.debugdata
+
+ def getorcreatedebug(self):
+ if self.debugdata is None:
+ self.debugdata = FrameDebugData()
+ return self.debugdata
+
+ def get_w_f_trace(self):
+ d = self.getdebug()
+ if d is None:
+ return None
+ return d.w_f_trace
+
+ def get_is_being_profiled(self):
+ d = self.getdebug()
+ if d is None:
+ return None
+ return d.is_being_profiled
def __repr__(self):
# NOT_RPYTHON: useful in tracebacks
@@ -386,7 +407,7 @@
else:
w_cells = space.newlist([space.wrap(cell) for cell in cells])
- if self.w_f_trace is None:
+ if self.get_w_f_trace() is None:
f_lineno = self.get_last_lineno()
else:
f_lineno = self.f_lineno
@@ -483,9 +504,11 @@
)
new_frame.last_instr = space.int_w(w_last_instr)
new_frame.frame_finished_execution = space.is_true(w_finished)
+ xxx
new_frame.f_lineno = space.int_w(w_f_lineno)
fastlocals_w = maker.slp_from_tuple_with_nulls(space, w_fastlocals)
new_frame.locals_stack_w[:len(fastlocals_w)] = fastlocals_w
+ xxx
if space.is_w(w_f_trace, space.w_None):
new_frame.w_f_trace = None
@@ -632,10 +655,10 @@
def fget_f_lineno(self, space):
"Returns the line number of the instruction currently being executed."
- if self.w_f_trace is None:
+ if self.get_w_f_trace() is None:
return space.wrap(self.get_last_lineno())
else:
- return space.wrap(self.f_lineno)
+ return space.wrap(self.getorcreatedebug().f_lineno)
def fset_f_lineno(self, space, w_new_lineno):
"Returns the line number of the instruction currently being executed."
@@ -645,7 +668,7 @@
raise OperationError(space.w_ValueError,
space.wrap("lineno must be an integer"))
- if self.w_f_trace is None:
+ if self.get_w_f_trace() is None:
raise OperationError(space.w_ValueError,
space.wrap("f_lineno can only be set by a trace function."))
@@ -764,7 +787,7 @@
block.cleanup(self)
f_iblock -= 1
- self.f_lineno = new_lineno
+ self.getorcreatedebug().f_lineno = new_lineno
self.last_instr = new_lasti
def get_last_lineno(self):
@@ -782,17 +805,18 @@
return self.space.wrap(self.last_instr)
def fget_f_trace(self, space):
- return self.w_f_trace
+ return self.get_w_f_trace()
def fset_f_trace(self, space, w_trace):
if space.is_w(w_trace, space.w_None):
- self.w_f_trace = None
+ self.getorcreatedebug().w_f_trace = None
else:
- self.w_f_trace = w_trace
- self.f_lineno = self.get_last_lineno()
+ d = self.getorcreatedebug()
+ d.w_f_trace = w_trace
+ d = self.get_last_lineno()
def fdel_f_trace(self, space):
- self.w_f_trace = None
+ self.getorcreatedebug().w_f_trace = None
def fget_f_exc_type(self, space):
if self.last_exception is not None:
diff --git a/pypy/interpreter/pyopcode.py b/pypy/interpreter/pyopcode.py
--- a/pypy/interpreter/pyopcode.py
+++ b/pypy/interpreter/pyopcode.py
@@ -109,14 +109,14 @@
# dispatch_bytecode(), causing the real exception to be
# raised after the exception handler block was popped.
try:
- trace = self.w_f_trace
+ trace = self.get_w_f_trace()
if trace is not None:
- self.w_f_trace = None
+ self.getorcreatedebug().w_f_trace = None
try:
ec.bytecode_trace_after_exception(self)
finally:
if trace is not None:
- self.w_f_trace = trace
+ self.getorcreatedebug().w_f_trace = trace
except OperationError, e:
operr = e
pytraceback.record_application_traceback(
@@ -1185,7 +1185,7 @@
args = self.argument_factory(arguments, keywords, keywords_w, w_star,
w_starstar)
w_function = self.popvalue()
- if self.is_being_profiled and function.is_builtin_code(w_function):
+ if self.get_is_being_profiled() and function.is_builtin_code(w_function):
w_result = self.space.call_args_and_c_profile(self, w_function,
args)
else:
diff --git a/pypy/objspace/std/callmethod.py b/pypy/objspace/std/callmethod.py
--- a/pypy/objspace/std/callmethod.py
+++ b/pypy/objspace/std/callmethod.py
@@ -102,7 +102,7 @@
if w_self is None:
f.popvalue() # removes w_self, which is None
w_callable = f.popvalue()
- if f.is_being_profiled and function.is_builtin_code(w_callable):
+ if f.get_is_being_profiled() and function.is_builtin_code(w_callable):
w_result = f.space.call_args_and_c_profile(f, w_callable, args)
else:
w_result = f.space.call_args(w_callable, args)
diff --git a/pypy/tool/pytest/appsupport.py b/pypy/tool/pytest/appsupport.py
--- a/pypy/tool/pytest/appsupport.py
+++ b/pypy/tool/pytest/appsupport.py
@@ -237,7 +237,8 @@
frame = space.getexecutioncontext().gettopframe()
w_locals = frame.getdictscope()
pycode = frame.pycode
- filename = "<%s:%s>" %(pycode.co_filename, frame.f_lineno)
+ filename = "<%s:%s>" %(pycode.co_filename,
+ space.int_w(frame.fget_f_lineno(space)))
lines = [x + "\n" for x in expr.split("\n")]
py.std.linecache.cache[filename] = (1, None, lines, filename)
w_locals = space.call_method(w_locals, 'copy')
More information about the pypy-commit
mailing list