aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'rpython/jit/metainterp/pyjitpl.py')
-rw-r--r--rpython/jit/metainterp/pyjitpl.py78
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)