[pypy-commit] pypy stmgc-c4: Add stm_transaction_break after CALL ops in stmrewrite. That way

Raemi noreply at buildbot.pypy.org
Mon Oct 14 16:03:49 CEST 2013


Author: Remi Meier <remi.meier at gmail.com>
Branch: stmgc-c4
Changeset: r67358:e22195363636
Date: 2013-10-14 16:03 +0200
http://bitbucket.org/pypy/pypy/changeset/e22195363636/

Log:	Add stm_transaction_break after CALL ops in stmrewrite. That way
	inevitable transactions causes by the calls will be much shorter and
	less likely to go on into atomic blocks.

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
@@ -45,6 +45,7 @@
     def rewrite(self, operations):
         # overridden method from parent class
         #
+        insert_transaction_break = False
         for op in operations:
             if not we_are_translated():
                 # only possible in tests:
@@ -81,6 +82,19 @@
             # ----------  pure operations, guards  ----------
             if op.is_always_pure() or op.is_guard() or op.is_ovf():
                 self.newops.append(op)
+
+                # insert a transaction break after call_release_gil
+                # in order to commit the inevitable transaction following
+                # it immediately
+                if (op.getopnum() == rop.GUARD_NOT_FORCED
+                    and insert_transaction_break):
+                    # insert transaction_break after GUARD after call
+                    self.newops.append(
+                        ResOperation(rop.STM_TRANSACTION_BREAK, [], None))
+                    insert_transaction_break = False
+                else:
+                    assert insert_transaction_break is False
+
                 continue
             # ----------  getfields  ----------
             if op.getopnum() in (rop.GETFIELD_GC,
@@ -104,9 +118,17 @@
                 continue
             # ----------  calls  ----------
             if op.is_call():
+                if (op.getopnum() == rop.CALL_MAY_FORCE or
+                    op.getopnum() == rop.CALL_ASSEMBLER or
+                    op.getopnum() == rop.CALL_RELEASE_GIL):
+                    # insert more transaction breaks after function
+                    # calls since they are likely to return as
+                    # inevitable transactions
+                    insert_transaction_break = True
+                    
                 if op.getopnum() == rop.CALL_RELEASE_GIL:
                     # self.fallback_inevitable(op)
-                    # done by assembler._release_gil_shadowstack()
+                    # is done by assembler._release_gil_shadowstack()
                     self.newops.append(op)
                 elif op.getopnum() == rop.CALL_ASSEMBLER:
                     self.handle_call_assembler(op)
@@ -158,6 +180,9 @@
             # ----------  fall-back  ----------
             self.fallback_inevitable(op)
             #
+
+        # call_XX without guard_not_forced?
+        assert not insert_transaction_break
         return self.newops
 
     def write_to_read_categories(self):
diff --git a/rpython/jit/backend/llsupport/test/test_stmrewrite.py b/rpython/jit/backend/llsupport/test/test_stmrewrite.py
--- a/rpython/jit/backend/llsupport/test/test_stmrewrite.py
+++ b/rpython/jit/backend/llsupport/test/test_stmrewrite.py
@@ -82,6 +82,7 @@
                 []
                 %s
                 call(123, descr=cd)
+                stm_transaction_break()
                 jump()
             """ % ("$INEV" if inev else "",), cd=calldescr)
     
@@ -94,6 +95,7 @@
             [p1, p2]
             cond_call_stm_b(p1, descr=P2Wdescr)
             setfield_gc(p1, p2, descr=tzdescr)
+            stm_transaction_break()
             jump()
         """)
 
@@ -109,6 +111,7 @@
             p3 = same_as(ConstPtr(t))
             cond_call_stm_b(p3, descr=P2Wdescr)
             setfield_gc(p3, p2, descr=tzdescr)
+            stm_transaction_break()
             jump()
             """, t=NULL)
 
@@ -133,6 +136,7 @@
             setfield_gc(p2, p0, descr=tzdescr)
             cond_call_stm_b(p1, descr=P2Rdescr)
             p4 = getfield_gc(p1, descr=tzdescr)
+            stm_transaction_break()
             jump()
             """, t=NULL)
 
@@ -155,6 +159,7 @@
             setfield_gc(p2, p0, descr=tzdescr)
             cond_call_stm_b(p1, descr=P2Rdescr)
             p5 = getfield_gc(p1, descr=tzdescr)
