Author: David Schneider <[email protected]>
Branch: remove-globals-in-jit
Changeset: r59671:d2595b151ff3
Date: 2012-12-20 15:44 +0100
http://bitbucket.org/pypy/pypy/changeset/d2595b151ff3/
Log: (wip) porting branch changes to ARM, some tests pass again
diff --git a/pypy/jit/backend/arm/assembler.py
b/pypy/jit/backend/arm/assembler.py
--- a/pypy/jit/backend/arm/assembler.py
+++ b/pypy/jit/backend/arm/assembler.py
@@ -30,7 +30,7 @@
from pypy.rlib.objectmodel import compute_unique_id
# XXX Move to llsupport
-from pypy.jit.backend.x86.support import values_array, memcpy_fn
+from pypy.jit.backend.x86.support import memcpy_fn
DEBUG_COUNTER = lltype.Struct('DEBUG_COUNTER', ('i', lltype.Signed),
('type', lltype.Char), # 'b'ridge, 'l'abel or
@@ -44,14 +44,8 @@
debug = True
- def __init__(self, cpu, failargs_limit=1000):
+ def __init__(self, cpu, translate_support_code=False):
self.cpu = cpu
- self.fail_boxes_int = values_array(lltype.Signed, failargs_limit)
- self.fail_boxes_float = values_array(longlong.FLOATSTORAGE,
- failargs_limit)
- self.fail_boxes_ptr = values_array(llmemory.GCREF, failargs_limit)
- self.fail_boxes_count = 0
- self.fail_force_index = 0
self.setup_failure_recovery()
self.mc = None
self.memcpy_addr = 0
@@ -68,6 +62,7 @@
self._debug = False
self.loop_run_counters = []
self.debug_counter_descr = cpu.fielddescrof(DEBUG_COUNTER, 'i')
+ self.force_token_to_dead_frame = {} # XXX temporary hack
def set_debug(self, v):
r = self._debug
@@ -123,9 +118,6 @@
self._build_release_gil(gc_ll_descr.gcrootmap)
self.memcpy_addr = self.cpu.cast_ptr_to_int(memcpy_fn)
self._exit_code_addr = self._gen_exit_path()
- self._leave_jitted_hook_save_exc = \
- self._gen_leave_jitted_hook_code(True)
- self._leave_jitted_hook = self._gen_leave_jitted_hook_code(False)
if not self._debug:
# if self._debug is already set it means that someone called
# set_debug by hand before initializing the assembler. Leave it
@@ -239,17 +231,12 @@
return # not supported (for tests, or non-translated)
#
mc = ARMv7Builder()
- # call on_leave_jitted_save_exc()
- if self.cpu.supports_floats:
- floats = r.caller_vfp_resp
- else:
- floats = []
- with saved_registers(mc, r.caller_resp + [r.lr], floats):
- addr = self.cpu.get_on_leave_jitted_int(save_exception=True,
- default_to_memoryerror=True)
- mc.BL(addr)
- mc.gen_load_int(r.ip.value, self.cpu.propagate_exception_v)
- mc.MOV_rr(r.r0.value, r.ip.value)
+ #
+ # Call the helper, which will return a dead frame object with
+ # the correct exception set, or MemoryError by default
+ # XXX make sure we return the correct value here
+ addr = rffi.cast(lltype.Signed, self.cpu.get_propagate_exception())
+ mc.BL(addr)
self.gen_func_epilog(mc=mc)
self.propagate_exception_path = mc.materialize(self.cpu.asmmemmgr, [])
@@ -282,12 +269,12 @@
# restore registers and return
# We check for c.EQ here, meaning all bits zero in this case
mc.POP([reg.value for reg in r.argument_regs] + [r.pc.value],
cond=c.EQ)
- # call on_leave_jitted_save_exc()
- addr = self.cpu.get_on_leave_jitted_int(save_exception=True)
+ #
+ # Call the helper, which will return a dead frame object with
+ # the correct exception set, or MemoryError by default
+ addr = rffi.cast(lltype.Signed, self.cpu.get_propagate_exception())
mc.BL(addr)
#
- mc.gen_load_int(r.r0.value, self.cpu.propagate_exception_v)
- #
# footer -- note the ADD, which skips the return address of this
# function, and will instead return to the caller's caller. Note
# also that we completely ignore the saved arguments, because we
@@ -347,17 +334,18 @@
vfp_registers = rffi.cast(rffi.LONGLONGP, stack_pointer)
registers = rffi.ptradd(vfp_registers, len(r.all_vfp_regs))
registers = rffi.cast(rffi.LONGP, registers)
- return self.decode_registers_and_descr(mem_loc, frame_pointer,
+ return self.decode_registers_and_descr(self.cpu, mem_loc,
frame_pointer,
registers, vfp_registers)
self.failure_recovery_func = failure_recovery_func
recovery_func_sign = lltype.Ptr(lltype.FuncType([lltype.Signed] * 3,
- lltype.Signed))
+ llmemory.GCREF))
- @rgc.no_collect
- def decode_registers_and_descr(self, mem_loc, frame_pointer,
+ @staticmethod
+ def decode_registers_and_descr(cpu, mem_loc, frame_pointer,
registers, vfp_registers):
+ # XXX rewrite
"""Decode locations encoded in memory at mem_loc and write the values
to the failboxes. Values for spilled vars and registers are stored on
stack at frame_loc """
@@ -539,9 +527,10 @@
DESCR_FLOAT = 0x02
DESCR_SPECIAL = 0x03
CODE_FROMSTACK = 64
- CODE_STOP = 0 | DESCR_SPECIAL
- CODE_HOLE = 4 | DESCR_SPECIAL
- CODE_INPUTARG = 8 | DESCR_SPECIAL
+ CODE_STOP = 0 | DESCR_SPECIAL
+ CODE_HOLE = 4 | DESCR_SPECIAL
+ CODE_INPUTARG = 8 | DESCR_SPECIAL
+ CODE_FORCED = 12 | DESCR_SPECIAL #XXX where should this be written?
def gen_descr_encoding(self, descr, failargs, locs):
assert self.mc is not None
@@ -579,9 +568,6 @@
self.mc.write32(fdescr)
self.align()
- # assert that the fail_boxes lists are big enough
- assert len(failargs) <= self.fail_boxes_int.SIZE
-
def _gen_path_to_exit_path(self, descr, args, arglocs,
save_exc, fcond=c.AL):
assert isinstance(save_exc, bool)
@@ -860,7 +846,7 @@
descr._arm_failure_recovery_block = failure_recovery_pos
relative_offset = tok.pos_recovery_stub - tok.offset
guard_pos = block_start + tok.offset
- if not tok.is_invalidate:
+ if not tok.is_guard_not_invalidated:
# patch the guard jumpt to the stub
# overwrite the generate NOP with a B_offs to the pos of the
# stub
@@ -1255,11 +1241,6 @@
else:
raise AssertionError('Trying to pop to an invalid location')
- def leave_jitted_hook(self):
- ptrs = self.fail_boxes_ptr.ar
- llop.gc_assume_young_pointers(lltype.Void,
- llmemory.cast_ptr_to_adr(ptrs))
-
def malloc_cond(self, nursery_free_adr, nursery_top_adr, size):
assert size & (WORD-1) == 0 # must be correctly aligned
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
@@ -33,12 +33,13 @@
class GuardToken(object):
- def __init__(self, descr, failargs, faillocs, offset,
- save_exc, fcond=c.AL, is_invalidate=False):
+ def __init__(self, descr, failargs, faillocs, offset, save_exc, fcond=c.AL,
+ is_guard_not_invalidated=False, is_guard_not_forced=False):
assert isinstance(save_exc, bool)
self.descr = descr
self.offset = offset
- self.is_invalidate = is_invalidate
+ self.is_guard_not_invalidated = is_guard_not_invalidated
+ self.is_guard_not_forced = is_guard_not_forced
self.failargs = failargs
self.faillocs = faillocs
self.save_exc = save_exc
@@ -190,7 +191,8 @@
return fcond
def _emit_guard(self, op, arglocs, fcond, save_exc,
- is_guard_not_invalidated=False):
+ is_guard_not_invalidated=False,
+ is_guard_not_forced=False):
assert isinstance(save_exc, bool)
assert isinstance(fcond, int)
descr = op.getdescr()
@@ -210,7 +212,8 @@
faillocs=arglocs,
offset=pos,
save_exc=save_exc,
- is_invalidate=is_guard_not_invalidated,
+
is_guard_not_invalidated=is_guard_not_invalidated,
+ is_guard_not_forced=is_guard_not_forced,
fcond=fcond))
return c.AL
@@ -312,49 +315,11 @@
return fcond
def emit_op_finish(self, op, arglocs, regalloc, fcond):
- for i in range(len(arglocs) - 1):
- loc = arglocs[i]
- box = op.getarg(i)
- if loc is None:
- continue
- if loc.is_reg():
- if box.type == REF:
- adr = self.fail_boxes_ptr.get_addr_for_num(i)
- elif box.type == INT:
- adr = self.fail_boxes_int.get_addr_for_num(i)
- else:
- assert 0
- self.mc.gen_load_int(r.ip.value, adr)
- self.mc.STR_ri(loc.value, r.ip.value)
- elif loc.is_vfp_reg():
- assert box.type == FLOAT
- adr = self.fail_boxes_float.get_addr_for_num(i)
- self.mc.gen_load_int(r.ip.value, adr)
- self.mc.VSTR(loc.value, r.ip.value)
- elif loc.is_stack() or loc.is_imm() or loc.is_imm_float():
- if box.type == FLOAT:
- adr = self.fail_boxes_float.get_addr_for_num(i)
- self.mov_loc_loc(loc, r.vfp_ip)
- self.mc.gen_load_int(r.ip.value, adr)
- self.mc.VSTR(r.vfp_ip.value, r.ip.value)
- elif box.type == REF or box.type == INT:
- if box.type == REF:
- adr = self.fail_boxes_ptr.get_addr_for_num(i)
- elif box.type == INT:
- adr = self.fail_boxes_int.get_addr_for_num(i)
- else:
- assert 0
- self.mov_loc_loc(loc, r.ip)
- self.mc.gen_load_int(r.lr.value, adr)
- self.mc.STR_ri(r.ip.value, r.lr.value)
- else:
- assert 0
- # note: no exception should currently be set in llop.get_exception_addr
- # even if this finish may be an exit_frame_with_exception (in this case
- # the exception instance is in arglocs[0]).
- addr = self.cpu.get_on_leave_jitted_int(save_exception=False)
- self.mc.BL(addr)
- self.mc.gen_load_int(r.r0.value, arglocs[-1].value)
+ [argloc] = arglocs
+ if argloc is not r.r0: #XXX verify this
+ self.mov(argloc, eax)
+ self.mov_loc_loc(arg_loc, r.r0, fcond)
+ # exit function
self.gen_func_epilog()
return fcond
@@ -1266,7 +1231,8 @@
self.mc.LDR_ri(r.ip.value, r.fp.value)
self.mc.CMP_ri(r.ip.value, 0)
- self._emit_guard(guard_op, arglocs[1 + numargs:], c.GE, save_exc=True)
+ self._emit_guard(guard_op, arglocs[1 + numargs:], c.GE,
+ save_exc=True, is_guard_not_forced=True)
return fcond
def emit_guard_call_release_gil(self, op, guard_op, arglocs, regalloc,
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
@@ -654,15 +654,9 @@
return args
def prepare_op_finish(self, op, fcond):
- args = [None] * (op.numargs() + 1)
- for i in range(op.numargs()):
- arg = op.getarg(i)
- if arg:
- args[i] = self.loc(arg)
- self.possibly_free_var(arg)
- n = self.cpu.get_fail_descr_number(op.getdescr())
- args[-1] = imm(n)
- return args
+ loc = self.loc(op.getarg(0))
+ self.possibly_free_var(op.getarg(0))
+ return [loc]
def prepare_op_guard_true(self, op, fcond):
l0 = self._ensure_value_is_boxed(op.getarg(0))
diff --git a/pypy/jit/backend/arm/runner.py b/pypy/jit/backend/arm/runner.py
--- a/pypy/jit/backend/arm/runner.py
+++ b/pypy/jit/backend/arm/runner.py
@@ -23,15 +23,21 @@
AbstractLLCPU.__init__(self, rtyper, stats, opts,
translate_support_code, gcdescr)
+ from pypy.jit.backend.llsupport import jitframe
+ self.deadframe_size_max = llmemory.sizeof(jitframe.DEADFRAME,
+ self.get_failargs_limit())
+
def set_debug(self, flag):
return self.assembler.set_debug(flag)
+ def get_failargs_limit(self):
+ if self.opts is not None:
+ return self.opts.failargs_limit
+ else:
+ return 1000
+
def setup(self):
- if self.opts is not None:
- failargs_limit = self.opts.failargs_limit
- else:
- failargs_limit = 1000
- self.assembler = AssemblerARM(self, failargs_limit=failargs_limit)
+ self.assembler = AssemblerARM(self, self.translate_support_code)
def setup_once(self):
self.assembler.setup_once()
@@ -51,24 +57,6 @@
return self.assembler.assemble_bridge(faildescr, inputargs, operations,
original_loop_token, log=log)
- def get_latest_value_float(self, index):
- return self.assembler.fail_boxes_float.getitem(index)
-
- def get_latest_value_int(self, index):
- return self.assembler.fail_boxes_int.getitem(index)
-
- def get_latest_value_ref(self, index):
- return self.assembler.fail_boxes_ptr.getitem(index)
-
- def get_latest_value_count(self):
- return self.assembler.fail_boxes_count
-
- def get_latest_force_token(self):
- return self.assembler.fail_force_index
-
- def get_on_leave_jitted_hook(self):
- return self.assembler.leave_jitted_hook
-
def clear_latest_values(self, count):
setitem = self.assembler.fail_boxes_ptr.setitem
null = lltype.nullptr(llmemory.GCREF.TO)
@@ -76,7 +64,7 @@
setitem(index, null)
def make_execute_token(self, *ARGS):
- FUNCPTR = lltype.Ptr(lltype.FuncType(ARGS, lltype.Signed))
+ FUNCPTR = lltype.Ptr(lltype.FuncType(ARGS, llmemory.GCREF))
def execute_token(executable_token, *args):
clt = executable_token.compiled_loop_token
@@ -91,12 +79,13 @@
prev_interpreter = LLInterpreter.current_interpreter
LLInterpreter.current_interpreter = self.debug_ll_interpreter
try:
- fail_index = func(*args)
+ deadframe = func(*args)
finally:
if not self.translate_support_code:
LLInterpreter.current_interpreter = prev_interpreter
#llop.debug_print(lltype.Void, "<<<< Back")
- return self.get_fail_descr_from_number(fail_index)
+ self.gc_set_extra_threshold()
+ return deadframe
return execute_token
def cast_ptr_to_int(x):
@@ -110,6 +99,7 @@
flavor='raw', zero=True, immortal=True)
def force(self, addr_of_force_index):
+ assert 0, 'refactor ME'
TP = rffi.CArrayPtr(lltype.Signed)
fail_index = rffi.cast(TP, addr_of_force_index)[0]
assert fail_index >= 0, "already forced!"
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit