Author: David Schneider <[email protected]>
Branch: jitframe-on-heap
Changeset: r60692:c4e0750d01c6
Date: 2013-01-29 17:00 +0100
http://bitbucket.org/pypy/pypy/changeset/c4e0750d01c6/
Log: port most of the latest changes to arm, regarding among other things
gcmap initialization
diff --git a/rpython/jit/backend/arm/assembler.py
b/rpython/jit/backend/arm/assembler.py
--- a/rpython/jit/backend/arm/assembler.py
+++ b/rpython/jit/backend/arm/assembler.py
@@ -115,7 +115,8 @@
self.set_debug(have_debug_prints())
debug_stop('jit-backend-counts')
# when finishing, we only have one value at [0], the rest dies
- self.gcmap_for_finish = lltype.malloc(jitframe.GCMAP, 1, zero=True)
+ self.gcmap_for_finish = lltype.malloc(jitframe.GCMAP, 1,
+ flavor='raw', immortal=True)
self.gcmap_for_finish[0] = r_uint(1)
def setup_failure_recovery(self):
@@ -502,6 +503,8 @@
positions[i] = v * WORD
# write down the positions of locs
guardtok.faildescr.rd_locs = positions
+ # we want the descr to keep alive
+ guardtok.faildescr.rd_loop_token = self.current_clt
self.regalloc_push(imm(fail_descr))
self.push_gcmap(self.mc, gcmap=guardtok.gcmap, push=True)
self.mc.BL(target)
@@ -603,9 +606,6 @@
# cpu interface
def assemble_loop(self, loopname, inputargs, operations, looptoken, log):
clt = CompiledLoopToken(self.cpu, looptoken.number)
- clt.frame_info = lltype.malloc(jitframe.JITFRAMEINFO)
- clt.allgcrefs = []
- clt.frame_info.jfi_frame_depth = 0 # for now
looptoken.compiled_loop_token = clt
clt._debug_nbargs = len(inputargs)
@@ -614,6 +614,13 @@
assert len(set(inputargs)) == len(inputargs)
self.setup(looptoken)
+
+ frame_info = self.datablockwrapper.malloc_aligned(
+ jitframe.JITFRAMEINFO_SIZE, alignment=WORD)
+ clt.frame_info = rffi.cast(jitframe.JITFRAMEINFOPTR, frame_info)
+ clt.allgcrefs = []
+ clt.frame_info.set_frame_depth(0, 0) # for now
+
if False and log:
operations = self._inject_debugging_code(looptoken, operations,
'e', looptoken.number)
@@ -624,8 +631,6 @@
regalloc = Regalloc(assembler=self)
operations = regalloc.prepare_loop(inputargs, operations, looptoken,
clt.allgcrefs)
- rgc._make_sure_does_not_move(lltype.cast_opaque_ptr(llmemory.GCREF,
- clt.frame_info))
loop_head = self.mc.get_relative_pos()
looptoken._arm_loop_code = loop_head
@@ -755,7 +760,8 @@
self.cpu.gc_ll_descr.gcrootmap)
def update_frame_depth(self, frame_depth):
- self.current_clt.frame_info.jfi_frame_depth = frame_depth
+ baseofs = self.cpu.get_baseofs_of_frame_field()
+ self.current_clt.frame_info.set_frame_depth(baseofs, frame_depth)
def write_pending_failure_recoveries(self):
for tok in self.pending_guards:
@@ -1118,6 +1124,7 @@
self.mc.STR_rr(reg2.value, r.fp.value, r.ip.value, cond=cond)
self.mc.POP([r.ip.value], cond=cond)
else:
+ assert 0, 'verify this code'
self.mc.STR_ri(reg1.value, r.fp.value, imm=offset, cond=cond)
self.mc.STR_ri(reg2.value, r.fp.value,
imm=offset + WORD, cond=cond)
@@ -1221,21 +1228,17 @@
return 0
def push_gcmap(self, mc, gcmap, push=False, mov=False, store=False):
- gcmapref = lltype.cast_opaque_ptr(llmemory.GCREF, gcmap)
- # keep the ref alive
- self.current_clt.allgcrefs.append(gcmapref)
- rgc._make_sure_does_not_move(gcmapref)
+ ptr = rffi.cast(lltype.Signed, gcmap)
if push:
- mc.gen_load_int(r.ip.value, rffi.cast(lltype.Signed, gcmapref))
+ mc.gen_load_int(r.ip.value, ptr)
mc.PUSH([r.ip.value])
elif mov:
assert 0
- mc.MOV(RawEspLoc(0, REF),
- imm(rffi.cast(lltype.Signed, gcmapref)))
+ mc.MOV(RawEspLoc(0, REF), ptr)
else:
assert store
ofs = self.cpu.get_ofs_of_frame_field('jf_gcmap')
- mc.gen_load_int(r.ip.value, rffi.cast(lltype.Signed, gcmapref))
+ mc.gen_load_int(r.ip.value, ptr)
mc.STR_ri(r.ip.value, r.fp.value, imm=ofs)
def pop_gcmap(self, mc):
diff --git a/rpython/jit/backend/arm/opassembler.py
b/rpython/jit/backend/arm/opassembler.py
--- a/rpython/jit/backend/arm/opassembler.py
+++ b/rpython/jit/backend/arm/opassembler.py
@@ -30,31 +30,31 @@
from rpython.rlib.objectmodel import we_are_translated
from rpython.rlib import rgc
from rpython.rtyper.lltypesystem import rstr, rffi, lltype, llmemory
+from rpython.rlib.rarithmetic import r_uint
NO_FORCE_INDEX = -1
class GuardToken(object):
- def __init__(self, faildescr, failargs, fail_locs, offset, exc, fcond=c.AL,
- is_guard_not_invalidated=False, is_guard_not_forced=False):
+ def __init__(self, gcmap, faildescr, failargs, fail_locs, offset, exc,
+ frame_depth, fcond=c.AL, is_guard_not_invalidated=False,
+ is_guard_not_forced=False):
assert isinstance(exc, bool)
self.faildescr = faildescr
self.failargs = failargs
self.fail_locs = fail_locs[1:]
self.offset = offset
- self.gcmap = self.compute_gcmap(failargs, fail_locs,
fail_locs[0].value)
+ self.gcmap = self.compute_gcmap(gcmap, failargs,
+ fail_locs, frame_depth)
self.exc = exc
self.is_guard_not_invalidated = is_guard_not_invalidated
self.is_guard_not_forced = is_guard_not_forced
self.fcond = fcond
- def compute_gcmap(self, failargs, fail_locs, frame_depth):
+ def compute_gcmap(self, gcmap, failargs, fail_locs, frame_depth):
# note that regalloc has a very similar compute, but
# one that does iteration over all bindings, so slightly different,
# eh
- size = frame_depth + JITFRAME_FIXED_SIZE
- gcmap = lltype.malloc(jitframe.GCMAP, size // WORD // 8 + 1,
- zero=True)
input_i = 0
for i in range(len(failargs)):
arg = failargs[i]
@@ -234,16 +234,32 @@
self.mc.NOP()
else:
self.mc.BKPT()
- self.pending_guards.append(GuardToken(descr,
+ gcmap = self.allocate_gcmap(arglocs[0].value)
+ self.pending_guards.append(GuardToken(gcmap,
+ descr,
failargs=op.getfailargs(),
- fail_locs=arglocs,
+ fail_locs=arglocs[1:],
offset=pos,
exc=save_exc,
+ frame_depth=arglocs[0].value,
is_guard_not_invalidated=is_guard_not_invalidated,
is_guard_not_forced=is_guard_not_forced,
fcond=fcond))
return c.AL
+ def allocate_gcmap(self, frame_depth):
+ size = frame_depth + JITFRAME_FIXED_SIZE
+ malloc_size = (size // WORD // 8 + 1) + 1
+ rawgcmap = self.datablockwrapper.malloc_aligned(WORD * malloc_size,
+ WORD)
+ # set the length field
+ rffi.cast(rffi.CArrayPtr(lltype.Signed), rawgcmap)[0] = malloc_size - 1
+ gcmap = rffi.cast(lltype.Ptr(jitframe.GCMAP), rawgcmap)
+ # zero the area
+ for i in range(malloc_size - 1):
+ gcmap[i] = r_uint(0)
+ return gcmap
+
def _emit_guard_overflow(self, guard, failargs, fcond):
if guard.getopnum() == rop.GUARD_OVERFLOW:
fcond = self._emit_guard(guard, failargs, c.VS, save_exc=False)
@@ -327,18 +343,18 @@
# so that the locations [ebp+8..] of the input arguments are valid
# stack locations both before and after the jump.
#
- descr = op.getdescr()
- assert isinstance(descr, TargetToken)
+ target_token = op.getdescr()
+ assert isinstance(target_token, TargetToken)
assert fcond == c.AL
my_nbargs = self.current_clt._debug_nbargs
- target_nbargs = descr._arm_clt._debug_nbargs
+ target_nbargs = target_token._arm_clt._debug_nbargs
assert my_nbargs == target_nbargs
self._insert_checks()
- if descr in self.target_tokens_currently_compiling:
- self.mc.B_offs(descr._arm_loop_code, fcond)
+ if target_token in self.target_tokens_currently_compiling:
+ self.mc.B_offs(target_token._arm_loop_code, fcond)
else:
- self.mc.B(descr._arm_loop_code, fcond)
+ self.mc.B(target_token._arm_loop_code, fcond)
return fcond
def emit_op_finish(self, op, arglocs, regalloc, fcond):
diff --git a/rpython/jit/backend/arm/runner.py
b/rpython/jit/backend/arm/runner.py
--- a/rpython/jit/backend/arm/runner.py
+++ b/rpython/jit/backend/arm/runner.py
@@ -9,6 +9,7 @@
from rpython.rlib.unroll import unrolling_iterable
from rpython.rtyper.llinterp import LLInterpreter
from rpython.rtyper.lltypesystem import lltype, rffi, llmemory
+from rpython.rtyper.lltypesystem.lloperation import llop
jitframe.STATICSIZE = JITFRAME_FIXED_SIZE
@@ -99,6 +100,9 @@
assert kind == history.REF
self.set_ref_value(ll_frame, num, arg)
num += WORD
+ # no GC operation between gc_assume_young_pointers and
+ # the actual call to assembler!
+ llop.gc_assume_young_pointers(lltype.Void, frame)
ll_frame = func(ll_frame)
finally:
if not self.translate_support_code:
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit