[pypy-commit] pypy stmgc-c7: make stm_hint_commit_soon visible to the JIT in order to not remove transaction

Raemi noreply at buildbot.pypy.org
Mon May 12 09:18:23 CEST 2014


Author: Remi Meier <remi.meier at inf.ethz.ch>
Branch: stmgc-c7
Changeset: r71468:a43485667edf
Date: 2014-05-12 09:16 +0200
http://bitbucket.org/pypy/pypy/changeset/a43485667edf/

Log:	make stm_hint_commit_soon visible to the JIT in order to not remove
	transaction breaks right after it

diff --git a/rpython/jit/backend/llsupport/gc.py b/rpython/jit/backend/llsupport/gc.py
--- a/rpython/jit/backend/llsupport/gc.py
+++ b/rpython/jit/backend/llsupport/gc.py
@@ -237,7 +237,7 @@
         return self.malloc_array(arraydescr.basesize, num_elem,
                                  arraydescr.itemsize,
                                  arraydescr.lendescr.offset)
-    
+
     def get_malloc_slowpath_addr(self):
         return None
 
@@ -257,7 +257,7 @@
 class GcRootMap_shadowstack(object):
     is_shadow_stack = True
     is_stm = False
-    
+
     def __init__(self, gcdescr):
         pass
 
@@ -271,7 +271,7 @@
 class GcRootMap_stm(object):
     is_shadow_stack = True
     is_stm = True
-    
+
     def __init__(self, gcdescr):
         pass
 
@@ -490,7 +490,7 @@
         unicode_itemsize   = self.unicode_descr.itemsize
         unicode_ofs_length = self.unicode_descr.lendescr.offset
 
-        
+
         def malloc_str(length):
             type_id = llop.extract_ushort(llgroup.HALFWORD, str_type_id)
             return llop1.do_malloc_varsize_clear(
@@ -499,7 +499,7 @@
                 str_ofs_length)
         self.generate_function('malloc_str', malloc_str,
                                [lltype.Signed])
-            
+
         def malloc_unicode(length):
             type_id = llop.extract_ushort(llgroup.HALFWORD, unicode_type_id)
             return llop1.do_malloc_varsize_clear(
@@ -529,6 +529,9 @@
             self.generate_function('stm_try_inevitable',
                                    rstm.become_inevitable, [],
                                    RESULT=lltype.Void)
+            self.generate_function('stm_hint_commit_soon',
+                                   rstm.hint_commit_soon, [],
+                                   RESULT=lltype.Void)
 
     def _bh_malloc(self, sizedescr):
         from rpython.memory.gctypelayout import check_typeid
@@ -603,7 +606,7 @@
 
     def can_use_nursery_malloc(self, size):
         return size < self.max_size_of_young_obj
-        
+
     def has_write_barrier_class(self):
         return WriteBarrierDescr
 
@@ -612,7 +615,7 @@
 
     def get_malloc_slowpath_array_addr(self):
         return self.get_malloc_fn_addr('malloc_array')
-    
+
 # ____________________________________________________________
 
 def get_ll_description(gcdescr, translator=None, rtyper=None):
diff --git a/rpython/jit/backend/llsupport/stmrewrite.py b/rpython/jit/backend/llsupport/stmrewrite.py
--- a/rpython/jit/backend/llsupport/stmrewrite.py
+++ b/rpython/jit/backend/llsupport/stmrewrite.py
@@ -31,6 +31,10 @@
             self.next_op_may_be_in_new_transaction()
             self.newops.append(op)
             return
+        if opnum == rop.STM_HINT_COMMIT_SOON:
+            self._do_stm_call('stm_hint_commit_soon', [], None,
+                              op.stm_location)
+            return
         # ----------  pure operations, guards  ----------
         if op.is_always_pure() or op.is_guard() or op.is_ovf():
             self.newops.append(op)
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
@@ -912,7 +912,12 @@
     @arguments()
     def bhimpl_stm_transaction_break():
         pass
-    
+
+    @arguments()
+    def bhimpl_stm_hint_commit_soon():
+        pass
+
+
     # ----------
     # the main hints and recursive calls
 
diff --git a/rpython/jit/metainterp/heapcache.py b/rpython/jit/metainterp/heapcache.py
--- a/rpython/jit/metainterp/heapcache.py
+++ b/rpython/jit/metainterp/heapcache.py
@@ -127,7 +127,8 @@
             opnum == rop.COPYSTRCONTENT or
             opnum == rop.COPYUNICODECONTENT):
             return
