Author: Armin Rigo <[email protected]>
Branch: 
Changeset: r48072:51224696c078
Date: 2011-10-15 14:43 +0200
http://bitbucket.org/pypy/pypy/changeset/51224696c078/

Log:    Use a quasi-immutable field to record whether we started using
        threads or not so far. As long as we didn't, we can generate
        assembler loops that don't need to decrement the GIL counter.

diff --git a/pypy/interpreter/executioncontext.py 
b/pypy/interpreter/executioncontext.py
--- a/pypy/interpreter/executioncontext.py
+++ b/pypy/interpreter/executioncontext.py
@@ -391,8 +391,11 @@
     def decrement_ticker(self, by):
         value = self._ticker
         if self.has_bytecode_counter:    # this 'if' is constant-folded
-            value -= by
-            self._ticker = value
+            if jit.isconstant(by) and by == 0:
+                pass     # normally constant-folded too
+            else:
+                value -= by
+                self._ticker = value
         return value
 
 
diff --git a/pypy/module/pypyjit/interp_jit.py 
b/pypy/module/pypyjit/interp_jit.py
--- a/pypy/module/pypyjit/interp_jit.py
+++ b/pypy/module/pypyjit/interp_jit.py
@@ -137,20 +137,15 @@
 
     def jump_absolute(self, jumpto, _, ec=None):
         if we_are_jitted():
-            # Normally, the tick counter is decremented by 100 for every
-            # Python opcode.  Here, to better support JIT compilation of
-            # small loops, we decrement it by a possibly smaller constant.
-            # We get the maximum 100 when the (unoptimized) trace length
-            # is at least 3200 (a bit randomly).
-            trace_length = r_uint(current_trace_length())
-            decr_by = trace_length // 32
-            if decr_by < 1:
-                decr_by = 1
-            elif decr_by > 100:    # also if current_trace_length() returned -1
-                decr_by = 100
+            #
+            # assume that only threads are using the bytecode counter
+            decr_by = 0
+            if self.space.actionflag.has_bytecode_counter:   # constant-folded
+                if self.space.threadlocals.gil_ready:   # quasi-immutable field
+                    decr_by = _get_adapted_tick_counter()
             #
             self.last_instr = intmask(jumpto)
-            ec.bytecode_trace(self, intmask(decr_by))
+            ec.bytecode_trace(self, decr_by)
             jumpto = r_uint(self.last_instr)
         #
         pypyjitdriver.can_enter_jit(frame=self, ec=ec, next_instr=jumpto,
@@ -158,6 +153,20 @@
                                     is_being_profiled=self.is_being_profiled)
         return jumpto
 
+def _get_adapted_tick_counter():
+    # Normally, the tick counter is decremented by 100 for every
+    # Python opcode.  Here, to better support JIT compilation of
+    # small loops, we decrement it by a possibly smaller constant.
+    # We get the maximum 100 when the (unoptimized) trace length
+    # is at least 3200 (a bit randomly).
+    trace_length = r_uint(current_trace_length())
+    decr_by = trace_length // 32
+    if decr_by < 1:
+        decr_by = 1
+    elif decr_by > 100:    # also if current_trace_length() returned -1
+        decr_by = 100
+    return intmask(decr_by)
+
 
 PyCode__initialize = PyCode._initialize
 
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
@@ -109,8 +109,11 @@
         p = pypysig_getaddr_occurred()
         value = p.c_value
         if self.has_bytecode_counter:    # this 'if' is constant-folded
-            value -= by
-            p.c_value = value
+            if jit.isconstant(by) and by == 0:
+                pass     # normally constant-folded too
+            else:
+                value -= by
+                p.c_value = value
         return value
 
 
diff --git a/pypy/module/thread/gil.py b/pypy/module/thread/gil.py
--- a/pypy/module/thread/gil.py
+++ b/pypy/module/thread/gil.py
@@ -17,6 +17,7 @@
 class GILThreadLocals(OSThreadLocals):
     """A version of OSThreadLocals that enforces a GIL."""
     gil_ready = False
+    _immutable_fields_ = ['gil_ready?']
 
     def initialize(self, space):
         # add the GIL-releasing callback as an action on the space
diff --git a/pypy/module/thread/threadlocals.py 
b/pypy/module/thread/threadlocals.py
--- a/pypy/module/thread/threadlocals.py
+++ b/pypy/module/thread/threadlocals.py
@@ -8,12 +8,13 @@
 
     def __init__(self):
         self._valuedict = {}   # {thread_ident: ExecutionContext()}
+        self._freeze_()
+
+    def _freeze_(self):
+        self._valuedict.clear()
         self._mainthreadident = 0
         self._mostrecentkey = 0        # fast minicaching for the common case
         self._mostrecentvalue = None   # fast minicaching for the common case
-
-    def _freeze_(self):
-        self.__init__()
         return False
 
     def getvalue(self):
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to