[pypy-svn] r69578 - in pypy/branch/shorter-guard-path-2/pypy: jit/backend jit/backend/cli jit/backend/llgraph jit/backend/llsupport jit/backend/test jit/backend/x86 jit/backend/x86/test jit/metainterp jit/metainterp/test objspace/std
arigo at codespeak.net
arigo at codespeak.net
Tue Nov 24 14:29:48 CET 2009
Author: arigo
Date: Tue Nov 24 14:29:46 2009
New Revision: 69578
Added:
pypy/branch/shorter-guard-path-2/pypy/jit/backend/test/test_model.py
- copied unchanged from r69483, pypy/branch/shorter-guard-path/pypy/jit/backend/test/test_model.py
pypy/branch/shorter-guard-path-2/pypy/jit/backend/x86/test/test_assembler.py
- copied unchanged from r69483, pypy/branch/shorter-guard-path/pypy/jit/backend/x86/test/test_assembler.py
Modified:
pypy/branch/shorter-guard-path-2/pypy/jit/backend/cli/method.py
pypy/branch/shorter-guard-path-2/pypy/jit/backend/cli/runner.py
pypy/branch/shorter-guard-path-2/pypy/jit/backend/llgraph/runner.py
pypy/branch/shorter-guard-path-2/pypy/jit/backend/llsupport/llmodel.py
pypy/branch/shorter-guard-path-2/pypy/jit/backend/model.py
pypy/branch/shorter-guard-path-2/pypy/jit/backend/test/runner_test.py
pypy/branch/shorter-guard-path-2/pypy/jit/backend/test/test_ll_random.py
pypy/branch/shorter-guard-path-2/pypy/jit/backend/test/test_random.py
pypy/branch/shorter-guard-path-2/pypy/jit/backend/x86/assembler.py
pypy/branch/shorter-guard-path-2/pypy/jit/backend/x86/regalloc.py
pypy/branch/shorter-guard-path-2/pypy/jit/backend/x86/ri386setup.py
pypy/branch/shorter-guard-path-2/pypy/jit/backend/x86/runner.py
pypy/branch/shorter-guard-path-2/pypy/jit/backend/x86/support.py
pypy/branch/shorter-guard-path-2/pypy/jit/backend/x86/test/test_recompilation.py
pypy/branch/shorter-guard-path-2/pypy/jit/backend/x86/test/test_ri386_auto_encoding.py
pypy/branch/shorter-guard-path-2/pypy/jit/backend/x86/test/test_runner.py
pypy/branch/shorter-guard-path-2/pypy/jit/metainterp/compile.py
pypy/branch/shorter-guard-path-2/pypy/jit/metainterp/history.py
pypy/branch/shorter-guard-path-2/pypy/jit/metainterp/logger.py
pypy/branch/shorter-guard-path-2/pypy/jit/metainterp/pyjitpl.py
pypy/branch/shorter-guard-path-2/pypy/jit/metainterp/test/test_compile.py
pypy/branch/shorter-guard-path-2/pypy/jit/metainterp/test/test_logger.py
pypy/branch/shorter-guard-path-2/pypy/jit/metainterp/test/test_pyjitpl.py
pypy/branch/shorter-guard-path-2/pypy/jit/metainterp/warmstate.py
pypy/branch/shorter-guard-path-2/pypy/objspace/std/multimethod.py
Log:
Merge the branch/shorter-guard-path.
Needs a bit of fixing.
Modified: pypy/branch/shorter-guard-path-2/pypy/jit/backend/cli/method.py
==============================================================================
--- pypy/branch/shorter-guard-path-2/pypy/jit/backend/cli/method.py (original)
+++ pypy/branch/shorter-guard-path-2/pypy/jit/backend/cli/method.py Tue Nov 24 14:29:46 2009
@@ -268,9 +268,6 @@
try:
return self.cpu.failing_ops.index(op)
except ValueError:
- descr = op.descr
- assert isinstance(descr, history.AbstractFailDescr)
- descr.get_index()
self.cpu.failing_ops.append(op)
return len(self.cpu.failing_ops)-1
Modified: pypy/branch/shorter-guard-path-2/pypy/jit/backend/cli/runner.py
==============================================================================
--- pypy/branch/shorter-guard-path-2/pypy/jit/backend/cli/runner.py (original)
+++ pypy/branch/shorter-guard-path-2/pypy/jit/backend/cli/runner.py Tue Nov 24 14:29:46 2009
@@ -135,9 +135,7 @@
func = cliloop.funcbox.holder.GetFunc()
func(self.get_inputargs())
op = self.failing_ops[self.inputargs.get_failed_op()]
- descr = op.descr
- assert isinstance(descr, AbstractFailDescr)
- return descr.get_index()
+ return op.descr
def set_future_value_int(self, index, intvalue):
self.get_inputargs().set_int(index, intvalue)
Modified: pypy/branch/shorter-guard-path-2/pypy/jit/backend/llgraph/runner.py
==============================================================================
--- pypy/branch/shorter-guard-path-2/pypy/jit/backend/llgraph/runner.py (original)
+++ pypy/branch/shorter-guard-path-2/pypy/jit/backend/llgraph/runner.py Tue Nov 24 14:29:46 2009
@@ -88,6 +88,7 @@
def __init__(self, rtyper, stats=None, translate_support_code=False,
annmixlevel=None, gcdescr=None):
+ model.AbstractCPU.__init__(self)
self.rtyper = rtyper
self.translate_support_code = translate_support_code
self.stats = stats or MiniStats()
@@ -167,7 +168,7 @@
if op.is_guard():
faildescr = op.descr
assert isinstance(faildescr, history.AbstractFailDescr)
- fail_index = faildescr.get_index()
+ fail_index = self.get_fail_descr_number(faildescr)
index = llimpl.compile_add_fail(c, fail_index)
faildescr._compiled_fail = c, index
for box in op.fail_args:
@@ -195,8 +196,7 @@
llimpl.compile_add_jump_target(c, compiled_version)
elif op.opnum == rop.FINISH:
faildescr = op.descr
- assert isinstance(faildescr, history.AbstractFailDescr)
- index = faildescr.get_index()
+ index = self.get_fail_descr_number(faildescr)
llimpl.compile_add_fail(c, index)
else:
assert False, "unknown operation"
@@ -213,7 +213,7 @@
fail_index = llimpl.frame_execute(frame)
# we hit a FAIL operation.
self.latest_frame = frame
- return fail_index
+ return self.get_fail_descr_from_number(fail_index)
def set_future_value_int(self, index, intvalue):
llimpl.set_future_value_int(index, intvalue)
Modified: pypy/branch/shorter-guard-path-2/pypy/jit/backend/llsupport/llmodel.py
==============================================================================
--- pypy/branch/shorter-guard-path-2/pypy/jit/backend/llsupport/llmodel.py (original)
+++ pypy/branch/shorter-guard-path-2/pypy/jit/backend/llsupport/llmodel.py Tue Nov 24 14:29:46 2009
@@ -20,6 +20,7 @@
def __init__(self, rtyper, stats, translate_support_code=False,
gcdescr=None):
from pypy.jit.backend.llsupport.gc import get_ll_description
+ AbstractCPU.__init__(self)
self.rtyper = rtyper
self.stats = stats
self.translate_support_code = translate_support_code
@@ -149,8 +150,8 @@
on_leave_jitted_hook()
def on_leave_jitted_save_exc():
- on_leave_jitted_hook()
save_exception()
+ on_leave_jitted_hook()
self.on_leave_jitted_noexc = on_leave_jitted_noexc
self.on_leave_jitted_save_exc = on_leave_jitted_save_exc
Modified: pypy/branch/shorter-guard-path-2/pypy/jit/backend/model.py
==============================================================================
--- pypy/branch/shorter-guard-path-2/pypy/jit/backend/model.py (original)
+++ pypy/branch/shorter-guard-path-2/pypy/jit/backend/model.py Tue Nov 24 14:29:46 2009
@@ -1,6 +1,25 @@
+from pypy.jit.metainterp import history
+
+
class AbstractCPU(object):
supports_floats = False
+ def __init__(self):
+ self.fail_descr_list = []
+
+ def get_fail_descr_number(self, descr):
+ assert isinstance(descr, history.AbstractFailDescr)
+ n = descr.index
+ if n < 0:
+ lst = self.fail_descr_list
+ n = len(lst)
+ lst.append(descr)
+ descr.index = n
+ return n
+
+ def get_fail_descr_from_number(self, n):
+ return self.fail_descr_list[n]
+
def set_class_sizes(self, class_sizes):
self.class_sizes = class_sizes
Modified: pypy/branch/shorter-guard-path-2/pypy/jit/backend/test/runner_test.py
==============================================================================
--- pypy/branch/shorter-guard-path-2/pypy/jit/backend/test/runner_test.py (original)
+++ pypy/branch/shorter-guard-path-2/pypy/jit/backend/test/runner_test.py Tue Nov 24 14:29:46 2009
@@ -39,7 +39,7 @@
else:
raise NotImplementedError(box)
res = self.cpu.execute_token(looptoken)
- if res == operations[-1].descr.index:
+ if res is operations[-1].descr:
self.guard_failed = False
else:
self.guard_failed = True
@@ -102,7 +102,7 @@
fail = self.cpu.execute_token(looptoken)
res = self.cpu.get_latest_value_int(0)
assert res == 3
- assert fail == 1
+ assert fail.identifier == 1
def test_compile_loop(self):
i0 = BoxInt()
@@ -121,7 +121,7 @@
self.cpu.compile_loop(inputargs, operations, looptoken)
self.cpu.set_future_value_int(0, 2)
fail = self.cpu.execute_token(looptoken)
- assert fail == 2
+ assert fail.identifier == 2
res = self.cpu.get_latest_value_int(0)
assert res == 10
@@ -200,7 +200,7 @@
self.cpu.set_future_value_int(0, 2)
fail = self.cpu.execute_token(looptoken)
- assert fail == 2
+ assert fail.identifier == 2
res = self.cpu.get_latest_value_int(0)
assert res == 20
@@ -242,9 +242,9 @@
i0 = BoxInt()
class UntouchableFailDescr(AbstractFailDescr):
def __setattr__(self, name, value):
+ if name == 'index':
+ return AbstractFailDescr.__setattr__(self, name, value)
py.test.fail("finish descrs should not be touched")
- def get_index(self):
- return 7
faildescr = UntouchableFailDescr() # to check that is not touched
looptoken = LoopToken()
operations = [
@@ -253,7 +253,7 @@
self.cpu.compile_loop([i0], operations, looptoken)
self.cpu.set_future_value_int(0, 99)
fail = self.cpu.execute_token(looptoken)
- assert fail == 7
+ assert fail is faildescr
res = self.cpu.get_latest_value_int(0)
assert res == 99
@@ -263,7 +263,7 @@
]
self.cpu.compile_loop([], operations, looptoken)
fail = self.cpu.execute_token(looptoken)
- assert fail == 7
+ assert fail is faildescr
res = self.cpu.get_latest_value_int(0)
assert res == 42
@@ -273,7 +273,7 @@
]
self.cpu.compile_loop([], operations, looptoken)
fail = self.cpu.execute_token(looptoken)
- assert fail == 7
+ assert fail is faildescr
def test_execute_operations_in_env(self):
cpu = self.cpu
@@ -357,9 +357,9 @@
self.cpu.set_future_value_int(1, y)
fail = self.cpu.execute_token(looptoken)
if (z == boom) ^ reversed:
- assert fail == 1
+ assert fail.identifier == 1
else:
- assert fail == 2
+ assert fail.identifier == 2
if z != boom:
assert self.cpu.get_latest_value_int(0) == z
assert not self.cpu.get_exception()
@@ -832,7 +832,7 @@
assert 0
#
fail = self.cpu.execute_token(looptoken)
- assert fail == 15
+ assert fail.identifier == 15
#
dstvalues = values[:]
for _ in range(11):
@@ -884,7 +884,7 @@
for i in range(len(fboxes)):
self.cpu.set_future_value_float(i, 13.5 + 6.73 * i)
fail = self.cpu.execute_token(looptoken)
- assert fail == 2
+ assert fail.identifier == 2
res = self.cpu.get_latest_value_float(0)
assert res == 8.5
for i in range(1, len(fboxes)):
@@ -935,7 +935,7 @@
assert 0
#
fail = self.cpu.execute_token(looptoken)
- assert fail == 1
+ assert fail.identifier == 1
class LLtypeBackendTest(BaseBackendTest):
Modified: pypy/branch/shorter-guard-path-2/pypy/jit/backend/test/test_ll_random.py
==============================================================================
--- pypy/branch/shorter-guard-path-2/pypy/jit/backend/test/test_ll_random.py (original)
+++ pypy/branch/shorter-guard-path-2/pypy/jit/backend/test/test_ll_random.py Tue Nov 24 14:29:46 2009
@@ -4,6 +4,7 @@
from pypy.jit.metainterp.resoperation import ResOperation, rop
from pypy.jit.metainterp.history import ConstInt, ConstPtr
from pypy.jit.metainterp.history import ConstAddr, BoxPtr, BoxInt
+from pypy.jit.metainterp.history import BasicFailDescr
from pypy.rpython.annlowlevel import llhelper
from pypy.rlib.rarithmetic import intmask
from pypy.rpython.llinterp import LLException
@@ -464,7 +465,7 @@
descr = builder.cpu.calldescrof(TP, TP.ARGS, TP.RESULT)
self.put(builder, args, descr)
op = ResOperation(rop.GUARD_NO_EXCEPTION, [], None,
- descr=builder.make_fail_descr())
+ descr=BasicFailDescr())
op.fail_args = fail_subset
builder.loop.operations.append(op)
@@ -486,7 +487,7 @@
_, vtableptr = builder.get_random_structure_type_and_vtable(r)
exc_box = ConstAddr(llmemory.cast_ptr_to_adr(vtableptr), builder.cpu)
op = ResOperation(rop.GUARD_EXCEPTION, [exc_box], BoxPtr(),
- descr=builder.make_fail_descr())
+ descr=BasicFailDescr())
op.fail_args = builder.subset_of_intvars(r)
op._exc_box = None
builder.should_fail_by = op
@@ -509,7 +510,7 @@
assert builder.cpu.get_exception()
builder.cpu.clear_exception()
op = ResOperation(rop.GUARD_EXCEPTION, [exc_box], BoxPtr(),
- descr=builder.make_fail_descr())
+ descr=BasicFailDescr())
op.fail_args = fail_subset
builder.loop.operations.append(op)
@@ -527,7 +528,7 @@
assert builder.cpu.get_exception()
builder.cpu.clear_exception()
op = ResOperation(rop.GUARD_NO_EXCEPTION, [], BoxPtr(),
- descr=builder.make_fail_descr())
+ descr=BasicFailDescr())
op._exc_box = ConstAddr(llmemory.cast_ptr_to_adr(exc), builder.cpu)
op.fail_args = builder.subset_of_intvars(r)
builder.should_fail_by = op
@@ -553,7 +554,7 @@
break
other_box = ConstAddr(llmemory.cast_ptr_to_adr(vtableptr), builder.cpu)
op = ResOperation(rop.GUARD_EXCEPTION, [other_box], BoxPtr(),
- descr=builder.make_fail_descr())
+ descr=BasicFailDescr())
op._exc_box = ConstAddr(llmemory.cast_ptr_to_adr(exc), builder.cpu)
op.fail_args = builder.subset_of_intvars(r)
builder.should_fail_by = op
Modified: pypy/branch/shorter-guard-path-2/pypy/jit/backend/test/test_random.py
==============================================================================
--- pypy/branch/shorter-guard-path-2/pypy/jit/backend/test/test_random.py (original)
+++ pypy/branch/shorter-guard-path-2/pypy/jit/backend/test/test_random.py Tue Nov 24 14:29:46 2009
@@ -18,8 +18,6 @@
self.operations = subops
class OperationBuilder(object):
- failnumbering = 0
-
def __init__(self, cpu, loop, vars):
self.cpu = cpu
self.loop = loop
@@ -36,12 +34,6 @@
self.counter = 0
assert len(self.intvars) == len(dict.fromkeys(self.intvars))
- @classmethod
- def make_fail_descr(cls):
- descr = BasicFailDescr(cls.failnumbering)
- cls.failnumbering += 1
- return descr
-
def fork(self, cpu, loop, vars):
fork = self.__class__(cpu, loop, vars)
fork.prebuilt_ptr_consts = self.prebuilt_ptr_consts
@@ -282,7 +274,7 @@
builder.intvars[:] = original_intvars
else:
op = ResOperation(rop.GUARD_NO_OVERFLOW, [], None)
- op.descr = builder.make_fail_descr()
+ op.descr = BasicFailDescr()
op.fail_args = fail_subset
builder.loop.operations.append(op)
@@ -343,7 +335,7 @@
def produce_into(self, builder, r):
op, passing = self.gen_guard(builder, r)
builder.loop.operations.append(op)
- op.descr = builder.make_fail_descr()
+ op.descr = BasicFailDescr()
op.fail_args = builder.subset_of_intvars(r)
if not passing:
builder.should_fail_by = op
@@ -559,7 +551,7 @@
endvars.append(v)
r.shuffle(endvars)
loop.operations.append(ResOperation(rop.FINISH, endvars, None,
- descr=BasicFailDescr(-2)))
+ descr=BasicFailDescr()))
if builder.should_fail_by:
self.should_fail_by = builder.should_fail_by
self.guard_op = builder.guard_op
@@ -605,7 +597,7 @@
else:
raise NotImplementedError(box)
fail = cpu.execute_token(self.loop.token)
- assert fail == self.should_fail_by.descr.index
+ assert fail is self.should_fail_by.descr
for i, v in enumerate(self.get_fail_args()):
if isinstance(v, (BoxFloat, ConstFloat)):
value = cpu.get_latest_value_float(i)
@@ -634,7 +626,7 @@
else:
op = ResOperation(rop.GUARD_EXCEPTION, [guard_op._exc_box],
BoxPtr())
- op.descr = self.builder.make_fail_descr()
+ op.descr = BasicFailDescr()
op.fail_args = []
return op
Modified: pypy/branch/shorter-guard-path-2/pypy/jit/backend/x86/assembler.py
==============================================================================
--- pypy/branch/shorter-guard-path-2/pypy/jit/backend/x86/assembler.py (original)
+++ pypy/branch/shorter-guard-path-2/pypy/jit/backend/x86/assembler.py Tue Nov 24 14:29:46 2009
@@ -1,11 +1,12 @@
import sys, os
import ctypes
from pypy.jit.backend.llsupport import symbolic
-from pypy.jit.metainterp.history import Const, Box, BoxPtr, REF, FLOAT
+from pypy.jit.metainterp.history import Const, Box, BoxPtr, INT, REF, FLOAT
from pypy.jit.metainterp.history import AbstractFailDescr
from pypy.rpython.lltypesystem import lltype, rffi, ll2ctypes, rstr, llmemory
from pypy.rpython.lltypesystem.rclass import OBJECT
from pypy.rpython.lltypesystem.lloperation import llop
+from pypy.rpython.annlowlevel import llhelper
from pypy.tool.uid import fixid
from pypy.jit.backend.x86.regalloc import RegAlloc, WORD, lower_byte,\
X86RegisterManager, X86XMMRegisterManager, get_ebp_ofs
@@ -16,6 +17,7 @@
from pypy.jit.backend.x86.support import NonmovableGrowableArrayFloat,\
NonmovableGrowableArraySigned, NonmovableGrowableArrayGCREF,\
CHUNK_SIZE
+from pypy.rlib.debug import debug_print
# our calling convention - we pass first 6 args in registers
# and the rest stays on the stack
@@ -33,11 +35,24 @@
return (words + CALL_ALIGN - 1) & ~(CALL_ALIGN-1)
class MachineCodeBlockWrapper(object):
- MC_SIZE = 1024*1024
+ MC_DEFAULT_SIZE = 1024*1024
- def __init__(self):
+ def __init__(self, bigsize):
self.old_mcs = [] # keepalive
- self._mc = codebuf.MachineCodeBlock(self.MC_SIZE)
+ self.bigsize = bigsize
+ self._mc = codebuf.MachineCodeBlock(bigsize)
+
+ def bytes_free(self):
+ return self._mc._size - self._mc._pos
+
+ def make_new_mc(self):
+ new_mc = codebuf.MachineCodeBlock(self.bigsize)
+ debug_print('[new machine code block at', new_mc.tell(), ']')
+ self._mc.JMP(rel32(new_mc.tell()))
+ self._mc.done()
+ self.old_mcs.append(self._mc)
+ self._mc = new_mc
+ make_new_mc._dont_inline_ = True
def tell(self):
return self._mc.tell()
@@ -49,12 +64,8 @@
def method(self, *args):
# XXX er.... pretty random number, just to be sure
# not to write half-instruction
- if self._mc._pos + 64 >= self._mc._size:
- new_mc = codebuf.MachineCodeBlock(self.MC_SIZE)
- self._mc.JMP(rel32(new_mc.tell()))
- self._mc.done()
- self.old_mcs.append(self._mc)
- self._mc = new_mc
+ if self.bytes_free() < 64:
+ self.make_new_mc()
getattr(self._mc, name)(*args)
method.func_name = name
return method
@@ -66,7 +77,7 @@
class Assembler386(object):
mc = None
mc2 = None
- debug_markers = True
+ mc_size = MachineCodeBlockWrapper.MC_DEFAULT_SIZE
def __init__(self, cpu, translate_support_code=False):
self.cpu = cpu
@@ -79,11 +90,9 @@
self.fail_boxes_int = NonmovableGrowableArraySigned()
self.fail_boxes_ptr = NonmovableGrowableArrayGCREF()
self.fail_boxes_float = NonmovableGrowableArrayFloat()
+ self.setup_failure_recovery()
def leave_jitted_hook(self):
- # XXX BIG FAT WARNING XXX
- # At this point, we should not call anyone here, because
- # RPython-level exception might be set. Here be dragons
i = 0
while i < self.fail_boxes_ptr.lgt:
chunk = self.fail_boxes_ptr.chunks[i]
@@ -113,8 +122,13 @@
# done
# we generate the loop body in 'mc'
# 'mc2' is for guard recovery code
- self.mc = MachineCodeBlockWrapper()
- self.mc2 = MachineCodeBlockWrapper()
+ self.mc = MachineCodeBlockWrapper(self.mc_size)
+ self.mc2 = MachineCodeBlockWrapper(self.mc_size)
+ self._build_failure_recovery(False)
+ self._build_failure_recovery(True)
+ if self.cpu.supports_floats:
+ self._build_failure_recovery(False, withfloats=True)
+ self._build_failure_recovery(True, withfloats=True)
def assemble_loop(self, inputargs, operations, looptoken):
"""adds the following attributes to looptoken:
@@ -137,8 +151,12 @@
def assemble_bridge(self, faildescr, inputargs, operations):
self.make_sure_mc_exists()
+ arglocs = self.rebuild_faillocs_from_descr(
+ faildescr._x86_failure_recovery_bytecode)
+ if not we_are_translated():
+ assert ([loc.assembler() for loc in arglocs] ==
+ [loc.assembler() for loc in faildescr._x86_debug_faillocs])
regalloc = RegAlloc(self, self.cpu.translate_support_code)
- arglocs = faildescr._x86_faillocs
fail_stack_depth = faildescr._x86_current_stack_depth
regalloc.prepare_bridge(fail_stack_depth, inputargs, arglocs,
operations)
@@ -150,9 +168,12 @@
# for the benefit of tests
faildescr._x86_bridge_stack_depth = stack_depth
# patch the jump from original guard
+ self.patch_jump(faildescr, adr_bridge)
+
+ def patch_jump(self, faildescr, adr_new_target):
adr_jump_offset = faildescr._x86_adr_jump_offset
mc = codebuf.InMemoryCodeBuilder(adr_jump_offset, adr_jump_offset + 4)
- mc.write(packimm32(adr_bridge - adr_jump_offset - 4))
+ mc.write(packimm32(adr_new_target - adr_jump_offset - 4))
mc.valgrind_invalidated()
mc.done()
@@ -743,50 +764,270 @@
def implement_guard_recovery(self, guard_opnum, faildescr, failargs,
fail_locs):
self._no_const_locs(failargs)
- addr = self.mc2.tell()
exc = (guard_opnum == rop.GUARD_EXCEPTION or
guard_opnum == rop.GUARD_NO_EXCEPTION)
- faildescr._x86_faillocs = fail_locs
- self.generate_failure(self.mc2, faildescr, failargs, fail_locs, exc)
+ return self.generate_quick_failure(faildescr, failargs, fail_locs, exc)
+
+ def generate_quick_failure(self, faildescr, failargs, fail_locs, exc):
+ """Generate the initial code for handling a failure. We try to
+ keep it as compact as possible. The idea is that this code is
+ executed at most once (and very often, zero times); when
+ executed, it generates a more complete piece of code which can
+ really handle recovery from this particular failure.
+ """
+ fail_index = self.cpu.get_fail_descr_number(faildescr)
+ bytes_needed = 20 + 5 * len(failargs) # conservative estimate
+ if self.mc2.bytes_free() < bytes_needed:
+ self.mc2.make_new_mc()
+ mc = self.mc2._mc
+ addr = mc.tell()
+ withfloats = False
+ for box in failargs:
+ if box.type == FLOAT:
+ withfloats = True
+ break
+ mc.CALL(rel32(self.failure_recovery_code[exc + 2 * withfloats]))
+ # write tight data that describes the failure recovery
+ faildescr._x86_failure_recovery_bytecode = mc.tell()
+ self.write_failure_recovery_description(mc, failargs, fail_locs)
+ # write the fail_index too
+ mc.write(packimm32(fail_index))
+ # for testing the decoding, write a final byte 0xCC
+ if not we_are_translated():
+ mc.writechr(0xCC)
+ faildescr._x86_debug_faillocs = fail_locs
return addr
- def generate_failure(self, mc, faildescr, failargs, locs, exc):
- pos = mc.tell()
+ DESCR_REF = 0x00
+ DESCR_INT = 0x01
+ DESCR_FLOAT = 0x02
+ DESCR_FROMSTACK = 8
+ DESCR_STOP = DESCR_INT + 4*esp.op
+
+ def write_failure_recovery_description(self, mc, failargs, locs):
for i in range(len(failargs)):
arg = failargs[i]
- if arg is None: # hole
- continue
+ if arg.type == REF:
+ kind = self.DESCR_REF
+ elif arg.type == INT:
+ kind = self.DESCR_INT
+ elif arg.type == FLOAT:
+ kind = self.DESCR_FLOAT
+ else:
+ raise AssertionError("bogus kind")
+ loc = locs[i]
+ if isinstance(loc, MODRM):
+ n = self.DESCR_FROMSTACK + loc.position
+ else:
+ assert isinstance(loc, REG)
+ n = loc.op
+ n = kind + 4*n
+ while n > 0x7F:
+ mc.writechr((n & 0x7F) | 0x80)
+ n >>= 7
+ mc.writechr(n)
+ mc.writechr(self.DESCR_STOP)
+ # preallocate the fail_boxes
+ i = len(failargs) - 1
+ if i >= 0:
+ self.fail_boxes_int.get_addr_for_num(i)
+ self.fail_boxes_ptr.get_addr_for_num(i)
+ if self.cpu.supports_floats:
+ self.fail_boxes_float.get_addr_for_num(i)
+
+ def rebuild_faillocs_from_descr(self, bytecode):
+ from pypy.jit.backend.x86.regalloc import X86StackManager
+ bytecode = rffi.cast(rffi.UCHARP, bytecode)
+ arglocs = []
+ while 1:
+ # decode the next instruction from the bytecode
+ code = rffi.cast(lltype.Signed, bytecode[0])
+ bytecode = rffi.ptradd(bytecode, 1)
+ if code >= 4*self.DESCR_FROMSTACK:
+ # 'code' identifies a stack location
+ if code > 0x7F:
+ shift = 7
+ code &= 0x7F
+ while True:
+ nextcode = rffi.cast(lltype.Signed, bytecode[0])
+ bytecode = rffi.ptradd(bytecode, 1)
+ code |= (nextcode & 0x7F) << shift
+ shift += 7
+ if nextcode <= 0x7F:
+ break
+ kind = code & 3
+ code = (code >> 2) - self.DESCR_FROMSTACK
+ if kind == self.DESCR_FLOAT:
+ size = 2
+ else:
+ size = 1
+ loc = X86StackManager.stack_pos(code, size)
+ elif code == self.DESCR_STOP:
+ break
+ else:
+ # 'code' identifies a register
+ kind = code & 3
+ code >>= 2
+ if kind == self.DESCR_FLOAT:
+ loc = xmm_registers[code]
+ else:
+ loc = registers[code]
+ arglocs.append(loc)
+ return arglocs[:]
+
+ def setup_failure_recovery(self):
+
+ def failure_recovery_func(registers):
+ # no malloc allowed here!!
+ # 'registers' is a pointer to a structure containing the
+ # original value of the registers, optionally the original
+ # value of XMM registers, and finally a reference to the
+ # recovery bytecode. See _build_failure_recovery() for details.
+ stack_at_ebp = registers[ebp.op]
+ bytecode = rffi.cast(rffi.UCHARP, registers[8])
+ num = 0
+ value_hi = 0
+ while 1:
+ # decode the next instruction from the bytecode
+ code = rffi.cast(lltype.Signed, bytecode[0])
+ bytecode = rffi.ptradd(bytecode, 1)
+ if code >= 4*self.DESCR_FROMSTACK:
+ if code > 0x7F:
+ shift = 7
+ code &= 0x7F
+ while True:
+ nextcode = rffi.cast(lltype.Signed, bytecode[0])
+ bytecode = rffi.ptradd(bytecode, 1)
+ code |= (nextcode & 0x7F) << shift
+ shift += 7
+ if nextcode <= 0x7F:
+ break
+ # load the value from the stack
+ kind = code & 3
+ code = (code >> 2) - self.DESCR_FROMSTACK
+ stackloc = stack_at_ebp + get_ebp_ofs(code)
+ value = rffi.cast(rffi.LONGP, stackloc)[0]
+ if kind == self.DESCR_FLOAT:
+ value_hi = value
+ value = rffi.cast(rffi.LONGP, stackloc - 4)[0]
+ elif code == self.DESCR_STOP:
+ break
+ else:
+ # 'code' identifies a register: load its value
+ kind = code & 3
+ code >>= 2
+ if kind == self.DESCR_FLOAT:
+ xmmregisters = rffi.ptradd(registers, -16)
+ value = xmmregisters[2*code]
+ value_hi = xmmregisters[2*code + 1]
+ else:
+ value = registers[code]
+
+ # store the loaded value into fail_boxes_<type>
+ if kind == self.DESCR_INT:
+ tgt = self.fail_boxes_int.get_addr_for_num(num)
+ elif kind == self.DESCR_REF:
+ tgt = self.fail_boxes_ptr.get_addr_for_num(num)
+ elif kind == self.DESCR_FLOAT:
+ tgt = self.fail_boxes_float.get_addr_for_num(num)
+ rffi.cast(rffi.LONGP, tgt)[1] = value_hi
+ else:
+ assert 0, "bogus kind"
+ rffi.cast(rffi.LONGP, tgt)[0] = value
+ num += 1
+ #
+ if not we_are_translated():
+ assert bytecode[4] == 0xCC
+ fail_index = rffi.cast(rffi.LONGP, bytecode)[0]
+ return fail_index
+
+ self.failure_recovery_func = failure_recovery_func
+ self.failure_recovery_code = [0, 0, 0, 0]
+
+ _FAILURE_RECOVERY_FUNC = lltype.Ptr(lltype.FuncType([rffi.LONGP],
+ lltype.Signed))
+
+ def _build_failure_recovery(self, exc, withfloats=False):
+ failure_recovery_func = llhelper(self._FAILURE_RECOVERY_FUNC,
+ self.failure_recovery_func)
+ failure_recovery_func = rffi.cast(lltype.Signed,
+ failure_recovery_func)
+ mc = self.mc2._mc
+ # Assume that we are called at the beginning, when there is no risk
+ # that 'mc' runs out of space. Checked by asserts in mc.write().
+ recovery_addr = mc.tell()
+ mc.PUSH(edi)
+ mc.PUSH(esi)
+ mc.PUSH(ebp)
+ mc.PUSH(esp) # <-- not really used, but needed to take up the space
+ mc.PUSH(ebx)
+ mc.PUSH(edx)
+ mc.PUSH(ecx)
+ mc.PUSH(eax)
+ mc.MOV(esi, esp)
+ if withfloats:
+ mc.SUB(esp, imm(8*8))
+ for i in range(8):
+ mc.MOVSD(mem64(esp, 8*i), xmm_registers[i])
+
+ # we call a provided function that will
+ # - call our on_leave_jitted_hook which will mark
+ # the fail_boxes_ptr array as pointing to young objects to
+ # avoid unwarranted freeing
+ # - optionally save exception depending on the flag
+ addr = self.cpu.get_on_leave_jitted_int(save_exception=exc)
+ mc.CALL(rel32(addr))
+
+ # the following call saves all values from the stack and from
+ # registers to the right 'fail_boxes_<type>' location.
+ # Note that the registers are saved so far in esi[0] to esi[7],
+ # as pushed above, plus optionally in esi[-16] to esi[-1] for
+ # the XMM registers. Moreover, esi[8] is a pointer to the recovery
+ # bytecode, pushed just before by the CALL instruction written by
+ # generate_quick_failure().
+ mc.PUSH(esi)
+ mc.CALL(rel32(failure_recovery_func))
+ # returns in eax the fail_index
+
+ # now we return from the complete frame, which starts from
+ # _assemble_bootstrap_code(). The LEA below throws away most
+ # of the frame, including all the PUSHes that we did just above.
+ mc.LEA(esp, addr_add(ebp, imm((-RET_BP + 2) * WORD)))
+ mc.POP(edi)
+ mc.POP(esi)
+ mc.POP(ebx)
+ mc.POP(ebp)
+ mc.RET()
+ self.mc2.done()
+ self.failure_recovery_code[exc + 2 * withfloats] = recovery_addr
+
+ def generate_failure(self, mc, fail_index, locs, exc, locs_are_ref):
+ for i in range(len(locs)):
loc = locs[i]
if isinstance(loc, REG):
- if arg.type == FLOAT:
+ if loc.width == 8:
adr = self.fail_boxes_float.get_addr_for_num(i)
mc.MOVSD(heap64(adr), loc)
else:
- if arg.type == REF:
+ if locs_are_ref[i]:
adr = self.fail_boxes_ptr.get_addr_for_num(i)
else:
adr = self.fail_boxes_int.get_addr_for_num(i)
mc.MOV(heap(adr), loc)
- for i in range(len(failargs)):
- arg = failargs[i]
- if arg is None: # hole
- continue
+ for i in range(len(locs)):
loc = locs[i]
if not isinstance(loc, REG):
- if arg.type == FLOAT:
+ if loc.width == 8:
mc.MOVSD(xmm0, loc)
adr = self.fail_boxes_float.get_addr_for_num(i)
mc.MOVSD(heap64(adr), xmm0)
else:
- if arg.type == REF:
+ if locs_are_ref[i]:
adr = self.fail_boxes_ptr.get_addr_for_num(i)
else:
adr = self.fail_boxes_int.get_addr_for_num(i)
mc.MOV(eax, loc)
mc.MOV(heap(adr), eax)
- if self.debug_markers:
- mc.MOV(eax, imm(pos))
- mc.MOV(heap(self.fail_boxes_int.get_addr_for_num(len(locs))), eax)
# we call a provided function that will
# - call our on_leave_jitted_hook which will mark
@@ -798,9 +1039,7 @@
# don't break the following code sequence!
mc = mc._mc
- mc.LEA(esp, addr_add(imm(0), ebp, (-RET_BP + 2) * WORD))
- assert isinstance(faildescr, AbstractFailDescr)
- fail_index = faildescr.get_index()
+ mc.LEA(esp, addr_add(ebp, imm((-RET_BP + 2) * WORD)))
mc.MOV(eax, imm(fail_index))
mc.POP(edi)
mc.POP(esi)
Modified: pypy/branch/shorter-guard-path-2/pypy/jit/backend/x86/regalloc.py
==============================================================================
--- pypy/branch/shorter-guard-path-2/pypy/jit/backend/x86/regalloc.py (original)
+++ pypy/branch/shorter-guard-path-2/pypy/jit/backend/x86/regalloc.py Tue Nov 24 14:29:46 2009
@@ -397,8 +397,10 @@
def consider_finish(self, op, ignored):
locs = [self.loc(v) for v in op.args]
- self.assembler.generate_failure(self.assembler.mc, op.descr, op.args,
- locs, self.exc)
+ locs_are_ref = [v.type == REF for v in op.args]
+ fail_index = self.assembler.cpu.get_fail_descr_number(op.descr)
+ self.assembler.generate_failure(self.assembler.mc, fail_index, locs,
+ self.exc, locs_are_ref)
self.possibly_free_vars(op.args)
def consider_guard_no_exception(self, op, ignored):
Modified: pypy/branch/shorter-guard-path-2/pypy/jit/backend/x86/ri386setup.py
==============================================================================
--- pypy/branch/shorter-guard-path-2/pypy/jit/backend/x86/ri386setup.py (original)
+++ pypy/branch/shorter-guard-path-2/pypy/jit/backend/x86/ri386setup.py Tue Nov 24 14:29:46 2009
@@ -459,6 +459,13 @@
SAHF = Instruction()
SAHF.mode0(['\x9E'])
+LODSB = Instruction()
+LODSB.mode0(['\xAC'])
+
+LODSD = Instruction()
+LODSD.mode0(['\xAD'])
+LODSD.as_alias = "LODSL"
+
# ------------------------- floating point instructions ------------------
FLDL = Instruction()
Modified: pypy/branch/shorter-guard-path-2/pypy/jit/backend/x86/runner.py
==============================================================================
--- pypy/branch/shorter-guard-path-2/pypy/jit/backend/x86/runner.py (original)
+++ pypy/branch/shorter-guard-path-2/pypy/jit/backend/x86/runner.py Tue Nov 24 14:29:46 2009
@@ -63,7 +63,7 @@
addr = executable_token._x86_bootstrap_code
func = rffi.cast(lltype.Ptr(self.BOOTSTRAP_TP), addr)
fail_index = self._execute_call(func)
- return fail_index
+ return self.get_fail_descr_from_number(fail_index)
def _execute_call(self, func):
# help flow objspace
Modified: pypy/branch/shorter-guard-path-2/pypy/jit/backend/x86/support.py
==============================================================================
--- pypy/branch/shorter-guard-path-2/pypy/jit/backend/x86/support.py (original)
+++ pypy/branch/shorter-guard-path-2/pypy/jit/backend/x86/support.py Tue Nov 24 14:29:46 2009
@@ -3,7 +3,8 @@
from pypy.rlib import rgc
from pypy.rlib.objectmodel import we_are_translated
-CHUNK_SIZE = 1000
+CHUNK_SIZE_BITS = 8
+CHUNK_SIZE = 1 << CHUNK_SIZE_BITS
def new_nonmovable_growable_array(TP):
ATP = lltype.GcArray(TP)
@@ -34,7 +35,7 @@
def _no_of(self, i):
while i >= len(self.chunks) * CHUNK_SIZE:
self._grow()
- return i / CHUNK_SIZE, i % CHUNK_SIZE
+ return i >> CHUNK_SIZE_BITS, i & (CHUNK_SIZE-1)
_no_of._always_inline_ = True
def setitem(self, i, v):
Modified: pypy/branch/shorter-guard-path-2/pypy/jit/backend/x86/test/test_recompilation.py
==============================================================================
--- pypy/branch/shorter-guard-path-2/pypy/jit/backend/x86/test/test_recompilation.py (original)
+++ pypy/branch/shorter-guard-path-2/pypy/jit/backend/x86/test/test_recompilation.py Tue Nov 24 14:29:46 2009
@@ -21,7 +21,7 @@
bridge = self.attach_bridge(ops, loop, -2)
self.cpu.set_future_value_int(0, 0)
fail = self.run(loop)
- assert fail == 2
+ assert fail.identifier == 2
assert self.getint(0) == 21
def test_compile_bridge_deeper(self):
@@ -52,7 +52,7 @@
assert new > previous
self.cpu.set_future_value_int(0, 0)
fail = self.run(loop)
- assert fail == 2
+ assert fail.identifier == 2
assert self.getint(0) == 21
assert self.getint(1) == 22
assert self.getint(2) == 23
@@ -78,7 +78,7 @@
bridge = self.attach_bridge(ops, other_loop, 0, looptoken=loop.token)
self.cpu.set_future_value_int(0, 1)
fail = self.run(other_loop)
- assert fail == 1
+ assert fail.identifier == 1
def test_bridge_jumps_to_self_deeper(self):
loop = self.interpret('''
Modified: pypy/branch/shorter-guard-path-2/pypy/jit/backend/x86/test/test_ri386_auto_encoding.py
==============================================================================
--- pypy/branch/shorter-guard-path-2/pypy/jit/backend/x86/test/test_ri386_auto_encoding.py (original)
+++ pypy/branch/shorter-guard-path-2/pypy/jit/backend/x86/test/test_ri386_auto_encoding.py Tue Nov 24 14:29:46 2009
@@ -92,7 +92,7 @@
return [pick1(i386.memSIB64) for i in range(COUNT2)]
def xmm_tests():
- return i386.xmm_registers
+ return i386.xmm_registers[:]
def modrm8_tests():
return i386.registers8 + [pick1(i386.memSIB8) for i in range(COUNT2)]
Modified: pypy/branch/shorter-guard-path-2/pypy/jit/backend/x86/test/test_runner.py
==============================================================================
--- pypy/branch/shorter-guard-path-2/pypy/jit/backend/x86/test/test_runner.py (original)
+++ pypy/branch/shorter-guard-path-2/pypy/jit/backend/x86/test/test_runner.py Tue Nov 24 14:29:46 2009
@@ -260,7 +260,7 @@
self.cpu.set_future_value_int(0, b.value)
else:
self.cpu.set_future_value_ref(0, b.value)
- r = self.cpu.execute_token(looptoken)
+ self.cpu.execute_token(looptoken)
result = self.cpu.get_latest_value_int(0)
if guard == rop.GUARD_FALSE:
assert result == execute(self.cpu, op, None, b).value
@@ -306,7 +306,7 @@
self.cpu.compile_loop(inputargs, ops, looptoken)
for i, box in enumerate(inputargs):
self.cpu.set_future_value_int(i, box.value)
- r = self.cpu.execute_token(looptoken)
+ self.cpu.execute_token(looptoken)
result = self.cpu.get_latest_value_int(0)
expected = execute(self.cpu, op, None, a, b).value
if guard == rop.GUARD_FALSE:
@@ -314,31 +314,27 @@
else:
assert result != expected
- def test_overflow_mc(self):
- from pypy.jit.backend.x86.assembler import MachineCodeBlockWrapper
- orig_size = MachineCodeBlockWrapper.MC_SIZE
- MachineCodeBlockWrapper.MC_SIZE = 1024
- old_mc = self.cpu.assembler.mc
- old_mc2 = self.cpu.assembler.mc2
- self.cpu.assembler.mc = None
- try:
- ops = []
- base_v = BoxInt()
- v = base_v
- for i in range(1024):
- next_v = BoxInt()
- ops.append(ResOperation(rop.INT_ADD, [v, ConstInt(1)], next_v))
- v = next_v
- ops.append(ResOperation(rop.FINISH, [v], None,
- descr=BasicFailDescr()))
- looptoken = LoopToken()
- self.cpu.compile_loop([base_v], ops, looptoken)
- assert self.cpu.assembler.mc != old_mc # overflowed
- self.cpu.set_future_value_int(0, base_v.value)
- self.cpu.execute_token(looptoken)
- assert self.cpu.get_latest_value_int(0) == 1024
- finally:
- MachineCodeBlockWrapper.MC_SIZE = orig_size
- self.cpu.assembler.mc = old_mc
- self.cpu.assembler.mc2 = old_mc2
+class TestX86OverflowMC(TestX86):
+
+ def setup_class(cls):
+ cls.cpu = CPU(rtyper=None, stats=FakeStats())
+ cls.cpu.assembler.mc_size = 1024
+
+ def test_overflow_mc(self):
+ ops = []
+ base_v = BoxInt()
+ v = base_v
+ for i in range(1024):
+ next_v = BoxInt()
+ ops.append(ResOperation(rop.INT_ADD, [v, ConstInt(1)], next_v))
+ v = next_v
+ ops.append(ResOperation(rop.FINISH, [v], None,
+ descr=BasicFailDescr()))
+ looptoken = LoopToken()
+ old_mc_mc = self.cpu.assembler.mc._mc
+ self.cpu.compile_loop([base_v], ops, looptoken)
+ assert self.cpu.assembler.mc._mc != old_mc_mc # overflowed
+ self.cpu.set_future_value_int(0, base_v.value)
+ self.cpu.execute_token(looptoken)
+ assert self.cpu.get_latest_value_int(0) == 1024
Modified: pypy/branch/shorter-guard-path-2/pypy/jit/metainterp/compile.py
==============================================================================
--- pypy/branch/shorter-guard-path-2/pypy/jit/metainterp/compile.py (original)
+++ pypy/branch/shorter-guard-path-2/pypy/jit/metainterp/compile.py Tue Nov 24 14:29:46 2009
@@ -113,7 +113,7 @@
metainterp_sd.log("compiled new " + type)
def send_bridge_to_backend(metainterp_sd, faildescr, inputargs, operations):
- n = faildescr.get_index()
+ n = metainterp_sd.cpu.get_fail_descr_number(faildescr)
metainterp_sd.logger_ops.log_bridge(inputargs, operations, n)
if not we_are_translated():
show_loop(metainterp_sd)
@@ -133,14 +133,7 @@
# ____________________________________________________________
class _DoneWithThisFrameDescr(AbstractFailDescr):
-
- def __init__(self, lst):
- "NOT_RPYTHON"
- self.index = len(lst)
- lst.append(self)
-
- def get_index(self):
- return self.index
+ pass
class DoneWithThisFrameDescrVoid(_DoneWithThisFrameDescr):
def handle_fail(self, metainterp_sd):
@@ -173,18 +166,6 @@
raise metainterp_sd.ExitFrameWithExceptionRef(cpu, value)
-done_with_this_frame_descrs = []
-done_with_this_frame_descr_void = DoneWithThisFrameDescrVoid(
- done_with_this_frame_descrs)
-done_with_this_frame_descr_int = DoneWithThisFrameDescrInt(
- done_with_this_frame_descrs)
-done_with_this_frame_descr_ref = DoneWithThisFrameDescrRef(
- done_with_this_frame_descrs)
-done_with_this_frame_descr_float = DoneWithThisFrameDescrFloat(
- done_with_this_frame_descrs)
-exit_frame_with_exception_descr_ref = ExitFrameWithExceptionDescrRef(
- done_with_this_frame_descrs)
-
prebuiltNotSpecNode = NotSpecNode()
class TerminatingLoopToken(LoopToken):
@@ -194,22 +175,30 @@
self.specnodes = [prebuiltNotSpecNode]*nargs
self.finishdescr = finishdescr
-# pseudo loop tokens to make the life of optimize.py easier
-loop_tokens_done_with_this_frame_int = [
- TerminatingLoopToken(1, done_with_this_frame_descr_int)
- ]
-loop_tokens_done_with_this_frame_ref = [
- TerminatingLoopToken(1, done_with_this_frame_descr_ref)
- ]
-loop_tokens_done_with_this_frame_float = [
- TerminatingLoopToken(1, done_with_this_frame_descr_float)
- ]
-loop_tokens_done_with_this_frame_void = [
- TerminatingLoopToken(0, done_with_this_frame_descr_void)
- ]
-loop_tokens_exit_frame_with_exception_ref = [
- TerminatingLoopToken(1, exit_frame_with_exception_descr_ref)
- ]
+def make_done_loop_tokens():
+ done_with_this_frame_descr_void = DoneWithThisFrameDescrVoid()
+ done_with_this_frame_descr_int = DoneWithThisFrameDescrInt()
+ done_with_this_frame_descr_ref = DoneWithThisFrameDescrRef()
+ done_with_this_frame_descr_float = DoneWithThisFrameDescrFloat()
+ exit_frame_with_exception_descr_ref = ExitFrameWithExceptionDescrRef()
+
+ # pseudo loop tokens to make the life of optimize.py easier
+ return {'loop_tokens_done_with_this_frame_int': [
+ TerminatingLoopToken(1, done_with_this_frame_descr_int)
+ ],
+ 'loop_tokens_done_with_this_frame_ref': [
+ TerminatingLoopToken(1, done_with_this_frame_descr_ref)
+ ],
+ 'loop_tokens_done_with_this_frame_float': [
+ TerminatingLoopToken(1, done_with_this_frame_descr_float)
+ ],
+ 'loop_tokens_done_with_this_frame_void': [
+ TerminatingLoopToken(0, done_with_this_frame_descr_void)
+ ],
+ 'loop_tokens_exit_frame_with_exception_ref': [
+ TerminatingLoopToken(1, exit_frame_with_exception_descr_ref)
+ ],
+ }
class ResumeDescr(AbstractFailDescr):
def __init__(self, original_greenkey):
@@ -222,13 +211,6 @@
def __init__(self, metainterp_sd, original_greenkey):
ResumeDescr.__init__(self, original_greenkey)
self.metainterp_sd = metainterp_sd
- self.index = -1
-
- def get_index(self):
- if self.index == -1:
- globaldata = self.metainterp_sd.globaldata
- self.index = globaldata.get_fail_descr_number(self)
- return self.index
def store_final_boxes(self, guard_op, boxes):
guard_op.fail_args = boxes
Modified: pypy/branch/shorter-guard-path-2/pypy/jit/metainterp/history.py
==============================================================================
--- pypy/branch/shorter-guard-path-2/pypy/jit/metainterp/history.py (original)
+++ pypy/branch/shorter-guard-path-2/pypy/jit/metainterp/history.py Tue Nov 24 14:29:46 2009
@@ -123,21 +123,16 @@
return '%r' % (self,)
class AbstractFailDescr(AbstractDescr):
+ index = -1
- def get_index(self):
- raise NotImplementedError
def handle_fail(self, metainterp_sd):
raise NotImplementedError
def compile_and_attach(self, metainterp, new_loop):
raise NotImplementedError
class BasicFailDescr(AbstractFailDescr):
-
- def __init__(self, index=-1):
- self.index = index
-
- def get_index(self):
- return self.index
+ def __init__(self, identifier=None):
+ self.identifier = identifier # for testing
class AbstractMethDescr(AbstractDescr):
# the base class of the result of cpu.methdescrof()
Modified: pypy/branch/shorter-guard-path-2/pypy/jit/metainterp/logger.py
==============================================================================
--- pypy/branch/shorter-guard-path-2/pypy/jit/metainterp/logger.py (original)
+++ pypy/branch/shorter-guard-path-2/pypy/jit/metainterp/logger.py Tue Nov 24 14:29:46 2009
@@ -90,8 +90,8 @@
if op.descr is not None:
descr = op.descr
if is_guard and self.guard_number:
- assert isinstance(descr, AbstractFailDescr)
- r = "<Guard%d>" % descr.get_index()
+ index = self.metainterp_sd.cpu.get_fail_descr_number(descr)
+ r = "<Guard%d>" % index
else:
r = self.repr_of_descr(descr)
args += ', descr=' + r
Modified: pypy/branch/shorter-guard-path-2/pypy/jit/metainterp/pyjitpl.py
==============================================================================
--- pypy/branch/shorter-guard-path-2/pypy/jit/metainterp/pyjitpl.py (original)
+++ pypy/branch/shorter-guard-path-2/pypy/jit/metainterp/pyjitpl.py Tue Nov 24 14:29:46 2009
@@ -1022,6 +1022,8 @@
self._addr2name_keys = []
self._addr2name_values = []
+ self.__dict__.update(compile.make_done_loop_tokens())
+
def _freeze_(self):
return True
@@ -1044,8 +1046,7 @@
else:
self.num_green_args = 0
self.state = None
- self.globaldata = MetaInterpGlobalData(
- self, compile.done_with_this_frame_descrs)
+ self.globaldata = MetaInterpGlobalData(self)
def _setup_once(self):
"""Runtime setup needed by the various components of the JIT."""
@@ -1136,11 +1137,10 @@
# ____________________________________________________________
class MetaInterpGlobalData(object):
- def __init__(self, staticdata, prebuilt_fail_descr_list):
+ def __init__(self, staticdata):
self.initialized = False
self.indirectcall_dict = None
self.addr2name = None
- self.fail_descr_list = prebuilt_fail_descr_list[:]
self.loopnumbering = 0
#
state = staticdata.state
@@ -1164,16 +1164,6 @@
cell.compiled_merge_points = []
return cell.compiled_merge_points
- def get_fail_descr_number(self, descr):
- assert isinstance(descr, history.AbstractFailDescr)
- lst = self.fail_descr_list
- n = len(lst)
- lst.append(descr)
- return n
-
- def get_fail_descr_from_number(self, n):
- return self.fail_descr_list[n]
-
# ____________________________________________________________
class MetaInterp(object):
@@ -1622,16 +1612,16 @@
if sd.result_type == 'void':
assert exitbox is None
exits = []
- loop_tokens = compile.loop_tokens_done_with_this_frame_void
+ loop_tokens = sd.loop_tokens_done_with_this_frame_void
elif sd.result_type == 'int':
exits = [exitbox]
- loop_tokens = compile.loop_tokens_done_with_this_frame_int
+ loop_tokens = sd.loop_tokens_done_with_this_frame_int
elif sd.result_type == 'ref':
exits = [exitbox]
- loop_tokens = compile.loop_tokens_done_with_this_frame_ref
+ loop_tokens = sd.loop_tokens_done_with_this_frame_ref
elif sd.result_type == 'float':
exits = [exitbox]
- loop_tokens = compile.loop_tokens_done_with_this_frame_float
+ loop_tokens = sd.loop_tokens_done_with_this_frame_float
else:
assert False
self.history.record(rop.JUMP, exits, None)
@@ -1643,7 +1633,8 @@
self.gen_store_back_in_virtualizable()
# temporarily put a JUMP to a pseudo-loop
self.history.record(rop.JUMP, [valuebox], None)
- loop_tokens = compile.loop_tokens_exit_frame_with_exception_ref
+ sd = self.staticdata
+ loop_tokens = sd.loop_tokens_exit_frame_with_exception_ref
target_loop_token = compile.compile_new_bridge(self, loop_tokens,
self.resumekey)
assert target_loop_token is loop_tokens[0]
Modified: pypy/branch/shorter-guard-path-2/pypy/jit/metainterp/test/test_compile.py
==============================================================================
--- pypy/branch/shorter-guard-path-2/pypy/jit/metainterp/test/test_compile.py (original)
+++ pypy/branch/shorter-guard-path-2/pypy/jit/metainterp/test/test_compile.py Tue Nov 24 14:29:46 2009
@@ -103,22 +103,3 @@
assert loop_tokens == [loop_token]
assert len(cpu.seen) == 0
assert staticdata.globaldata.loopnumbering == 2
-
-def test_resumeguarddescr_get_index():
- from pypy.jit.metainterp.pyjitpl import MetaInterpGlobalData
-
- class FakeStaticData:
- state = None
- virtualizable_info = None
- gd = MetaInterpGlobalData(FakeStaticData, [])
- FakeStaticData.globaldata = gd
-
- rgd = ResumeGuardDescr(FakeStaticData, ())
-
- fail_index = rgd.get_index()
- fail_index1 = rgd.get_index()
-
- assert fail_index == fail_index1
-
- assert gd.get_fail_descr_from_number(fail_index) is rgd
-
Modified: pypy/branch/shorter-guard-path-2/pypy/jit/metainterp/test/test_logger.py
==============================================================================
--- pypy/branch/shorter-guard-path-2/pypy/jit/metainterp/test/test_logger.py (original)
+++ pypy/branch/shorter-guard-path-2/pypy/jit/metainterp/test/test_logger.py Tue Nov 24 14:29:46 2009
@@ -6,6 +6,8 @@
from StringIO import StringIO
from pypy.jit.metainterp.test.test_optimizeopt import equaloplists
from pypy.jit.metainterp.history import AbstractDescr, LoopToken, BasicFailDescr
+from pypy.jit.backend.model import AbstractCPU
+
class Descr(AbstractDescr):
pass
@@ -36,8 +38,8 @@
def make_metainterp_sd(self):
class FakeMetaInterpSd:
- class cpu:
- ts = self.ts
+ cpu = AbstractCPU()
+ cpu.ts = self.ts
def get_name_from_address(self, addr):
return 'Name'
return FakeMetaInterpSd()
@@ -122,7 +124,7 @@
pure_parse(output)
def test_guard_descr(self):
- namespace = {'fdescr': BasicFailDescr(4)}
+ namespace = {'fdescr': BasicFailDescr()}
inp = '''
[i0]
guard_true(i0, descr=fdescr) [i0]
@@ -130,15 +132,14 @@
loop = pure_parse(inp, namespace=namespace)
logger = Logger(self.make_metainterp_sd(), guard_number=True)
output = logger.log_loop(loop)
- assert output.splitlines()[-1] == "guard_true(i0, descr=<Guard4>) [i0]"
+ assert output.splitlines()[-1] == "guard_true(i0, descr=<Guard0>) [i0]"
pure_parse(output)
- def boom():
- raise Exception
- namespace['fdescr'].get_index = boom
logger = Logger(self.make_metainterp_sd(), guard_number=False)
output = logger.log_loop(loop)
- assert output.splitlines()[-1].startswith("guard_true(i0, descr=<")
+ lastline = output.splitlines()[-1]
+ assert lastline.startswith("guard_true(i0, descr=<")
+ assert not lastline.startswith("guard_true(i0, descr=<Guard")
def test_class_name(self):
from pypy.rpython.lltypesystem import lltype
Modified: pypy/branch/shorter-guard-path-2/pypy/jit/metainterp/test/test_pyjitpl.py
==============================================================================
--- pypy/branch/shorter-guard-path-2/pypy/jit/metainterp/test/test_pyjitpl.py (original)
+++ pypy/branch/shorter-guard-path-2/pypy/jit/metainterp/test/test_pyjitpl.py Tue Nov 24 14:29:46 2009
@@ -38,35 +38,6 @@
if rop._NOSIDEEFFECT_FIRST <= opnum <= rop._NOSIDEEFFECT_LAST:
assert hasattr(pyjitpl.MIFrame, 'opimpl_' + opname.lower()), opname
-def test_faildescr_numbering():
- class FakeStaticData:
- state = None
- virtualizable_info = None
-
- fail_descr0 = AbstractFailDescr()
- lst = [fail_descr0]
- gd = pyjitpl.MetaInterpGlobalData(FakeStaticData, lst)
- assert gd.fail_descr_list is not lst
-
- fail_descr = gd.get_fail_descr_from_number(0)
- assert fail_descr is fail_descr0
-
- fail_descr1 = AbstractFailDescr()
- fail_descr2 = AbstractFailDescr()
-
- n1 = gd.get_fail_descr_number(fail_descr1)
- n2 = gd.get_fail_descr_number(fail_descr2)
- assert n1 != n2
-
- fail_descr = gd.get_fail_descr_from_number(n1)
- assert fail_descr is fail_descr1
- fail_descr = gd.get_fail_descr_from_number(n2)
- assert fail_descr is fail_descr2
-
- # doesn't provide interning on its own
- n1_1 = gd.get_fail_descr_number(fail_descr1)
- assert n1_1 != n1
-
def test_portal_trace_positions():
jitcode = codewriter.JitCode("f")
jitcode.code = jitcode.constants = None
Modified: pypy/branch/shorter-guard-path-2/pypy/jit/metainterp/warmstate.py
==============================================================================
--- pypy/branch/shorter-guard-path-2/pypy/jit/metainterp/warmstate.py (original)
+++ pypy/branch/shorter-guard-path-2/pypy/jit/metainterp/warmstate.py Tue Nov 24 14:29:46 2009
@@ -244,10 +244,9 @@
while True: # until interrupted by an exception
metainterp_sd.profiler.start_running()
debug_start("jit-running")
- fail_index = metainterp_sd.cpu.execute_token(loop_token)
+ fail_descr = metainterp_sd.cpu.execute_token(loop_token)
debug_stop("jit-running")
metainterp_sd.profiler.end_running()
- fail_descr = globaldata.get_fail_descr_from_number(fail_index)
loop_token = fail_descr.handle_fail(metainterp_sd)
maybe_compile_and_run._dont_inline_ = True
Modified: pypy/branch/shorter-guard-path-2/pypy/objspace/std/multimethod.py
==============================================================================
--- pypy/branch/shorter-guard-path-2/pypy/objspace/std/multimethod.py (original)
+++ pypy/branch/shorter-guard-path-2/pypy/objspace/std/multimethod.py Tue Nov 24 14:29:46 2009
@@ -29,6 +29,9 @@
self.w_type = w_type
self.w_value = w_value
+ def __str__(self):
+ return '<FailedToImplement(%s, %s)>' % (self.w_type, self.w_value)
+
def raiseFailedToImplement():
raise FailedToImplement
More information about the Pypy-commit
mailing list