[pypy-commit] pypy stm-jit: in-progress
arigo
noreply at buildbot.pypy.org
Sat Aug 11 08:46:17 CEST 2012
Author: Armin Rigo <arigo at tunes.org>
Branch: stm-jit
Changeset: r56702:92bc41fa2e6a
Date: 2012-08-10 18:15 +0200
http://bitbucket.org/pypy/pypy/changeset/92bc41fa2e6a/
Log: in-progress
diff --git a/pypy/jit/backend/llsupport/stmrewrite.py b/pypy/jit/backend/llsupport/stmrewrite.py
--- a/pypy/jit/backend/llsupport/stmrewrite.py
+++ b/pypy/jit/backend/llsupport/stmrewrite.py
@@ -112,9 +112,13 @@
self.newops.append(op)
return
lst[0] = self.unconstifyptr(lst[0])
- self.newops.append(OP_STM_READ_BEFORE)
+ write_barrier_descr = self.gc_ll_descr.write_barrier_descr
+ op_before = ResOperation(rop.STM_READ_BEFORE, [lst[0]], None,
+ descr=write_barrier_descr)
+ op_after = ResOperation(rop.STM_READ_AFTER, [lst[0]], None)
+ self.newops.append(op_before)
self.newops.append(op.copy_and_change(op.getopnum(), args=lst))
- self.newops.append(OP_STM_READ_AFTER)
+ self.newops.append(op_after)
def handle_copystrcontent(self, op):
# first, a write barrier on the target string
@@ -133,7 +137,3 @@
self.newops.append(op1)
self.always_inevitable = True
self.newops.append(op)
-
-
-OP_STM_READ_BEFORE = ResOperation(rop.STM_READ_BEFORE, [], None)
-OP_STM_READ_AFTER = ResOperation(rop.STM_READ_AFTER, [], None)
diff --git a/pypy/jit/backend/llsupport/test/test_stmrewrite.py b/pypy/jit/backend/llsupport/test/test_stmrewrite.py
--- a/pypy/jit/backend/llsupport/test/test_stmrewrite.py
+++ b/pypy/jit/backend/llsupport/test/test_stmrewrite.py
@@ -156,9 +156,9 @@
jump(p2)
""", """
[p1]
- stm_read_before()
+ stm_read_before(p1, descr=wbdescr)
p2 = getfield_gc(p1, descr=tzdescr)
- stm_read_after()
+ stm_read_after(p1)
jump(p2)
""")
@@ -170,9 +170,9 @@
""", """
[p1]
p3 = same_as(ConstPtr(t))
- stm_read_before()
+ stm_read_before(p3, descr=wbdescr)
p2 = getfield_gc(p3, descr=tzdescr)
- stm_read_after()
+ stm_read_after(p3)
jump(p2)
""")
@@ -183,9 +183,9 @@
jump(i3)
""", """
[p1, i2]
- stm_read_before()
+ stm_read_before(p1, descr=wbdescr)
i3 = getarrayitem_gc(p1, i2, descr=adescr)
- stm_read_after()
+ stm_read_after(p1)
jump(i3)
""")
@@ -196,9 +196,9 @@
jump(i3)
""", """
[p1, i2]
- stm_read_before()
+ stm_read_before(p1, descr=wbdescr)
i3 = getinteriorfield_gc(p1, i2, descr=adescr)
- stm_read_after()
+ stm_read_after(p1)
jump(i3)
""")
@@ -211,10 +211,10 @@
jump(p2, i2)
""", """
[p1]
- stm_read_before()
+ stm_read_before(p1, descr=wbdescr)
p2 = getfield_gc(p1, descr=tzdescr)
i2 = getfield_gc(p1, descr=tydescr)
- stm_read_after()
+ stm_read_after(p1)
jump(p2, i2)
""")
@@ -226,12 +226,12 @@
jump(p2, i2)
""", """
[p1]
- stm_read_before()
+ stm_read_before(p1, descr=wbdescr)
p2 = getfield_gc(p1, descr=tzdescr)
- stm_read_after()
- stm_read_before()
+ stm_read_after(p1)
+ stm_read_before(p2, descr=wbdescr)
i2 = getfield_gc(p2, descr=tydescr)
- stm_read_after()
+ stm_read_after(p2)
jump(p2, i2)
""")
@@ -245,10 +245,10 @@
jump(p2, i2)
""", """
[p1]
- stm_read_before()
+ stm_read_before(p1, descr=wbdescr)
p2 = getfield_gc(p1, descr=tzdescr)
i2 = getfield_gc(p1, descr=tydescr)
- stm_read_after()
+ stm_read_after(p1)
guard_nonnull(p2) [i1]
jump(p2, i2)
""")
@@ -262,13 +262,13 @@
jump(p2, i2)
""", """
[p1]
- stm_read_before()
+ stm_read_before(p1, descr=wbdescr)
p2 = getfield_gc(p1, descr=tzdescr)
- stm_read_after()
+ stm_read_after(p1)
call(123)
- stm_read_before()
+ stm_read_before(p1, descr=wbdescr)
i2 = getfield_gc(p1, descr=tydescr)
- stm_read_after()
+ stm_read_after(p1)
jump(p2, i2)
""")
@@ -490,9 +490,9 @@
""", """
[p1, p2, i1, i2, i3]
cond_call_gc_wb(p2, 0, descr=wbdescr)
- stm_read_before()
+ stm_read_before(p1, descr=wbdescr)
copystrcontent(p1, p2, i1, i2, i3)
- stm_read_after()
+ stm_read_after(p1)
jump()
""")
diff --git a/pypy/jit/backend/x86/assembler.py b/pypy/jit/backend/x86/assembler.py
--- a/pypy/jit/backend/x86/assembler.py
+++ b/pypy/jit/backend/x86/assembler.py
@@ -2557,6 +2557,49 @@
genop_discard_cond_call_gc_wb_array = genop_discard_cond_call_gc_wb
+ def genop_discard_stm_read_before(self, op, arglocs):
+ descr = op.getdescr()
+ if we_are_translated():
+ cls = self.cpu.gc_ll_descr.has_write_barrier_class()
+ assert cls is not None and isinstance(descr, cls)
+ #
+ loc, loc_version = arglocs
+ assert loc is edx
+ assert loc_version is eax
+ # XXX hard-coded for now: the version is the second WORD in objects
+ self.mc.MOV_rm(loc_version.value, (loc.value, WORD))
+ #
+ mask = descr.jit_wb_if_flag_singlebyte # test GCFLAG_GLOBAL
+ self.mc.TEST8_mi((loc.value, descr.jit_wb_if_flag_byteofs), mask)
+ self.mc.J_il8(rx86.Conditions['Z'], 0) # patched later
+ jz_location = self.mc.get_relative_pos()
+
+ # call interface: 'loc' is passed in edx; 'loc_version' is
+ # returned in eax.
+ self.mc.CALL(imm(self.stm_read_before_slowpath))
+
+ # patch the JZ above
+ offset = self.mc.get_relative_pos() - jz_location
+ assert 0 < offset <= 127
+ self.mc.overwrite(jz_location-1, chr(offset))
+
+ def genop_discard_stm_read_after(self, op, arglocs):
+ loc, loc_version, loc_position = arglocs
+ assert isinstance(loc, RegLoc)
+ assert isinstance(loc_version, RegLoc)
+ assert isinstance(loc_position, ImmedLoc)
+ # XXX hard-coded for now: the version is the second WORD in objects
+ self.mc.CMP_rm(loc_version.value, (loc.value, WORD))
+ #
+ # the negative offset of the conditional jump
+ offset = loc_position.value - (self.mc.get_relative_pos() + 2)
+ assert offset < 0
+ if offset >= -128:
+ self.mc.J_il8(rx86.Conditions['NE'], offset)
+ else:
+ # doesn't fit in one byte, use the 4-bytes variant
+ XXX
+
def not_implemented_op_discard(self, op, arglocs):
not_implemented("not implemented operation: %s" % op.getopname())
diff --git a/pypy/jit/backend/x86/regalloc.py b/pypy/jit/backend/x86/regalloc.py
--- a/pypy/jit/backend/x86/regalloc.py
+++ b/pypy/jit/backend/x86/regalloc.py
@@ -1534,6 +1534,24 @@
def consider_stm_read_before(self, op):
self.xrm.before_call(save_all_regs=True)
self.rm.before_call(save_all_regs=True)
+ self.stm_read_before_position = self.assembler.mc.get_relative_pos()
+ args = op.getarglist()
+ loc = self.rm.make_sure_var_in_reg(args[0], selected_reg=edx)
+ tmpbox_version = TempBox()
+ loc_version = self.rm.force_allocate_reg(tmpbox_version,
+ selected_reg=eax)
+ self.PerformDiscard(op, [loc, loc_version])
+ # tmpbox_version freed only in stm_read_after
+ self.stm_tmpbox_version = tmpbox_version
+
+ def consider_stm_read_after(self, op):
+ tmpbox_version = self.stm_tmpbox_version
+ loc = self.rm.make_sure_var_in_reg(op.getarg(0))
+ loc_version = self.rm.make_sure_var_in_reg(tmpbox_version)
+ loc_position = imm(self.stm_read_before_position)
+ self.PerformDiscard(op, [loc, loc_version, loc_position])
+ self.rm.possibly_free_var(op.getarg(0))
+ self.rm.possibly_free_var(tmpbox_version)
def not_implemented_op(self, op):
not_implemented("not implemented operation: %s" % op.getopname())
diff --git a/pypy/jit/backend/x86/test/test_stm_integration.py b/pypy/jit/backend/x86/test/test_stm_integration.py
--- a/pypy/jit/backend/x86/test/test_stm_integration.py
+++ b/pypy/jit/backend/x86/test/test_stm_integration.py
@@ -11,9 +11,9 @@
def test_stm_read_before_spills_all(self):
# for now, stm_read_before() first spills all registers
ops = '''
- [i1, i2]
+ [i1, i2, p1]
i3 = int_add(i1, i2)
- stm_read_before()
+ stm_read_before(p1, descr=wbdescr)
escape(i3) # assert i3 was spilled
finish(i3)
'''
diff --git a/pypy/jit/metainterp/resoperation.py b/pypy/jit/metainterp/resoperation.py
--- a/pypy/jit/metainterp/resoperation.py
+++ b/pypy/jit/metainterp/resoperation.py
@@ -503,8 +503,8 @@
'QUASIIMMUT_FIELD/1d', # [objptr], descr=SlowMutateDescr
'RECORD_KNOWN_CLASS/2', # [objptr, clsptr]
'KEEPALIVE/1',
- 'STM_READ_BEFORE/0', # inserted by backend/llsupport/stmrewrite
- 'STM_READ_AFTER/0', # inserted by backend/llsupport/stmrewrite
+ 'STM_READ_BEFORE/1d', # inserted by backend/llsupport/stmrewrite
+ 'STM_READ_AFTER/1', # inserted by backend/llsupport/stmrewrite
'_CANRAISE_FIRST', # ----- start of can_raise operations -----
'_CALL_FIRST',
More information about the pypy-commit
mailing list