+            stm_transaction_break()
             jump()
         """)
 
@@ -178,6 +183,7 @@
             setfield_gc(p2, p0, descr=tzdescr)
             cond_call_stm_b(p1, descr=P2Rdescr)
             p4 = getfield_gc(p1, descr=tzdescr)
+            stm_transaction_break()
             jump()
         """)
 
@@ -203,6 +209,7 @@
             setfield_gc(p2, p0, descr=tzdescr)
             cond_call_stm_b(p1, descr=P2Rdescr)
             p4 = getfield_gc(p1, descr=tzdescr)
+            stm_transaction_break()
             jump()
         """
         for op in ops:
@@ -225,6 +232,7 @@
                                 descr=malloc_big_fixedsize_descr)
             cond_call_stm_b(p3, descr=P2Wdescr)
             setfield_gc(p3, p1, descr=tzdescr)
+            stm_transaction_break()
             jump(p2)
         """)
 
@@ -243,6 +251,7 @@
                                 %(tdescr.size)d, %(tdescr.tid)d, \
                                 descr=malloc_big_fixedsize_descr)
             p4 = getfield_gc(p1, descr=tzdescr)
+            stm_transaction_break()
             jump(p2)
         """)
             
@@ -258,6 +267,7 @@
                                 %(tdescr.size)d, %(tdescr.tid)d, \
                                 descr=malloc_big_fixedsize_descr)
             setfield_gc(p2, p1, descr=tzdescr)
+            stm_transaction_break()
             jump(p2)
         """)
 
@@ -273,6 +283,7 @@
             setfield_gc(p1, p2, descr=tzdescr)
             cond_call_stm_b(p3, descr=P2Wdescr)
             setfield_gc(p3, p4, descr=tzdescr)
+            stm_transaction_break()
             jump()
         """)
 
@@ -287,6 +298,7 @@
             cond_call_stm_b(p1, descr=P2Wdescr)
             setfield_gc(p1, p2, descr=tzdescr)
             setfield_gc(p1, i3, descr=tydescr)
+            stm_transaction_break()
             jump()
         """)
 
@@ -304,6 +316,7 @@
             label(p1, i3)
             cond_call_stm_b(p1, descr=P2Wdescr)
             setfield_gc(p1, i3, descr=tydescr)
+            stm_transaction_break()
             jump(p1)
         """)
 
@@ -314,6 +327,7 @@
             jump()
         """, """
             [i1, i2]
+            stm_transaction_break()
             jump()
         """)
 
@@ -333,7 +347,7 @@
             testcase = """
                 [i1, i2, p1, p2, f1]
                 %s
-                jump(i2)
+                finish()
             """ % op
             self.check_rewrite(testcase, testcase)
 
@@ -346,6 +360,7 @@
             [p1]
             cond_call_stm_b(p1, descr=P2Rdescr)
             p2 = getfield_gc(p1, descr=tzdescr)
+            stm_transaction_break()
             jump(p2)
         """)
 
@@ -361,6 +376,7 @@
             p3 = same_as(ConstPtr(t))
             cond_call_stm_b(p3, descr=P2Rdescr)
             p2 = getfield_gc(p3, descr=tzdescr)
+            stm_transaction_break()
             jump(p2)
         """, t=NULL)
         # XXX could do better: G2Rdescr
@@ -374,6 +390,7 @@
             [p1, i2]
             cond_call_stm_b(p1, descr=P2Rdescr)
             i3 = getarrayitem_gc(p1, i2, descr=adescr)
+            stm_transaction_break()
             jump(i3)
         """)
 
@@ -386,6 +403,7 @@
             [p1, i2]
             cond_call_stm_b(p1, descr=P2Rdescr)
             i3 = getinteriorfield_gc(p1, i2, descr=adescr)
+            stm_transaction_break()
             jump(i3)
         """)
 
@@ -400,6 +418,7 @@
             cond_call_stm_b(p1, descr=P2Rdescr)
             p2 = getfield_gc(p1, descr=tzdescr)
             i2 = getfield_gc(p1, descr=tydescr)
+            stm_transaction_break()
             jump(p2, i2)
         """)
 
@@ -415,6 +434,7 @@
             p2 = getfield_gc(p1, descr=tzdescr)
             cond_call_stm_b(p2, descr=P2Rdescr)
             i2 = getfield_gc(p2, descr=tydescr)
+            stm_transaction_break()
             jump(p2, i2)
         """)
 
