diff options
Diffstat (limited to 'rpython/jit/metainterp/pyjitpl.py')
-rw-r--r-- | rpython/jit/metainterp/pyjitpl.py | 78 |
1 files changed, 47 insertions, 31 deletions
diff --git a/rpython/jit/metainterp/pyjitpl.py b/rpython/jit/metainterp/pyjitpl.py index 56faf0670a..914270b110 100644 --- a/rpython/jit/metainterp/pyjitpl.py +++ b/rpython/jit/metainterp/pyjitpl.py @@ -65,44 +65,56 @@ class MIFrame(object): def __init__(self, metainterp): self.metainterp = metainterp - self.registers_i = [None] * 256 - self.registers_r = [None] * 256 - self.registers_f = [None] * 256 + self.registers_i = None + self.registers_r = None + self.registers_f = None def setup(self, jitcode, greenkey=None): # if not translated, fill the registers with MissingValue() - if not we_are_translated(): - self.registers_i = [MissingValue()] * 256 - self.registers_r = [MissingValue()] * 256 - self.registers_f = [MissingValue()] * 256 assert isinstance(jitcode, JitCode) self.jitcode = jitcode self.bytecode = jitcode.code # this is not None for frames that are recursive portal calls self.greenkey = greenkey - # copy the constants in place - self.copy_constants(self.registers_i, jitcode.constants_i, ConstInt) - self.copy_constants(self.registers_r, jitcode.constants_r, ConstPtrJitCode) - self.copy_constants(self.registers_f, jitcode.constants_f, ConstFloat) + # create registers_* lists and copy the constants in place + num_regs_and_consts_i = jitcode.num_regs_and_consts_i() + num_regs_and_consts_r = jitcode.num_regs_and_consts_r() + num_regs_and_consts_f = jitcode.num_regs_and_consts_f() + if num_regs_and_consts_i: + self.registers_i = self.copy_constants(self.registers_i, jitcode.constants_i, jitcode.num_regs_i(), ConstInt) + if num_regs_and_consts_r: + self.registers_r = self.copy_constants(self.registers_r, jitcode.constants_r, jitcode.num_regs_r(), ConstPtrJitCode) + if num_regs_and_consts_f: + self.registers_f = self.copy_constants(self.registers_f, jitcode.constants_f, jitcode.num_regs_f(), ConstFloat) self._result_argcode = 'v' # for resume.py operation self.parent_snapshot = None # counter for unrolling inlined loops self.unroll_iterations = 1 - @specialize.arg(3) - def copy_constants(self, registers, constants, ConstClass): - """Copy jitcode.constants[0] to registers[255], - jitcode.constants[1] to registers[254], - jitcode.constants[2] to registers[253], etc.""" + @specialize.arg(4) + def copy_constants(self, registers, constants, targetindex, ConstClass): + """Copy jitcode.constants[0] to registers[self.jitcode.num_regs_x() + 0], + jitcode.constants[1] to registers[self.jitcode.num_regs_x() + 1], + jitcode.constants[2] to registers[self.jitcode.num_regs_x() + 2], + etc.""" + if not we_are_translated(): + missing = MissingValue() + else: + missing = None + num_regs_and_consts = targetindex + len(constants) + # increase size if its too small + if registers is None or len(registers) < num_regs_and_consts: + registers = [missing] * num_regs_and_consts + elif not we_are_translated(): + for i in range(len(registers)): + registers[i] = missing if nonconst.NonConstant(0): # force the right type constants[0] = ConstClass.value # (useful for small tests) - i = len(constants) - 1 - while i >= 0: - j = 255 - i - assert j >= 0 - registers[j] = ConstClass(constants[i]) - i -= 1 + for i in range(len(constants)): + registers[targetindex] = ConstClass(constants[i]) + targetindex += 1 + return registers def cleanup_registers(self): # To avoid keeping references alive, this cleans up the registers_r. @@ -232,6 +244,8 @@ class MIFrame(object): registers = self.registers_f else: assert 0, oldbox + if not count: + return for i in range(count): if registers[i] is oldbox: registers[i] = newbox @@ -397,8 +411,7 @@ class MIFrame(object): @arguments("box", "box", "boxes2", "descr", "orgpc") def opimpl_record_known_result_i_ir_v(self, resbox, funcbox, argboxes, calldescr, pc): - allboxes = self._build_allboxes(funcbox, argboxes, calldescr) - allboxes = [resbox] + allboxes + allboxes = self._build_allboxes(funcbox, argboxes, calldescr, prepend_box=resbox) # this is a weird op! we don't want to execute anything, so just record # an operation self.metainterp._record_helper_varargs(rop.RECORD_KNOWN_RESULT, None, calldescr, allboxes) @@ -1889,11 +1902,15 @@ class MIFrame(object): self.metainterp.assert_no_exception() return op - def _build_allboxes(self, funcbox, argboxes, descr): - allboxes = [None] * (len(argboxes)+1) - allboxes[0] = funcbox + def _build_allboxes(self, funcbox, argboxes, descr, prepend_box=None): + allboxes = [None] * (len(argboxes)+1 + int(prepend_box is not None)) + i = 0 + if prepend_box is not None: + allboxes[0] = prepend_box + i = 1 + allboxes[i] = funcbox + i += 1 src_i = src_r = src_f = 0 - i = 1 for kind in descr.get_arg_types(): if kind == history.INT or kind == 'S': # single float while True: @@ -2055,11 +2072,10 @@ class MIFrame(object): def do_conditional_call(self, condbox, funcbox, argboxes, descr, pc, is_value=False): - allboxes = self._build_allboxes(funcbox, argboxes, descr) + allboxes = self._build_allboxes(funcbox, argboxes, descr, prepend_box=condbox) effectinfo = descr.get_extra_info() assert not effectinfo.check_forces_virtual_or_virtualizable() exc = effectinfo.check_can_raise() - allboxes = [condbox] + allboxes # COND_CALL cannot be pure (=elidable): it has no result. # On the other hand, COND_CALL_VALUE is always calling a pure # function. @@ -2396,7 +2412,7 @@ class MetaInterp(object): (jitcode.jitdriver_sd, None, self.history.get_trace_position())) # we save the freed MIFrames to avoid needing to re-create new # MIFrame objects all the time; they are a bit big, with their - # 3*256 register entries. + # up to 3*256 register entries. frame.cleanup_registers() self.free_frames_list.append(frame) |