[pypy-commit] pypy stm-jit: in-progress. Missing tests :-(
arigo
noreply at buildbot.pypy.org
Sun Aug 5 18:39:58 CEST 2012
Author: Armin Rigo <arigo at tunes.org>
Branch: stm-jit
Changeset: r56586:4a547da831fd
Date: 2012-08-05 16:22 +0200
http://bitbucket.org/pypy/pypy/changeset/4a547da831fd/
Log: in-progress. Missing tests :-(
diff --git a/pypy/jit/backend/llsupport/gc.py b/pypy/jit/backend/llsupport/gc.py
--- a/pypy/jit/backend/llsupport/gc.py
+++ b/pypy/jit/backend/llsupport/gc.py
@@ -22,6 +22,7 @@
# ____________________________________________________________
class GcLLDescription(GcCache):
+ stm = False
def __init__(self, gcdescr, translator=None, rtyper=None):
GcCache.__init__(self, translator is not None, rtyper)
@@ -580,11 +581,12 @@
class WriteBarrierDescr(AbstractDescr):
def __init__(self, gc_ll_descr):
self.llop1 = gc_ll_descr.llop1
- if not gc_ll_descr.stm:
+ self.returns_modified_object = gc_ll_descr.stm
+ if not self.returns_modified_object:
self.WB_FUNCPTR = lltype.Ptr(lltype.FuncType(
[llmemory.Address], lltype.Void))
else:
- self.WB_STM_FUNCPTR = lltype.Ptr(lltype.FuncType(
+ self.WB_FUNCPTR_MOD = lltype.Ptr(lltype.FuncType(
[llmemory.Address], llmemory.Address))
self.fielddescr_tid = gc_ll_descr.fielddescr_tid
#
@@ -618,9 +620,16 @@
while value[i] == '\x00': i += 1
return (i, struct.unpack('b', value[i])[0])
- def get_write_barrier_fn(self, cpu):
+ def get_write_barrier_fn(self, cpu, returns_modified_object=False):
+ # must pass in 'self.returns_modified_object', to make sure that
+ # the callers are fixed for this case
+ assert returns_modified_object == self.returns_modified_object
+ if returns_modified_object:
+ FUNCTYPE = self.WB_FUNCPTR_MOD
+ else:
+ FUNCTYPE = self.WB_FUNCPTR
llop1 = self.llop1
- funcptr = llop1.get_write_barrier_failing_case(self.WB_FUNCPTR)
+ funcptr = llop1.get_write_barrier_failing_case(FUNCTYPE)
funcaddr = llmemory.cast_ptr_to_adr(funcptr)
return cpu.cast_adr_to_int(funcaddr)
@@ -630,6 +639,7 @@
funcptr = llop1.get_write_barrier_from_array_failing_case(
self.WB_FUNCPTR)
funcaddr = llmemory.cast_ptr_to_adr(funcptr)
+ assert not (funcaddr and self.returns_modified_object)
return cpu.cast_adr_to_int(funcaddr) # this may return 0
def has_write_barrier_from_array(self, cpu):
@@ -646,7 +656,10 @@
GcLLDescription.__init__(self, gcdescr, translator, rtyper)
self.translator = translator
self.llop1 = llop1
- self.stm = translator.config.translation.stm
+ try:
+ self.stm = translator.config.translation.stm
+ except AttributeError:
+ pass # keep the default of False
if really_not_translated:
assert not self.translate_support_code # but half does not work
self._initialize_for_tests()
diff --git a/pypy/jit/backend/llsupport/rewrite.py b/pypy/jit/backend/llsupport/rewrite.py
--- a/pypy/jit/backend/llsupport/rewrite.py
+++ b/pypy/jit/backend/llsupport/rewrite.py
@@ -274,8 +274,8 @@
v = op.getarg(1)
if isinstance(v, BoxPtr) or (isinstance(v, ConstPtr) and
bool(v.value)): # store a non-NULL
+ op = self.prepare_write_barrier(op, rop.SETFIELD_RAW)
self.gen_write_barrier(op.getarg(0), v)
- op = op.copy_and_change(rop.SETFIELD_RAW)
self.newops.append(op)
def handle_write_barrier_setinteriorfield(self, op):
@@ -285,8 +285,8 @@
v = op.getarg(2)
if isinstance(v, BoxPtr) or (isinstance(v, ConstPtr) and
bool(v.value)): # store a non-NULL
+ op = self.prepare_write_barrier(op, rop.SETINTERIORFIELD_RAW)
self.gen_write_barrier(op.getarg(0), v)
- op = op.copy_and_change(rop.SETINTERIORFIELD_RAW)
self.newops.append(op)
def handle_write_barrier_setarrayitem(self, op):
@@ -296,11 +296,21 @@
v = op.getarg(2)
if isinstance(v, BoxPtr) or (isinstance(v, ConstPtr) and
bool(v.value)): # store a non-NULL
+ op = self.prepare_write_barrier(op, rop.SETARRAYITEM_RAW)
self.gen_write_barrier_array(op.getarg(0),
op.getarg(1), v)
- op = op.copy_and_change(rop.SETARRAYITEM_RAW)
self.newops.append(op)
+ def prepare_write_barrier(self, op, newopnum):
+ write_barrier_descr = self.gc_ll_descr.write_barrier_descr
+ args = op.getarglist()
+ if (write_barrier_descr.returns_modified_object and
+ isinstance(op.getarg(0), ConstPtr)):
+ v_box = BoxPtr()
+ self.newops.append(ResOperation(rop.SAME_AS, [args[0]], v_box))
+ args[0] = v_box
+ return op.copy_and_change(opnum=newopnum, args=args)
+
def gen_write_barrier(self, v_base, v_value):
write_barrier_descr = self.gc_ll_descr.write_barrier_descr
args = [v_base, v_value]
@@ -313,6 +323,7 @@
# If we know statically the length of 'v', and it is not too
# big, then produce a regular write_barrier. If it's unknown or
# too big, produce instead a write_barrier_from_array.
+ assert not write_barrier_descr.returns_modified_object
LARGE = 130
length = self.known_lengths.get(v_base, LARGE)
if length >= LARGE:
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
@@ -351,12 +351,17 @@
rawstart = mc.materialize(self.cpu.asmmemmgr, [])
self.stack_check_slowpath = rawstart
+ def _wb_returns_modified_object(self):
+ descr = self.cpu.gc_ll_descr.write_barrier_descr
+ return descr.returns_modified_object
+
def _build_wb_slowpath(self, withcards, withfloats=False):
descr = self.cpu.gc_ll_descr.write_barrier_descr
if descr is None:
return
if not withcards:
- func = descr.get_write_barrier_fn(self.cpu)
+ func = descr.get_write_barrier_fn(self.cpu,
+ descr.returns_modified_object)
else:
if descr.jit_wb_cards_set == 0:
return
@@ -402,6 +407,9 @@
mc.MOV_rs(edi.value, (frame_size - 1) * WORD)
mc.CALL(imm(func))
#
+ if descr.returns_modified_object:
+ mc.MOV_sr(correct_esp_by, eax.value)
+ #
if withcards:
# A final TEST8 before the RET, for the caller. Careful to
# not follow this instruction with another one that changes
@@ -422,7 +430,10 @@
# ADD esp, correct_esp_by --- but cannot use ADD, because
# of its effects on the CPU flags
mc.LEA_rs(esp.value, correct_esp_by)
- mc.RET16_i(WORD)
+ if not descr.returns_modified_object:
+ mc.RET16_i(WORD)
+ else:
+ mc.RET() # and leave the modified object in [ESP+0]
#
rawstart = mc.materialize(self.cpu.asmmemmgr, [])
self.wb_slowpath[withcards + 2 * withfloats] = rawstart
@@ -2480,6 +2491,16 @@
self.mc.PUSH(loc_base)
self.mc.CALL(imm(self.wb_slowpath[helper_num]))
+ if self._wb_returns_modified_object():
+ # the value at [ESP] is not popped in this case, but possibly
+ # updated. We have to use it to update the register at loc_base
+ assert isinstance(loc_base, RegLoc)
+ self.mc.POP_r(loc_base.value)
+ # also update the copy of the same value in the stack, if any
+ loc_base_2 = self._regalloc.fm.get(op.getarg(0))
+ if loc_base_2 is not None:
+ self.regalloc_mov(loc_base, loc_base_2)
+
if card_marking:
# The helper ends again with a check of the flag in the object.
# So here, we can simply write again a 'JNS', which will be
More information about the pypy-commit
mailing list