[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