Author: David Schneider <[email protected]>
Branch: arm-backed-float
Changeset: r44502:8585a9e5f393
Date: 2011-05-25 14:06 +0200
http://bitbucket.org/pypy/pypy/changeset/8585a9e5f393/
Log: (arigo, bivab) implement cond_call_gc_wb operation
diff --git a/pypy/jit/backend/arm/opassembler.py
b/pypy/jit/backend/arm/opassembler.py
--- a/pypy/jit/backend/arm/opassembler.py
+++ b/pypy/jit/backend/arm/opassembler.py
@@ -398,7 +398,44 @@
def emit_op_debug_merge_point(self, op, arglocs, regalloc, fcond):
return fcond
emit_op_jit_debug = emit_op_debug_merge_point
- emit_op_cond_call_gc_wb = emit_op_debug_merge_point
+
+ def emit_op_cond_call_gc_wb(self, op, arglocs, regalloc, fcond):
+ # Write code equivalent to write_barrier() in the GC: it checks
+ # a flag in the object at arglocs[0], and if set, it calls the
+ # function remember_young_pointer() from the GC. The two arguments
+ # to the call are in arglocs[:2]. The rest, arglocs[2:], contains
+ # registers that need to be saved and restored across the call.
+ 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)
+ return fcond
+ loc_base = arglocs[0]
+ self.mc.LDR_ri(r.ip.value, loc_base.value)
+ # calculate the shift value to rotate the ofs according to the ARM
+ # shifted imm values
+ # (4 - 0) * 4 & 0xF = 0
+ # (4 - 1) * 4 & 0xF = 12
+ # (4 - 2) * 4 & 0xF = 8
+ # (4 - 3) * 4 & 0xF = 4
+ ofs = (((4 - descr.jit_wb_if_flag_byteofs) * 4) & 0xF) << 8
+ ofs |= descr.jit_wb_if_flag_singlebyte
+ self.mc.TST_ri(r.ip.value, imm=ofs)
+
+ jz_location = self.mc.currpos()
+ self.mc.NOP()
+
+ # the following is supposed to be the slow path, so whenever possible
+ # we choose the most compact encoding over the most efficient one.
+ with saved_registers(self.mc, r.caller_resp, regalloc=regalloc):
+ remap_frame_layout(self, arglocs, [r.r0, r.r1], r.ip)
+ self.mc.BL(descr.get_write_barrier_fn(self.cpu))
+
+ # patch the JZ above
+ offset = self.mc.currpos() - jz_location
+ pmc = OverwritingBuilder(self.mc, jz_location, WORD)
+ pmc.ADD_ri(r.pc.value, r.pc.value, offset - PC_OFFSET, cond=c.EQ)
+
class FieldOpAssembler(object):
diff --git a/pypy/jit/backend/arm/regalloc.py b/pypy/jit/backend/arm/regalloc.py
--- a/pypy/jit/backend/arm/regalloc.py
+++ b/pypy/jit/backend/arm/regalloc.py
@@ -963,10 +963,22 @@
assert base_loc.is_reg()
return [value_loc, base_loc, imm(ofs_length)]
- prepare_op_cond_call_gc_wb = void
prepare_op_debug_merge_point = void
prepare_op_jit_debug = void
+ def prepare_op_cond_call_gc_wb(self, op, fcond):
+ assert op.result is None
+ args = op.getarglist()
+ loc_newvalue, box_newvalue = self._ensure_value_is_boxed(op.getarg(1),
args)
+ # ^^^ we force loc_newvalue in a reg (unless it's a Const),
+ # because it will be needed anyway by the following setfield_gc.
+ # It avoids loading it twice from the memory.
+ loc_base, box_base = self._ensure_value_is_boxed(op.getarg(0), args)
+ arglocs = [loc_base, loc_newvalue]
+ self.rm.possibly_free_vars([box_newvalue, box_base])
+ return arglocs
+
+
def prepare_op_force_token(self, op, fcond):
res_loc = self.force_allocate_reg(op.result)
self.possibly_free_var(op.result)
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit