[pypy-commit] pypy stmgc-c7: read barriers

arigo noreply at buildbot.pypy.org
Sat Mar 22 12:04:21 CET 2014


Author: Armin Rigo <arigo at tunes.org>
Branch: stmgc-c7
Changeset: r70160:8c9539ab0df6
Date: 2014-03-22 12:03 +0100
http://bitbucket.org/pypy/pypy/changeset/8c9539ab0df6/

Log:	read barriers

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
@@ -17,6 +17,7 @@
     def __init__(self, *args):
         GcRewriterAssembler.__init__(self, *args)
         self.always_inevitable = False
+        self.read_barrier_applied = {}
 
     def other_operation(self, op):
         opnum = op.getopnum()
@@ -103,28 +104,23 @@
 
     def next_op_may_be_in_new_transaction(self):
         self.always_inevitable = False
+        self.read_barrier_applied.clear()
 
     def handle_getfields(self, op):
-        opnum = op.getopnum()
-        descr = op.getdescr()
-        target_category = 'R'
-        # XXX: review:
-        # if opnum == rop.GETFIELD_GC:
-        #     assert isinstance(descr, FieldDescr)
-        #     if descr.is_immutable():
-        #         target_category = 'I'
-        # elif opnum == rop.GETINTERIORFIELD_GC:
-        #     assert isinstance(descr, InteriorFieldDescr)
-        #     if descr.is_immutable():
-        #         target_category = 'I'
-        # elif opnum == rop.GETARRAYITEM_GC:
-        #     assert isinstance(descr, ArrayDescr)
-        #     if descr.is_immutable():
-        #         target_category = 'I'
-                
-        self.handle_category_operations(op, target_category)
+        # XXX missing optimitations: the placement of stm_read should
+        # ideally be delayed for a bit longer after the getfields; if we
+        # group together several stm_reads then we can save one
+        # instruction; if delayed over a cond_call_gc_wb then we can
+        # omit the stm_read completely; ...
+        self.newops.append(op)
+        v_ptr = op.getarg(0)
+        if (v_ptr not in self.read_barrier_applied and
+            v_ptr not in self.write_barrier_applied):
+            op1 = ResOperation(rop.STM_READ, [v_ptr], None)
+            self.newops.append(op1)
+            self.read_barrier_applied[v_ptr] = None
 
-    
+
     def handle_setfields(self, op):
         opnum = op.getopnum()
         descr = op.getdescr()
@@ -174,7 +170,6 @@
         self.newops.append(op1)
 
     def fallback_inevitable(self, op):
-        self.known_category.clear()
         if not self.always_inevitable:
             self.emitting_an_operation_that_can_collect()
             self._do_stm_call('stm_try_inevitable', [], None)
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
@@ -20,6 +20,10 @@
     words.append('CALL_MALLOC_GC')
     words.append('COND_CALL_GC_WB')
     words.append('COND_CALL_GC_WB_ARRAY')
+    # these are pure, and can be done without any read barrier
+    words.append('ARRAYLEN_GC')
+    words.append('GETFIELD_GC_PURE')
+    words.append('GETARRAYITEM_GC_PURE')
     #
     words = set(words)
     missing = []
@@ -85,7 +89,7 @@
                 call(123, descr=cd)
                 jump()
             """ % ("$INEV" if inev else "",), cd=calldescr)
-    
+
     def test_rewrite_one_setfield_gc(self):
         self.check_rewrite("""
             [p1, p2]
@@ -93,9 +97,8 @@
             jump()
         """, """
             [p1, p2]
-            cond_call_stm_b(p1, descr=A2Wdescr)
+            cond_call_gc_wb(p1, descr=wbdescr)
             setfield_gc(p1, p2, descr=tzdescr)
-            
             jump()
         """)
 
@@ -108,13 +111,42 @@
             jump()
         """, """
             [p1, p2]
-            p3 = same_as(ConstPtr(t))
-            cond_call_stm_b(p3, descr=A2Wdescr)
-            setfield_gc(p3, p2, descr=tzdescr)
-            
+            cond_call_gc_wb(ConstPtr(t), descr=wbdescr)
+            setfield_gc(ConstPtr(t), p2, descr=tzdescr)
             jump()
             """, t=NULL)
 
+    def test_rewrite_one_getfield_gc(self):
+        self.check_rewrite("""
+            [p1]
+            p2 = getfield_gc(p1, descr=tzdescr)
+            jump()
+        """, """
+            [p1]
+            p2 = getfield_gc(p1, descr=tzdescr)
+            stm_read(p1)
+            jump()
+        """)
+
+    def test_rewrite_several_getfield_gc(self):
+        self.check_rewrite("""
+            [p1, p2]
+            p3 = getfield_gc(p1, descr=tzdescr)
+            p4 = getfield_gc(p1, descr=tzdescr)
+            p5 = getfield_gc(p2, descr=tzdescr)
+            p6 = getfield_gc(p1, descr=tzdescr)
+            jump()
+        """, """
+            [p1, p2]
+            p3 = getfield_gc(p1, descr=tzdescr)
+            stm_read(p1)
+            p4 = getfield_gc(p1, descr=tzdescr)
+            p5 = getfield_gc(p2, descr=tzdescr)
+            stm_read(p2)
+            p6 = getfield_gc(p1, descr=tzdescr)
+            jump()
+        """)
+
     def test_invalidate_read_status_after_write_to_constptr(self):
         TP = lltype.GcArray(lltype.Signed)
         NULL = lltype.cast_opaque_ptr(llmemory.GCREF, lltype.nullptr(TP))
diff --git a/rpython/jit/metainterp/executor.py b/rpython/jit/metainterp/executor.py
--- a/rpython/jit/metainterp/executor.py
+++ b/rpython/jit/metainterp/executor.py
@@ -346,6 +346,7 @@
                          rop.CALL_MALLOC_NURSERY_VARSIZE,
                          rop.CALL_MALLOC_NURSERY_VARSIZE_FRAME,
                          rop.LABEL,
+                         rop.STM_READ,
                          ):      # list of opcodes never executed by pyjitpl
                 continue
             raise AssertionError("missing %r" % (key,))
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
@@ -511,6 +511,7 @@
     'RECORD_KNOWN_CLASS/2',   # [objptr, clsptr]
     'KEEPALIVE/1',
     'STM_TRANSACTION_BREAK/1',
+    'STM_READ/1',
 
     '_CANRAISE_FIRST', # ----- start of can_raise operations -----
     '_CALL_FIRST',


More information about the pypy-commit mailing list