Author: Alex Gaynor <[email protected]>
Branch: jit-settrace
Changeset: r67542:226c15c4600b
Date: 2013-10-23 18:05 -0700
http://bitbucket.org/pypy/pypy/changeset/226c15c4600b/
Log: Random hacks to make the JIT compile things when you have
sys.settrace enabled
diff --git a/pypy/interpreter/eval.py b/pypy/interpreter/eval.py
--- a/pypy/interpreter/eval.py
+++ b/pypy/interpreter/eval.py
@@ -2,6 +2,8 @@
This module defines the abstract base classes that support execution:
Code and Frame.
"""
+from rpython.rlib import jit
+
from pypy.interpreter.error import OperationError
from pypy.interpreter.baseobjspace import W_Root
@@ -85,28 +87,15 @@
self.w_locals = w_locals
self.locals2fast()
- def getfastscope(self):
- "Abstract. Get the fast locals as a list."
- raise TypeError("abstract")
-
- def setfastscope(self, scope_w):
- """Abstract. Initialize the fast locals from a list of values,
- where the order is according to self.getcode().signature()."""
- raise TypeError("abstract")
-
- def getfastscopelength(self):
- "Abstract. Get the expected number of locals."
- raise TypeError("abstract")
-
+ @jit.look_inside_iff(lambda self: jit.isvirtual(self))
def fast2locals(self):
# Copy values from the fastlocals to self.w_locals
if self.w_locals is None:
self.w_locals = self.space.newdict()
varnames = self.getcode().getvarnames()
- fastscope_w = self.getfastscope()
- for i in range(min(len(varnames), self.getfastscopelength())):
+ for i in range(min(len(varnames), self.pycode.co_nlocals)):
name = varnames[i]
- w_value = fastscope_w[i]
+ w_value = self.locals_stack_w[i]
w_name = self.space.wrap(name)
if w_value is not None:
self.space.setitem(self.w_locals, w_name, w_value)
@@ -117,11 +106,12 @@
if not e.match(self.space, self.space.w_KeyError):
raise
+ @jit.look_inside_iff(lambda self: jit.isvirtual(self))
def locals2fast(self):
# Copy values from self.w_locals to the fastlocals
assert self.w_locals is not None
varnames = self.getcode().getvarnames()
- numlocals = self.getfastscopelength()
+ numlocals = self.pycode.co_nlocals
new_fastlocals_w = [None] * numlocals
diff --git a/pypy/interpreter/executioncontext.py
b/pypy/interpreter/executioncontext.py
--- a/pypy/interpreter/executioncontext.py
+++ b/pypy/interpreter/executioncontext.py
@@ -76,7 +76,7 @@
frame_vref()
jit.virtual_ref_finish(frame_vref, frame)
- if self.w_tracefunc is not None and not frame.hide():
+ if self.gettrace() is not None and not frame.hide():
self.space.frame_trace_action.fire()
# ________________________________________________________________
@@ -115,14 +115,14 @@
def call_trace(self, frame):
"Trace the call of a function"
- if self.w_tracefunc is not None or self.profilefunc is not None:
+ if self.gettrace() 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"
- if self.w_tracefunc is not None:
+ if self.gettrace() is not None:
return_from_hidden = self._trace(frame, 'return', w_retval)
# special case: if we are returning from a hidden function,
# then maybe we have to fire() the action again; otherwise
@@ -152,7 +152,7 @@
def exception_trace(self, frame, operationerr):
"Trace function called upon OperationError."
operationerr.record_interpreter_traceback()
- if self.w_tracefunc is not None:
+ if self.gettrace() is not None:
self._trace(frame, 'exception', None, operationerr)
#operationerr.print_detailed_traceback(self.space)
@@ -181,7 +181,7 @@
self.space.frame_trace_action.fire()
def gettrace(self):
- return self.w_tracefunc
+ return jit.promote(self.w_tracefunc)
def setprofile(self, w_func):
"""Set the global trace function."""
@@ -234,7 +234,7 @@
# Tracing cases
if event == 'call':
- w_callback = self.w_tracefunc
+ w_callback = self.gettrace()
else:
w_callback = frame.w_f_trace
@@ -367,7 +367,7 @@
def _rebuild_action_dispatcher(self):
periodic_actions = unrolling_iterable(self._periodic_actions)
- @jit.dont_look_inside
+ @jit.unroll_safe
def action_dispatcher(ec, frame):
# periodic actions (first reset the bytecode counter)
self.reset_ticker(self.checkinterval_scaled)
@@ -454,6 +454,9 @@
def perform(self, executioncontext, frame):
if self.finalizers_lock_count > 0:
return
+ self._run_finalizers()
+
+ def _run_finalizers(self):
# Each call to perform() first grabs the self.dying_objects
# and replaces it with an empty list. We do this to try to
# avoid too deep recursions of the kind of __del__ being called
@@ -473,9 +476,10 @@
class FrameTraceAction(AsyncAction):
"""An action that calls the local trace functions (w_f_trace)."""
+ @jit.unroll_safe
def perform(self, executioncontext, frame):
if (frame.w_f_trace is None or executioncontext.is_tracing or
- executioncontext.w_tracefunc is None):
+ executioncontext.gettrace() is None):
return
code = frame.pycode
if frame.instr_lb <= frame.last_instr < frame.instr_ub:
diff --git a/pypy/interpreter/nestedscope.py b/pypy/interpreter/nestedscope.py
--- a/pypy/interpreter/nestedscope.py
+++ b/pypy/interpreter/nestedscope.py
@@ -128,7 +128,7 @@
if self.cells is not None:
self.cells[:ncellvars] = cellvars
- @jit.dont_look_inside
+ @jit.look_inside_iff(lambda self: jit.isvirtual(self))
def fast2locals(self):
super_fast2locals(self)
# cellvars are values exported to inner scopes
@@ -147,7 +147,7 @@
w_name = self.space.wrap(name)
self.space.setitem(self.w_locals, w_name, w_value)
- @jit.dont_look_inside
+ @jit.look_inside_iff(lambda self: jit.isvirtual(self))
def locals2fast(self):
super_locals2fast(self)
freevarnames = self.pycode.co_cellvars + self.pycode.co_freevars
diff --git a/pypy/interpreter/pyframe.py b/pypy/interpreter/pyframe.py
--- a/pypy/interpreter/pyframe.py
+++ b/pypy/interpreter/pyframe.py
@@ -440,12 +440,7 @@
def getcode(self):
return hint(self.pycode, promote=True)
- @jit.dont_look_inside
- def getfastscope(self):
- "Get the fast locals as a list."
- return self.locals_stack_w
-
- @jit.dont_look_inside
+ @jit.look_inside_iff(lambda self, scope_w: jit.isvirtual(scope_w))
def setfastscope(self, scope_w):
"""Initialize the fast locals from a list of values,
where the order is according to self.pycode.signature()."""
@@ -463,9 +458,6 @@
This is overridden in nestedscope.py"""
pass
- def getfastscopelength(self):
- return self.pycode.co_nlocals
-
def getclosure(self):
return None
diff --git a/pypy/module/signal/interp_signal.py
b/pypy/module/signal/interp_signal.py
--- a/pypy/module/signal/interp_signal.py
+++ b/pypy/module/signal/interp_signal.py
@@ -75,11 +75,15 @@
# and there is a signal pending: we force the ticker to
# -1, which should ensure perform() is called quickly.
+ def perform(self, executioncontext, frame):
+ self._poll_for_signals()
+
@jit.dont_look_inside
- def perform(self, executioncontext, frame):
+ def _poll_for_signals(self):
# Poll for the next signal, if any
n = self.pending_signal
- if n < 0: n = pypysig_poll()
+ if n < 0:
+ n = pypysig_poll()
while n >= 0:
if self.space.threadlocals.signals_enabled():
# If we are in the main thread, report the signal now,
@@ -87,7 +91,8 @@
self.pending_signal = -1
report_signal(self.space, n)
n = self.pending_signal
- if n < 0: n = pypysig_poll()
+ if n < 0:
+ n = pypysig_poll()
else:
# Otherwise, arrange for perform() to be called again
# after we switch to the main thread.
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit