[pypy-commit] pypy stmgc-c4: WIP: make stm_transaction_break a guard

Raemi noreply at buildbot.pypy.org
Sun Jan 12 14:11:15 CET 2014


Author: Remi Meier <remi.meier at gmail.com>
Branch: stmgc-c4
Changeset: r68604:55c2df34eca5
Date: 2014-01-12 12:16 +0100
http://bitbucket.org/pypy/pypy/changeset/55c2df34eca5/

Log:	WIP: make stm_transaction_break a guard

diff --git a/pypy/interpreter/pyopcode.py b/pypy/interpreter/pyopcode.py
--- a/pypy/interpreter/pyopcode.py
+++ b/pypy/interpreter/pyopcode.py
@@ -67,7 +67,8 @@
                         self=self, co_code=co_code,
                         next_instr=next_instr, ec=ec)
                     # nothing inbetween!
-                    rstm.jit_stm_transaction_break_point(False)
+                    if rstm.jit_should_break_transaction(False):
+                        rstm.jit_stm_transaction_break_point()
                     self = self._hints_for_stm()
                 next_instr = self.handle_bytecode(co_code, next_instr, ec)
         except ExitFrame:
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
@@ -70,7 +70,8 @@
                     frame=self, next_instr=next_instr, pycode=pycode,
                     is_being_profiled=is_being_profiled)
                 # nothing inbetween!
-                rstm.jit_stm_transaction_break_point(False)
+                if rstm.jit_should_break_transaction(False):
+                    rstm.jit_stm_transaction_break_point()
                 co_code = pycode.co_code
                 self.valuestackdepth = hint(self.valuestackdepth, promote=True)
                 next_instr = self.handle_bytecode(co_code, next_instr, ec)
@@ -96,7 +97,8 @@
             self.last_instr = intmask(jumpto)
             ec.bytecode_trace(self, decr_by)
             jumpto = r_uint(self.last_instr)
-            rstm.jit_stm_transaction_break_point(True)
+            if rstm.jit_should_break_transaction(True):
+                rstm.jit_stm_transaction_break_point()
         #
         pypyjitdriver.can_enter_jit(frame=self, ec=ec, next_instr=jumpto,
                                     pycode=self.getcode(),
diff --git a/rpython/jit/codewriter/jtransform.py b/rpython/jit/codewriter/jtransform.py
--- a/rpython/jit/codewriter/jtransform.py
+++ b/rpython/jit/codewriter/jtransform.py
@@ -1341,15 +1341,17 @@
                                           [v], None))
         return ops
 
+    def rewrite_op_jit_stm_should_break_transaction(self, op):
+        assert isinstance(op.args[0], Constant)
+        
+        arg = int(op.args[0].value)
+        c_arg = Constant(arg, lltype.Signed)
+
+        return SpaceOperation('stm_should_break_transaction',
+                              [c_arg], op.result)
+
     def rewrite_op_jit_stm_transaction_break_point(self, op):
-        if isinstance(op.args[0], Constant):
-            arg = int(op.args[0].value)
-            c_arg = Constant(arg, lltype.Signed)
-        else:
-            log.WARNING("stm_transaction_break_point without const argument, assuming False in %r" % (self.graph,))
-            c_arg = Constant(0, lltype.Signed)
-
-        return SpaceOperation('stm_transaction_break', [c_arg], op.result)
+        return SpaceOperation('stm_transaction_break', [], op.result)
     
     def rewrite_op_jit_marker(self, op):
         key = op.args[0].value
diff --git a/rpython/jit/metainterp/blackhole.py b/rpython/jit/metainterp/blackhole.py
--- a/rpython/jit/metainterp/blackhole.py
+++ b/rpython/jit/metainterp/blackhole.py
@@ -893,8 +893,14 @@
     def bhimpl_ref_isvirtual(x):
         return False
 
-    @arguments("i")
-    def bhimpl_stm_transaction_break(if_there_is_no_other):
+
+    @arguments("i", returns="i")
+    def bhimpl_stm_should_break_transaction(if_there_is_no_other):
+        return False
+
+
+    @arguments()
+    def bhimpl_stm_transaction_break():
         pass
     
     # ----------
diff --git a/rpython/jit/metainterp/pyjitpl.py b/rpython/jit/metainterp/pyjitpl.py
--- a/rpython/jit/metainterp/pyjitpl.py
+++ b/rpython/jit/metainterp/pyjitpl.py
@@ -18,8 +18,7 @@
 from rpython.rlib.jit import Counters
 from rpython.rlib.objectmodel import we_are_translated, specialize
 from rpython.rlib.unroll import unrolling_iterable
-from rpython.rtyper.lltypesystem import lltype, rclass, rffi
-
+from rpython.rtyper.lltypesystem import lltype, rclass, rffi, llmemory
 
 
 # ____________________________________________________________
@@ -189,13 +188,26 @@
 
     # ------------------------------
     @arguments("int")
-    def opimpl_stm_transaction_break(self, if_there_is_no_other):
+    def opimpl_stm_should_break_transaction(self, if_there_is_no_other):
         val = bool(if_there_is_no_other)
         mi = self.metainterp
         if (mi.stm_break_wanted or (val and not mi.stm_break_done)):
             mi.stm_break_done = True
             mi.stm_break_wanted = False
-            self.execute(rop.STM_TRANSACTION_BREAK, ConstInt(val))
+            # insert a CALL
+            resbox = history.BoxInt(0)
+            funcptr = mi.staticdata.stm_should_break_transaction
+            funcdescr = mi.staticdata.stm_should_break_transaction_descr
+            funcaddr = llmemory.cast_ptr_to_adr(funcptr)
+            mi._record_helper_nonpure_varargs(
+                rop.CALL, resbox, funcdescr,
+                [ConstInt(mi.cpu.cast_adr_to_int(funcaddr)),])
+            return resbox
+        else:
+            return ConstInt(0)
+
+    def opimpl_stm_transaction_break(self):
+        self.execute(rop.STM_TRANSACTION_BREAK)
     
     for _opimpl in ['int_add', 'int_sub', 'int_mul', 'int_floordiv', 'int_mod',
                     'int_lt', 'int_le', 'int_eq',
@@ -1507,6 +1519,22 @@
         d = self.exit_frame_with_exception_descr_ref
         self.cpu.exit_frame_with_exception_descr_ref = d
 
+        if self.config.translation.stm:
+            self.stm_should_break_transaction = rffi.llexternal(
+                'stm_should_break_transaction',
+                [], lltype.Bool,
+                sandboxsafe=True, _nowrapper=True, transactionsafe=True)
+            FUNC = lltype.typeOf(self.stm_should_break_transaction).TO
+
+            ei = EffectInfo([], [], [], [],
+                            EffectInfo.EF_CANNOT_RAISE,
+                            can_invalidate=False)
+            
+            self.stm_should_break_transaction_descr = (
+                self.cpu.calldescrof(FUNC, FUNC.ARGS,
+                                     FUNC.RESULT, ei))
+
+            
     def _freeze_(self):
         return True
 
@@ -2695,7 +2723,6 @@
         # if the codewriter didn't produce any OS_LIBFFI_CALL at all.
         assert self.staticdata.has_libffi_call
         #
-        from rpython.rtyper.lltypesystem import llmemory
         from rpython.rlib.jit_libffi import CIF_DESCRIPTION_P
         from rpython.jit.backend.llsupport.ffisupport import get_arg_descr
         #
diff --git a/rpython/jit/metainterp/test/test_stm.py b/rpython/jit/metainterp/test/test_stm.py
new file mode 100644
--- /dev/null
+++ b/rpython/jit/metainterp/test/test_stm.py
@@ -0,0 +1,19 @@
+import py, sys
+from rpython.jit.metainterp.test.support import LLJitMixin
+from rpython.rlib.jit import JitDriver, dont_look_inside
+from rpython.rlib.rarithmetic import ovfcheck, LONG_BIT, intmask
+from rpython.jit.codewriter.policy import StopAtXPolicy
+from rpython.rlib import rstm
+
+
+
+
+class STMTests:
+    def test_simple(self):
+        def g():
+            return rstm.jit_stm_should_break_transaction(False)
+        res = self.interp_operations(g, [])
+        assert res == False
+
+class TestLLtype(STMTests, LLJitMixin):
+    pass
diff --git a/rpython/jit/tl/tlc.py b/rpython/jit/tl/tlc.py
--- a/rpython/jit/tl/tlc.py
+++ b/rpython/jit/tl/tlc.py
@@ -250,7 +250,8 @@
                 myjitdriver.jit_merge_point(frame=frame,
                                             code=code, pc=pc, pool=pool)
                 # nothing inbetween!
-                rstm.jit_stm_transaction_break_point(False)
+                if rstm.jit_should_break_transaction(False):
+                    rstm.jit_stm_transaction_break_point()
             opcode = ord(code[pc])
             pc += 1
             stack = frame.stack
@@ -351,7 +352,8 @@
                 pc += char2int(code[pc])
                 pc += 1
                 if jitted and old_pc > pc:
-                    rstm.jit_stm_transaction_break_point(True)
+                    if rstm.jit_should_break_transaction(True):
+                        rstm.jit_stm_transaction_break_point()
                     myjitdriver.can_enter_jit(code=code, pc=pc, frame=frame,
                                               pool=pool)
                 
@@ -361,7 +363,8 @@
                     old_pc = pc
                     pc += char2int(code[pc]) + 1
                     if jitted and old_pc > pc:
-                        rstm.jit_stm_transaction_break_point(True)
+                        if rstm.jit_should_break_transaction(True):
+                            rstm.jit_stm_transaction_break_point()
                         myjitdriver.can_enter_jit(code=code, pc=pc, frame=frame,
                                                   pool=pool)
                 else:
@@ -373,7 +376,8 @@
                     old_pc = pc
                     pc += offset
                     if jitted and old_pc > pc:
-                        rstm.jit_stm_transaction_break_point(True)
+                        if rstm.jit_should_break_transaction(True):
+                            rstm.jit_stm_transaction_break_point()
                         myjitdriver.can_enter_jit(code=code, pc=pc, frame=frame,
                                                   pool=pool)
                         
diff --git a/rpython/rlib/rstm.py b/rpython/rlib/rstm.py
--- a/rpython/rlib/rstm.py
+++ b/rpython/rlib/rstm.py
@@ -29,26 +29,20 @@
     addr = llop.stm_get_adr_of_read_barrier_cache(llmemory.Address)
     return rffi.cast(lltype.Signed, addr)
 
-def jit_stm_transaction_break_point(if_there_is_no_other):
+def jit_stm_transaction_break_point():
+    if we_are_translated():
+        llop.jit_stm_transaction_break_point(lltype.Void)
+
+
+def jit_stm_should_break_transaction(if_there_is_no_other):
     # if_there_is_no_other means that we use this point only
     # if there is no other break point in the trace.
     # If it is False, the point may be used if it comes right
     # a CALL_RELEASE_GIL
-    pass # specialized below
-    # llop.jit_stm_transaction_break_point(lltype.Void,
-    #                                      if_there_is_no_other)
+    return llop.jit_stm_should_break_transaction(lltype.Bool,
+                                                 if_there_is_no_other)
 
-class JitSTMTransactionBreakPoint(ExtRegistryEntry):
-    _about_ = jit_stm_transaction_break_point
-    def compute_result_annotation(self, arg):
-        from rpython.annotator import model as annmodel
-        return annmodel.s_None
-    def specialize_call(self, hop):
-        [v_arg] = hop.inputargs(lltype.Bool)
-        hop.exception_cannot_occur()
-        return hop.genop('jit_stm_transaction_break_point', [v_arg],
-                         resulttype=lltype.Void)
-    
+
 @dont_look_inside
 def become_inevitable():
     llop.stm_become_inevitable(lltype.Void)
diff --git a/rpython/rtyper/lltypesystem/lloperation.py b/rpython/rtyper/lltypesystem/lloperation.py
--- a/rpython/rtyper/lltypesystem/lloperation.py
+++ b/rpython/rtyper/lltypesystem/lloperation.py
@@ -525,6 +525,7 @@
                                canraise=(Exception,),
                                canmallocgc=True),
     'jit_stm_transaction_break_point' : LLOp(canmallocgc=True),