-        if opnum in (rop.GUARD_NOT_FORCED, rop.GUARD_NOT_FORCED_2):
+        if opnum in (rop.GUARD_NOT_FORCED, rop.GUARD_NOT_FORCED_2,
+                     rop.STM_HINT_COMMIT_SOON):
             self.stm_break_wanted = True
             return
         if (rop._OVF_FIRST <= opnum <= rop._OVF_LAST or
diff --git a/rpython/jit/metainterp/optimizeopt/stm.py b/rpython/jit/metainterp/optimizeopt/stm.py
--- a/rpython/jit/metainterp/optimizeopt/stm.py
+++ b/rpython/jit/metainterp/optimizeopt/stm.py
@@ -31,7 +31,7 @@
     def flush(self):
         # just in case. it shouldn't be necessary
         self.flush_cached()
-        
+
     def default_emit(self, op):
         self.flush_cached()
         self.emit_operation(op)
@@ -39,7 +39,7 @@
     def _break_wanted(self):
         is_loop = self.optimizer.loop.is_really_loop
         return self.optimizer.stm_info.get('break_wanted', is_loop)
-    
+
     def _set_break_wanted(self, val):
         self.optimizer.stm_info['break_wanted'] = val
 
@@ -84,6 +84,11 @@
             self.keep_but_ignore_gnf = False
             self.emit_operation(op)
 
+    def optimize_STM_HINT_COMMIT_SOON(self, op):
+        self.flush_cached()
+        self._set_break_wanted(True)
+        self.emit_operation(op)
+
 
 dispatch_opt = make_dispatcher_method(OptSTM, 'optimize_',
                                       default=OptSTM.default_emit)
diff --git a/rpython/jit/metainterp/optimizeopt/test/test_stm.py b/rpython/jit/metainterp/optimizeopt/test/test_stm.py
--- a/rpython/jit/metainterp/optimizeopt/test/test_stm.py
+++ b/rpython/jit/metainterp/optimizeopt/test/test_stm.py
@@ -70,7 +70,7 @@
 
         i0 = stm_should_break_transaction()
         guard_false(i0) []
-        
+
         jump()
         """
         expected = """
@@ -93,7 +93,7 @@
         preamble = """
         [p1]
         i1 = getfield_gc(p1, descr=adescr)
-        
+
         i0 = stm_should_break_transaction()
         guard_false(i0) []
         jump(p1)
@@ -102,7 +102,7 @@
         [p1]
         i0 = stm_should_break_transaction()
         guard_false(i0) []
-        
+
         jump(p1)
         """
         self.optimize_loop(ops, expected, expected_preamble=preamble)
@@ -142,10 +142,10 @@
         []
         stm_transaction_break(0)
         guard_not_forced() []
-        
+
         escape() # e.g. like a call_release_gil
         guard_not_forced() []
-        
+
         stm_transaction_break(0)
         guard_not_forced() []
         stm_transaction_break(0)
@@ -164,7 +164,7 @@
 
         stm_transaction_break(0)
         guard_not_forced() []
-        
+
         i0 = stm_should_break_transaction()
         guard_false(i0) []
         jump()
@@ -209,7 +209,7 @@
         guard_not_forced() []
 
         p6 = force_token() # not removed!
-                
+
         i0 = stm_should_break_transaction()
         guard_false(i0) []
         jump(p0)
@@ -224,7 +224,7 @@
         escape()
 
         p6 = force_token() # not removed!
-        
+
         i0 = stm_should_break_transaction()
         guard_false(i0) []
         jump(p0)
@@ -234,7 +234,7 @@
         escape()
 
         p6 = force_token() # not removed!
-        
+
         i0 = stm_should_break_transaction()
         guard_false(i0) []
         jump(p0)
@@ -246,7 +246,7 @@
         [p0, p1]
         setfield_gc(p0, p1, descr=adescr)
         stm_transaction_break(0)
-        
+
         p2 = force_token()
         p3 = force_token()
         jump(p0, p1)
@@ -264,9 +264,9 @@
         [p0, p1]
         p2 = force_token()
         p3 = force_token()
-        
+
         setfield_gc(p0, p1, descr=adescr) # moved here by other stuff...
-        jump(p0, p1)        
+        jump(p0, p1)
         """
         self.optimize_loop(ops, expected, expected_preamble=preamble)
 
@@ -286,3 +286,46 @@
         jump(i1, p1)
         """
         self.optimize_loop(ops, expected)
+
+    def test_add_tb_after_commit_soon(self):
+        ops = """
+        []
+        stm_transaction_break(0)
+        guard_not_forced() []
+
+        stm_hint_commit_soon()
+
+        stm_transaction_break(0)
+        guard_not_forced() []
+        stm_transaction_break(0)
+        guard_not_forced() []
+        i0 = stm_should_break_transaction()
+        guard_false(i0) []
+        jump()
+        """
+        preamble = """
+        []
+        stm_transaction_break(0)
+        guard_not_forced() []
+
+        stm_hint_commit_soon()
+
+        stm_transaction_break(0)
+        guard_not_forced() []
+
+        i0 = stm_should_break_transaction()
+        guard_false(i0) []
+        jump()
+        """
+        expected = """
+        []
+        stm_hint_commit_soon()
+
+        stm_transaction_break(0)
+        guard_not_forced() []
+
+        i0 = stm_should_break_transaction()
+        guard_false(i0) []
+        jump()
+        """
+        self.optimize_loop(ops, expected, expected_preamble=preamble)
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
@@ -224,6 +224,13 @@
         # because of that
         self._record_stm_transaction_break(True)
 
+    @arguments()
+    def opimpl_stm_hint_commit_soon(self):
+        mi = self.metainterp
+        mi.history.record(rop.STM_HINT_COMMIT_SOON, [], None)
+        self.metainterp.heapcache.invalidate_caches(rop.STM_HINT_COMMIT_SOON,
+                                                    None, [])
+
     for _opimpl in ['int_add', 'int_sub', 'int_mul', 'int_floordiv', 'int_mod',
                     'int_lt', 'int_le', 'int_eq',
                     'int_ne', 'int_gt', 'int_ge',
diff --git a/rpython/jit/metainterp/resoperation.py b/rpython/jit/metainterp/resoperation.py
--- a/rpython/jit/metainterp/resoperation.py
+++ b/rpython/jit/metainterp/resoperation.py
@@ -495,6 +495,7 @@
     'VIRTUAL_REF/2',         # removed before it's passed to the backend
     'READ_TIMESTAMP/0',
     'STM_SHOULD_BREAK_TRANSACTION/0',
+    'STM_HINT_COMMIT_SOON/0',
     'MARK_OPAQUE_PTR/1b',
     # this one has no *visible* side effect, since the virtualizable
     # must be forced, however we need to execute it anyway
diff --git a/rpython/jit/metainterp/test/test_stm.py b/rpython/jit/metainterp/test/test_stm.py
--- a/rpython/jit/metainterp/test/test_stm.py
+++ b/rpython/jit/metainterp/test/test_stm.py
@@ -55,13 +55,17 @@
             rstm.jit_stm_should_break_transaction(True) # keep (True)
             rstm.jit_stm_should_break_transaction(True) # keep (True)
             rstm.jit_stm_should_break_transaction(False)
+            rstm.hint_commit_soon()
+            rstm.jit_stm_should_break_transaction(False) # keep
+            rstm.jit_stm_should_break_transaction(False)
             return 42
         res = self.interp_operations(g, [], translationoptions={"stm":True})
         assert res == 42
         self.check_operations_history({
-            'stm_transaction_break':1,
+            'stm_transaction_break':2,
+            'stm_hint_commit_soon':1,
             'stm_should_break_transaction':3,
-            'guard_not_forced':2,
+            'guard_not_forced':3,
             'guard_no_exception':1,
             'call_may_force':1})
 
diff --git a/rpython/rlib/rstm.py b/rpython/rlib/rstm.py
--- a/rpython/rlib/rstm.py
+++ b/rpython/rlib/rstm.py
@@ -49,7 +49,6 @@
     return llop.jit_stm_should_break_transaction(lltype.Bool,
                                                  if_there_is_no_other)
 
- at dont_look_inside
 def hint_commit_soon():
     """As the name says, just a hint. Maybe calling it
     several times in a row is more persuasive"""
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
@@ -438,7 +438,7 @@
     'stm_should_break_transaction':       LLOp(sideeffects=False),
     'stm_set_transaction_length':         LLOp(),
 
-    'stm_hint_commit_soon':   LLOp(),
+    'stm_hint_commit_soon':   LLOp(canrun=True),
 
     'stm_threadlocalref_get': LLOp(sideeffects=False),
     'stm_threadlocalref_set': LLOp(canmallocgc=True), # may allocate new array,
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
@@ -715,6 +715,9 @@
 def op_jit_stm_transaction_break_point():
     pass
 
+def op_stm_hint_commit_soon():
+    pass
+
 
 # ____________________________________________________________
 


More information about the pypy-commit mailing list