Author: Armin Rigo <ar...@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', _______________________________________________ pypy-commit mailing list pypy-commit@python.org http://mail.python.org/mailman/listinfo/pypy-commit