+    'jit_stm_should_break_transaction' : LLOp(canrun=True),
 
     # __________ GC operations __________
 
diff --git a/rpython/rtyper/lltypesystem/opimpl.py b/rpython/rtyper/lltypesystem/opimpl.py
--- a/rpython/rtyper/lltypesystem/opimpl.py
+++ b/rpython/rtyper/lltypesystem/opimpl.py
@@ -701,6 +701,9 @@
 def op_jit_assembler_call(funcptr, *args):
     return funcptr(*args)
 
+def op_jit_stm_should_break_transaction(if_there_is_no_other):
+    return False
+
 # ____________________________________________________________
 
 def get_op_impl(opname):
diff --git a/rpython/translator/stm/jitdriver.py b/rpython/translator/stm/jitdriver.py
--- a/rpython/translator/stm/jitdriver.py
+++ b/rpython/translator/stm/jitdriver.py
@@ -18,12 +18,13 @@
                 and op.args[0].value == 'jit_merge_point'):
                 jitdriver = op.args[1].value
                 if not jitdriver.autoreds:
-                    if (relaxed
-                        or (i + 1 < len(block.operations)
-                            and block.operations[i+1].opname == 'jit_stm_transaction_break_point')):
-                        found.append((block, i))
-                    else:
-                        log.WARNING("ignoring jitdriver without a transaction break point in %r" % (graph,))
+                    # XXX: BUG, redo the below code in order to ensure atomicity of bytecode instrs
+                    # if (relaxed
+                    #     or (i + 1 < len(block.operations)
+                    #         and block.operations[i+1].opname == 'jit_stm_transaction_break_point')):
+                    found.append((block, i))
+                    # else:
+                    #     log.WARNING("ignoring jitdriver without a transaction break point in %r" % (graph,))
                 else:
                     log.WARNING("ignoring jitdriver with autoreds in %r" % (
                         graph,))        # XXX XXX!


More information about the pypy-commit mailing list