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

Reply via email to