@@ -434,6 +454,7 @@
             i2 = int_add(i1, 1)
             cond_call_stm_b(p1, descr=P2Wdescr)
             setfield_gc(p1, i2, descr=tydescr)
+            stm_transaction_break()
             jump(p1)
         """)
 
@@ -448,6 +469,7 @@
             cond_call_stm_b(p1, descr=P2Wdescr)
             setfield_gc(p1, 123, descr=tydescr)
             p2 = getfield_gc(p1, descr=tzdescr)
+            stm_transaction_break()
             jump(p2)
         """)
 
@@ -463,6 +485,7 @@
                                 %(tdescr.size)d, %(tdescr.tid)d, \
                                 descr=malloc_big_fixedsize_descr)
             p2 = getfield_gc(p1, descr=tzdescr)
+            stm_transaction_break()
             jump(p2)
         """)
 
@@ -488,6 +511,7 @@
             call(p2, descr=calldescr1)
             cond_call_stm_b(p1, descr=P2Wdescr)
             setfield_gc(p1, 5, descr=tydescr)
+            stm_transaction_break()
             jump(p2)
         """, calldescr1=calldescr1)
 
@@ -504,6 +528,7 @@
             i3 = getfield_raw(i1, descr=tydescr)
             keepalive(i3)
             i4 = getfield_raw(i2, descr=tydescr)
+            stm_transaction_break()
             jump(i3, i4)
         """)
 
@@ -519,6 +544,7 @@
         """, """
             [i1]
             i2 = getfield_raw(i1, descr=fdescr)
+            stm_transaction_break()
             jump(i2)
         """, fdescr=fdescr)
 
@@ -536,6 +562,7 @@
             label(i1, i2, i3)
             $INEV
             i4 = getfield_raw(i2, descr=tydescr)
+            stm_transaction_break()
             jump(i3, i4)
         """)
 
@@ -550,6 +577,7 @@
             $INEV
             i3 = getarrayitem_raw(i1, 5, descr=adescr)
             i4 = getarrayitem_raw(i2, i3, descr=adescr)
+            stm_transaction_break()
             jump(i3, i4)
         """)
 
@@ -565,6 +593,7 @@
             setarrayitem_gc(p1, i1, p2, descr=adescr)
             cond_call_stm_b(p3, descr=P2Wdescr)
             setarrayitem_gc(p3, i3, p4, descr=adescr)
+            stm_transaction_break()
             jump()
         """)
 
@@ -581,6 +610,7 @@
             setarrayitem_gc(p1, i2, p2, descr=adescr)
             i4 = read_timestamp()
             setarrayitem_gc(p1, i3, p3, descr=adescr)
+            stm_transaction_break()
             jump()
         """)
 
@@ -597,6 +627,7 @@
             setinteriorfield_gc(p1, i2, p2, descr=adescr)
             i4 = read_timestamp()
             setinteriorfield_gc(p1, i3, p3, descr=adescr)
+            stm_transaction_break()
             jump()
         """)
 
@@ -611,11 +642,35 @@
             cond_call_stm_b(p1, descr=P2Wdescr)
             strsetitem(p1, i2, i3)
             unicodesetitem(p1, i2, i3)
+            stm_transaction_break()
             jump()
         """)
         py.test.skip("XXX not really right: should instead be an assert "
                      "that p1 is already a W")
 
+    def test_call_release_gil(self):
+        T = rffi.CArrayPtr(rffi.TIME_T)
+        calldescr2 = get_call_descr(self.gc_ll_descr, [T], rffi.TIME_T)
+        self.check_rewrite("""
+            [i1, i2, i3, p7]
+            setfield_gc(p7, 10, descr=tydescr)
+            call_release_gil(123, descr=calldescr2)
+            guard_not_forced() []
+            setfield_gc(p7, 20, descr=tydescr)
+            jump(i2, p7)
+        """, """
+            [i1, i2, i3, p7]
+            cond_call_stm_b(p7, descr=P2Wdescr)
+            setfield_gc(p7, 10, descr=tydescr)
+            call_release_gil(123, descr=calldescr2)
+            guard_not_forced() []
+            stm_transaction_break()
+            cond_call_stm_b(p7, descr=P2Wdescr)
+            setfield_gc(p7, 20, descr=tydescr)
+            stm_transaction_break()
+            jump(i2, p7)
+        """, calldescr2=calldescr2)
+        
     def test_fallback_to_inevitable(self):
         T = rffi.CArrayPtr(rffi.TIME_T)
         calldescr2 = get_call_descr(self.gc_ll_descr, [T], rffi.TIME_T)
@@ -623,7 +678,6 @@
             "setfield_raw(i1, i2, descr=tydescr)",
             "setarrayitem_raw(i1, i2, i3, descr=tydescr)",
             "setinteriorfield_raw(i1, i2, i3, descr=adescr)",
-            "call_release_gil(123, descr=calldescr2)",
             "escape(i1)",    # a generic unknown operation
             ]
         for op in oplist:
@@ -641,6 +695,7 @@
                 %s
                 cond_call_stm_b(p7, descr=P2Wdescr)
                 setfield_gc(p7, 20, descr=tydescr)
+                stm_transaction_break()
                 jump(i2, p7)
             """ % op, calldescr2=calldescr2)
 
@@ -654,6 +709,7 @@
             cond_call_stm_b(p2, descr=P2Wdescr)
             cond_call_stm_b(p1, descr=P2Rdescr)
             copystrcontent(p1, p2, i1, i2, i3)
+            stm_transaction_break()
             jump()
         """)
 
@@ -675,6 +731,7 @@
                 setfield_gc(p1, 10, descr=tydescr)
                 %s
                 setfield_gc(p1, 20, descr=tydescr)
+                stm_transaction_break()
                 jump(p1)
             """ % op)
 
@@ -685,26 +742,33 @@
         T = rffi.CArrayPtr(rffi.TIME_T)
         calldescr2 = get_call_descr(self.gc_ll_descr, [T], rffi.TIME_T,
                                     fakeextrainfo())
-        for op in ["call(123, descr=calldescr2)",
-                   "call_assembler(123, descr=casmdescr)",
-                   "call_may_force(123, descr=calldescr2)",
-                   "call_loopinvariant(123, descr=calldescr2)",
-                   ]:
+        for op, guarded in [
+                ("call(123, descr=calldescr2)", False),
+                ("call_assembler(123, descr=casmdescr)", True),
+                ("call_may_force(123, descr=calldescr2)", True),
+                ("call_loopinvariant(123, descr=calldescr2)", False),
+                ]:
+            guard = "guard_not_forced() []" if guarded else ""
+            tr_break = "stm_transaction_break()" if guarded else ""
             self.check_rewrite("""
                 [p1]
                 setfield_gc(p1, 10, descr=tydescr)
                 %s
+                %s
                 setfield_gc(p1, 20, descr=tydescr)
                 jump(p1)
-            """ % op, """
+            """ % (op, guard), """
                 [p1]
                 cond_call_stm_b(p1, descr=P2Wdescr)
                 setfield_gc(p1, 10, descr=tydescr)
                 %s
+                %s
+                %s
                 cond_call_stm_b(p1, descr=P2Wdescr)
                 setfield_gc(p1, 20, descr=tydescr)
+                stm_transaction_break()
                 jump(p1)
-            """ % op, calldescr2=calldescr2)
+            """ % (op, guard, tr_break), calldescr2=calldescr2)
 
     def test_ptr_eq_null(self):
         self.check_rewrite("""
@@ -714,6 +778,7 @@
         """, """
             [p1, p2]
             i1 = ptr_eq(p1, NULL)
+            stm_transaction_break()
             jump(i1)
         """)
 
@@ -725,6 +790,7 @@
         """, """
             [p1, p2]
             i1 = ptr_eq(p1, p2)
+            stm_transaction_break()
             jump(i1)
         """)
 
@@ -736,6 +802,7 @@
         """, """
             [p1, p2]
             i1 = instance_ptr_eq(p1, p2)
+            stm_transaction_break()
             jump(i1)
         """)
 
@@ -747,6 +814,7 @@
         """, """
             [p1, p2]
             i1 = ptr_ne(p1, p2)
+            stm_transaction_break()
             jump(i1)
         """)
 
@@ -758,6 +826,7 @@
         """, """
             [p1, p2]
             i1 = instance_ptr_ne(p1, p2)
+            stm_transaction_break()
             jump(i1)
         """)
 


More information about the pypy-commit mailing list