Author: Armin Rigo <[email protected]>
Branch: stm-thread
Changeset: r55443:7c36b212bd3a
Date: 2012-06-06 19:05 +0200
http://bitbucket.org/pypy/pypy/changeset/7c36b212bd3a/

Log:    Tweaks in the main loop to not longer systematically call
        rstm.perform_transaction().

diff --git a/pypy/interpreter/pyopcode.py b/pypy/interpreter/pyopcode.py
--- a/pypy/interpreter/pyopcode.py
+++ b/pypy/interpreter/pyopcode.py
@@ -75,23 +75,32 @@
     ### opcode dispatch ###
 
     def dispatch(self, pycode, next_instr, ec):
-        if self.space.config.translation.stm and we_are_translated():
-            return self.dispatch_with_stm(next_instr)
-
         # For the sequel, force 'next_instr' to be unsigned for performance
         next_instr = r_uint(next_instr)
         co_code = pycode.co_code
 
         try:
-            while True:
+            while self._runs_normal_handler():
                 next_instr = self.handle_bytecode(co_code, next_instr, ec)
         except ExitFrame:
             return self.popvalue()
+        #
+        # we only get here if _runs_normal_handler() returned False
+        return self._dispatch_stm_breaking_transaction(next_instr)
 
-    def dispatch_with_stm(self, next_instr):
+    def _runs_normal_handler(self):
+        if self.space.config.translation.stm and we_are_translated():
+            return not rstm.should_break_transaction()
+        return True
+
+    def _dispatch_stm_breaking_transaction(self, next_instr):
+        # STM: entered the first time this frame is asked to introduce
+        # a transaction break.  This is done by invoking the C function
+        # rstm.perform_transaction(), which calls back
+        # _dispatch_new_stm_transaction().
         from pypy.rlib import rstm
-        self.last_instr = intmask(next_instr)
-        rstm.perform_transaction(pyframe.PyFrame._dispatch_stm_transaction,
+        self.last_instr = intmask(next_instr)     # save this value
+        rstm.perform_transaction(pyframe.PyFrame._dispatch_new_stm_transaction,
                                  self.space.FrameClass, self)
         e = self.__reraise
         if e is None:
@@ -100,21 +109,26 @@
             self.__reraise = None
             raise e                   # re-raise the exception we got
 
-    def _dispatch_stm_transaction(self, retry_counter):
+    def _dispatch_new_stm_transaction(self, retry_counter):
         self = self._hints_for_stm()
+        co_code = self.pycode.co_code
+        next_instr = r_uint(self.last_instr)    # restore this value
+        ec = self.space.getexecutioncontext()
+
+        # a loop similar to the one in dispatch()
         try:
-            co_code = self.pycode.co_code
-            next_instr = r_uint(self.last_instr)
-            ec = self.space.getexecutioncontext()
-            next_instr = self.handle_bytecode(co_code, next_instr, ec)
-            self.last_instr = intmask(next_instr)
-            return 1     # loop
+            while self._runs_normal_handler():
+                next_instr = self.handle_bytecode(co_code, next_instr, ec)
         except ExitFrame:
             self.__reraise = None
-            return 0     # stop looping
+            return 0     # stop perform_transaction() and returns
         except Exception, e:
             self.__reraise = e
-            return 0     # stop looping
+            return 0     # stop perform_transaction() and returns
+        #
+        # we get there if _runs_normal_handler() return False again
+        self.last_instr = intmask(next_instr)      # save this value
+        return 1     # causes perform_transaction() to loop and call us again
 
     def handle_bytecode(self, co_code, next_instr, ec):
         try:
@@ -318,9 +332,21 @@
                 return next_instr
 
             if self.space.config.translation.stm:
+                # with STM, if should_break_transaction(), then it is a good
+                # idea to leave and let _dispatch_stm_breaking_transaction()
+                # break the transaction.  But avoid doing it if we are in a
+                # tail-call position: if the next opcode is RETURN_VALUE, or
+                # one of the opcodes in the one of the sequences
+                #    * POP_TOP/LOAD_CONST/RETURN_VALUE
+                #    * POP_TOP/LOAD_FAST/RETURN_VALUE
                 from pypy.rlib import rstm
                 if rstm.should_break_transaction():
-                    return next_instr
+                    opcode = ord(co_code[next_instr])
+                    if opcode not in (self.opcodedesc.RETURN_VALUE.index,
+                                      self.opcodedesc.POP_TOP.index,
+                                      self.opcodedesc.LOAD_CONST.index,
+                                      self.opcodedesc.LOAD_FAST.index):
+                        return next_instr
 
     @jit.unroll_safe
     def unrollstack(self, unroller_kind):
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to