[pypy-svn] r74543 - in pypy/branch/blackhole-improvement/pypy/jit: backend backend/llgraph backend/x86 codewriter codewriter/test metainterp metainterp/test
arigo at codespeak.net
arigo at codespeak.net
Tue May 18 17:04:46 CEST 2010
Author: arigo
Date: Tue May 18 17:04:44 2010
New Revision: 74543
Modified:
pypy/branch/blackhole-improvement/pypy/jit/backend/llgraph/llimpl.py
pypy/branch/blackhole-improvement/pypy/jit/backend/llgraph/runner.py
pypy/branch/blackhole-improvement/pypy/jit/backend/model.py
pypy/branch/blackhole-improvement/pypy/jit/backend/x86/assembler.py
pypy/branch/blackhole-improvement/pypy/jit/backend/x86/support.py
pypy/branch/blackhole-improvement/pypy/jit/codewriter/assembler.py
pypy/branch/blackhole-improvement/pypy/jit/codewriter/flatten.py
pypy/branch/blackhole-improvement/pypy/jit/codewriter/jitcode.py
pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_assembler.py
pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_codewriter.py
pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_flatten.py
pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_format.py
pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_jitcode.py
pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_liveness.py
pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_regalloc.py
pypy/branch/blackhole-improvement/pypy/jit/metainterp/blackhole.py
pypy/branch/blackhole-improvement/pypy/jit/metainterp/compile.py
pypy/branch/blackhole-improvement/pypy/jit/metainterp/pyjitpl.py
pypy/branch/blackhole-improvement/pypy/jit/metainterp/resume.py
pypy/branch/blackhole-improvement/pypy/jit/metainterp/test/test_basic.py
pypy/branch/blackhole-improvement/pypy/jit/metainterp/typesystem.py
pypy/branch/blackhole-improvement/pypy/jit/metainterp/warmspot.py
pypy/branch/blackhole-improvement/pypy/jit/metainterp/warmstate.py
Log:
Start hooking the blackhole interpreter to the rest of the metainterp.
Modified: pypy/branch/blackhole-improvement/pypy/jit/backend/llgraph/llimpl.py
==============================================================================
--- pypy/branch/blackhole-improvement/pypy/jit/backend/llgraph/llimpl.py (original)
+++ pypy/branch/blackhole-improvement/pypy/jit/backend/llgraph/llimpl.py Tue May 18 17:04:44 2010
@@ -1063,17 +1063,38 @@
def frame_int_getvalue(frame, num):
frame = _from_opaque(frame)
+ assert num >= 0
return frame.fail_args[num]
def frame_float_getvalue(frame, num):
frame = _from_opaque(frame)
+ assert num >= 0
return frame.fail_args[num]
def frame_ptr_getvalue(frame, num):
frame = _from_opaque(frame)
- result = frame.fail_args[num]
- frame.fail_args[num] = None
- return result
+ assert num >= 0
+ return frame.fail_args[num]
+
+def frame_get_value_kind(frame, num):
+ frame = _from_opaque(frame)
+ assert num >= 0
+ TYPE = lltype.typeOf(frame.fail_args[num])
+ if TYPE is lltype.Signed:
+ return INT
+ if TYPE == llmemory.GCREF:
+ return REF
+ if TYPE is lltype.Float:
+ return FLOAT
+ raise TypeError("frame.fail_args[%d] is of type %r" % (num, TYPE))
+
+def get_latest_value_count(frame):
+ frame = _from_opaque(frame)
+ return len(frame.fail_args)
+
+def frame_clear_latest_values(frame):
+ frame = _from_opaque(frame)
+ del frame.fail_args
_last_exception = None
Modified: pypy/branch/blackhole-improvement/pypy/jit/backend/llgraph/runner.py
==============================================================================
--- pypy/branch/blackhole-improvement/pypy/jit/backend/llgraph/runner.py (original)
+++ pypy/branch/blackhole-improvement/pypy/jit/backend/llgraph/runner.py Tue May 18 17:04:44 2010
@@ -243,26 +243,18 @@
def get_latest_value_float(self, index):
return llimpl.frame_float_getvalue(self.latest_frame, index)
+ def get_latest_value_kind(self, index):
+ return llimpl.frame_get_value_kind(self.latest_frame, index)
+
+ def get_latest_value_count(self):
+ return llimpl.frame_get_value_count(self.latest_frame)
+
def get_latest_force_token(self):
token = llimpl.get_frame_forced_token(self.latest_frame)
return self.cast_adr_to_int(token)
- def make_boxes_from_latest_values(self, faildescr):
- inputargs_and_holes = []
- for i in range(len(faildescr._fail_args_types)):
- boxtype = faildescr._fail_args_types[i]
- if boxtype == history.INT:
- box = history.BoxInt(self.get_latest_value_int(i))
- elif boxtype == history.REF:
- box = self.ts.BoxRef(self.get_latest_value_ref(i))
- elif boxtype == history.FLOAT:
- box = history.BoxFloat(self.get_latest_value_float(i))
- elif boxtype == history.HOLE:
- box = None
- else:
- assert False, "bad box type: num=%d" % ord(boxtype)
- inputargs_and_holes.append(box)
- return inputargs_and_holes
+ def clear_latest_values(self):
+ llimpl.frame_clear_latest_values(self.latest_frame)
# ----------
Modified: pypy/branch/blackhole-improvement/pypy/jit/backend/model.py
==============================================================================
--- pypy/branch/blackhole-improvement/pypy/jit/backend/model.py (original)
+++ pypy/branch/blackhole-improvement/pypy/jit/backend/model.py Tue May 18 17:04:44 2010
@@ -85,15 +85,24 @@
or from 'args' if it was a FINISH). Returns a ptr or an obj."""
raise NotImplementedError
+ def get_latest_value_kind(self, index):
+ """Return the kind (history.INT, REF or FLOAT) of the index'th
+ argument to the last executed operation."""
+ raise NotImplementedError
+
+ def get_latest_value_count(self):
+ """Return how many values are ready to be returned by
+ get_latest_value_xxx()."""
+ raise NotImplementedError
+
def get_latest_force_token(self):
"""After a GUARD_NOT_FORCED fails, this function returns the
same FORCE_TOKEN result as the one in the just-failed loop."""
raise NotImplementedError
- def make_boxes_from_latest_value(self, faildescr):
- """Build a list of Boxes (and None for holes) that contains
- the current values, as would be returned by calls to
- get_latest_value_xxx()."""
+ def clear_latest_values(self):
+ """Clear the latest values (at least the ref ones, so that
+ they no longer keep objects alive)."""
raise NotImplementedError
def get_exception(self):
Modified: pypy/branch/blackhole-improvement/pypy/jit/backend/x86/assembler.py
==============================================================================
--- pypy/branch/blackhole-improvement/pypy/jit/backend/x86/assembler.py (original)
+++ pypy/branch/blackhole-improvement/pypy/jit/backend/x86/assembler.py Tue May 18 17:04:44 2010
@@ -1081,13 +1081,8 @@
n = self.CODE_HOLE
mc.writechr(n)
mc.writechr(self.CODE_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)
+ # assert that the fail_boxes lists are big enough
+ assert len(failargs) <= self.fail_boxes_int.SIZE
def rebuild_faillocs_from_descr(self, bytecode):
from pypy.jit.backend.x86.regalloc import X86FrameManager
Modified: pypy/branch/blackhole-improvement/pypy/jit/backend/x86/support.py
==============================================================================
--- pypy/branch/blackhole-improvement/pypy/jit/backend/x86/support.py (original)
+++ pypy/branch/blackhole-improvement/pypy/jit/backend/x86/support.py Tue May 18 17:04:44 2010
@@ -4,6 +4,8 @@
ATP = lltype.GcArray(TP)
class ValuesArray(object):
+ SIZE = size
+
def __init__(self):
self.ar = lltype.malloc(ATP, size, zero=True, immortal=True)
Modified: pypy/branch/blackhole-improvement/pypy/jit/codewriter/assembler.py
==============================================================================
--- pypy/branch/blackhole-improvement/pypy/jit/codewriter/assembler.py (original)
+++ pypy/branch/blackhole-improvement/pypy/jit/codewriter/assembler.py Tue May 18 17:04:44 2010
@@ -47,6 +47,7 @@
self.liveness = {}
self.nextlive = None
self.startpoints = set()
+ self.alllabels = set()
def emit_reg(self, reg):
if reg.index >= self.count_regs[reg.kind]:
@@ -113,6 +114,7 @@
else:
argcodes.append(kind[0])
elif isinstance(x, TLabel):
+ self.alllabels.add(len(self.code))
self.tlabel_positions.append((x.name, len(self.code)))
self.code.append("temp 1")
self.code.append("temp 2")
@@ -194,4 +196,5 @@
self.count_regs['ref'],
self.count_regs['float'],
liveness=self.liveness,
- startpoints=self.startpoints)
+ startpoints=self.startpoints,
+ alllabels=self.alllabels)
Modified: pypy/branch/blackhole-improvement/pypy/jit/codewriter/flatten.py
==============================================================================
--- pypy/branch/blackhole-improvement/pypy/jit/codewriter/flatten.py (original)
+++ pypy/branch/blackhole-improvement/pypy/jit/codewriter/flatten.py Tue May 18 17:04:44 2010
@@ -210,8 +210,8 @@
assert block.exitswitch.concretetype == lltype.Bool
opargs = [block.exitswitch]
#
- self.emitline(opname, TLabel(linkfalse),
- *self.flatten_list(opargs))
+ lst = self.flatten_list(opargs) + [TLabel(linkfalse)]
+ self.emitline(opname, *lst)
# true path:
self.make_link(linktrue)
# false path:
@@ -258,10 +258,10 @@
for switch in switches:
# make the case described by 'switch'
self.emitline('goto_if_not_int_eq',
- TLabel(switch),
color,
Constant(switch.llexitcase,
- block.exitswitch.concretetype))
+ block.exitswitch.concretetype),
+ TLabel(switch))
# emit code for the "taken" path
self.make_link(switch)
# finally, emit the label for the "non-taken" path
Modified: pypy/branch/blackhole-improvement/pypy/jit/codewriter/jitcode.py
==============================================================================
--- pypy/branch/blackhole-improvement/pypy/jit/codewriter/jitcode.py (original)
+++ pypy/branch/blackhole-improvement/pypy/jit/codewriter/jitcode.py Tue May 18 17:04:44 2010
@@ -16,31 +16,33 @@
self._ssarepr = None # debugging
def setup(self, code='', constants_i=[], constants_r=[], constants_f=[],
- num_regs_i=256, num_regs_r=256, num_regs_f=256,
- liveness=None, startpoints=None):
+ num_regs_i=255, num_regs_r=255, num_regs_f=255,
+ liveness=None, startpoints=None, alllabels=None):
self.code = code
# if the following lists are empty, use a single shared empty list
self.constants_i = constants_i or self._empty_i
self.constants_r = constants_r or self._empty_r
self.constants_f = constants_f or self._empty_f
# encode the three num_regs into a single integer
- self.num_regs_encoded = ((num_regs_i << 18) |
- (num_regs_f << 9) |
+ assert num_regs_i < 256 and num_regs_r < 256 and num_regs_f < 256
+ self.num_regs_encoded = ((num_regs_i << 16) |
+ (num_regs_f << 8) |
(num_regs_r << 0))
self.liveness = liveness
self._startpoints = startpoints # debugging
+ self._alllabels = alllabels # debugging
def get_fnaddr_as_int(self):
return llmemory.cast_adr_to_int(self.fnaddr)
def num_regs_i(self):
- return self.num_regs_encoded >> 18
+ return self.num_regs_encoded >> 16
def num_regs_f(self):
- return (self.num_regs_encoded >> 9) & 0x1FF
+ return (self.num_regs_encoded >> 8) & 0xFF
def num_regs_r(self):
- return self.num_regs_encoded & 0x1FF
+ return self.num_regs_encoded & 0xFF
def has_liveness_info(self, pc):
return pc in self.liveness
Modified: pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_assembler.py
==============================================================================
--- pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_assembler.py (original)
+++ pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_assembler.py Tue May 18 17:04:44 2010
@@ -93,7 +93,7 @@
i0, i1 = Register('int', 0x16), Register('int', 0x17)
ssarepr.insns = [
(Label('L1'),),
- ('goto_if_not_int_gt', TLabel('L2'), i0, Constant(4, lltype.Signed)),
+ ('goto_if_not_int_gt', i0, Constant(4, lltype.Signed), TLabel('L2')),
('int_add', i1, i0, i1),
('int_sub', i0, Constant(1, lltype.Signed), i0),
('goto', TLabel('L1')),
@@ -102,12 +102,12 @@
]
assembler = Assembler()
jitcode = assembler.assemble(ssarepr)
- assert jitcode.code == ("\x00\x10\x00\x16\x04"
+ assert jitcode.code == ("\x00\x16\x04\x10\x00"
"\x01\x17\x16\x17"
"\x02\x16\x01\x16"
"\x03\x00\x00"
"\x04\x17")
- assert assembler.insns == {'goto_if_not_int_gt/Lic': 0,
+ assert assembler.insns == {'goto_if_not_int_gt/icL': 0,
'int_add/iii': 1,
'int_sub/ici': 2,
'goto/L': 3,
Modified: pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_codewriter.py
==============================================================================
--- pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_codewriter.py (original)
+++ pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_codewriter.py Tue May 18 17:04:44 2010
@@ -30,12 +30,12 @@
return b
cw = CodeWriter()
jitcode = cw.transform_func_to_jitcode(f, [5, 6])
- assert jitcode.code == ("\x00\x10\x00\x00\x00" # ends at 5
+ assert jitcode.code == ("\x00\x00\x00\x10\x00" # ends at 5
"\x01\x01\x00\x01"
"\x02\x00\x01\x00"
"\x03\x00\x00"
"\x04\x01")
- assert cw.assembler.insns == {'goto_if_not_int_gt/Lic': 0,
+ assert cw.assembler.insns == {'goto_if_not_int_gt/icL': 0,
'int_add/iii': 1,
'int_sub/ici': 2,
'goto/L': 3,
@@ -82,7 +82,8 @@
jitcode = cw.transform_func_to_jitcode(f, [5, 6])
blackholeinterpbuilder = BlackholeInterpBuilder(cw)
blackholeinterp = blackholeinterpbuilder.acquire_interp()
+ blackholeinterp.setposition(jitcode, 0)
blackholeinterp.setarg_i(0, 6)
blackholeinterp.setarg_i(1, 100)
- blackholeinterp.run(jitcode, 0)
+ blackholeinterp.run()
assert blackholeinterp.get_result_i() == 100+6+5+4+3
Modified: pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_flatten.py
==============================================================================
--- pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_flatten.py (original)
+++ pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_flatten.py Tue May 18 17:04:44 2010
@@ -120,7 +120,7 @@
int_copy %i1, %i3
L1:
int_gt %i2, $0, %i4
- goto_if_not L2, %i4
+ goto_if_not %i4, L2
int_copy %i2, %i5
int_copy %i3, %i6
int_add %i6, %i5, %i7
@@ -142,7 +142,7 @@
int_copy %i0, %i2
int_copy %i1, %i3
L1:
- goto_if_not_int_gt L2, %i2, $0
+ goto_if_not_int_gt %i2, $0, L2
int_copy %i2, %i4
int_copy %i3, %i5
int_add %i5, %i4, %i6
@@ -210,13 +210,13 @@
else: return 42
self.encoding_test(f, [65], """
int_guard_value %i0, %i0
- goto_if_not_int_eq L1, %i0, $-5
+ goto_if_not_int_eq %i0, $-5, L1
int_return $12
L1:
- goto_if_not_int_eq L2, %i0, $2
+ goto_if_not_int_eq %i0, $2, L2
int_return $51
L2:
- goto_if_not_int_eq L3, %i0, $7
+ goto_if_not_int_eq %i0, $7, L3
int_return $1212
L3:
int_return $42
@@ -342,7 +342,7 @@
# note that 'goto_if_not_int_is_true' is actually the same thing
# as just 'goto_if_not'.
self.encoding_test(f, [7], """
- goto_if_not L1, %i0
+ goto_if_not %i0, L1
int_return $False
L1:
int_return $True
Modified: pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_format.py
==============================================================================
--- pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_format.py (original)
+++ pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_format.py Tue May 18 17:04:44 2010
@@ -52,7 +52,7 @@
i0, i1 = Register('int', 0), Register('int', 1)
ssarepr.insns = [
(Label('L1'),),
- ('goto_if_not_int_gt', TLabel('L2'), i0, Constant(0, lltype.Signed)),
+ ('goto_if_not_int_gt', i0, Constant(0, lltype.Signed), TLabel('L2')),
('int_add', i1, i0, i1),
('int_sub', i0, Constant(1, lltype.Signed), i0),
('goto', TLabel('L1')),
@@ -62,7 +62,7 @@
asm = format_assembler(ssarepr)
expected = """
L1:
- goto_if_not_int_gt L2, %i0, $0
+ goto_if_not_int_gt %i0, $0, L2
int_add %i1, %i0, %i1
int_sub %i0, $1, %i0
goto L1
Modified: pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_jitcode.py
==============================================================================
--- pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_jitcode.py (original)
+++ pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_jitcode.py Tue May 18 17:04:44 2010
@@ -11,10 +11,10 @@
assert j.num_regs_i() == 0
assert j.num_regs_r() == 0
assert j.num_regs_f() == 0
- j.setup(num_regs_i=256, num_regs_r=256, num_regs_f=256)
- assert j.num_regs_i() == 256
- assert j.num_regs_r() == 256
- assert j.num_regs_f() == 256
+ j.setup(num_regs_i=255, num_regs_r=255, num_regs_f=255)
+ assert j.num_regs_i() == 255
+ assert j.num_regs_r() == 255
+ assert j.num_regs_f() == 255
def test_liveness():
j = JitCode("test")
Modified: pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_liveness.py
==============================================================================
--- pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_liveness.py (original)
+++ pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_liveness.py Tue May 18 17:04:44 2010
@@ -66,7 +66,7 @@
-live- %i0, %i1
G_int_add %i0, $5, %i2
int_is_true %i2, %i3
- goto_if_not L1, %i3
+ goto_if_not %i3, L1
int_copy %i0, %i4
-live-
G_int_add %i4, $1, %i5
@@ -87,7 +87,7 @@
-live- %i0, %i1
G_int_add %i0, $5, %i2
int_is_true %i2, %i3
- goto_if_not L1, %i3
+ goto_if_not %i3, L1
int_copy %i0, %i4
int_copy %i1, %i5
-live-
@@ -109,7 +109,7 @@
-live- %i0
G_int_add %i0, %i1, %i2
int_is_true %i2, %i3
- goto_if_not L1, %i3
+ goto_if_not %i3, L1
int_copy %i0, %i4
-live-
G_int_add %i4, $5, %i5
@@ -129,7 +129,7 @@
self.encoding_test(f, [5, 6], """
int_is_true %i0, %i2
-live- %i0, %i1
- goto_if_not L1, %i2
+ goto_if_not %i2, L1
int_return %i0
L1:
int_return %i1
Modified: pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_regalloc.py
==============================================================================
--- pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_regalloc.py (original)
+++ pypy/branch/blackhole-improvement/pypy/jit/codewriter/test/test_regalloc.py Tue May 18 17:04:44 2010
@@ -59,7 +59,7 @@
self.check_assembler(graph, """
L1:
int_gt %i0, $0, %i2
- goto_if_not L2, %i2
+ goto_if_not %i2, L2
int_add %i1, %i0, %i1
int_sub %i0, $1, %i0
goto L1
@@ -76,7 +76,7 @@
self.check_assembler(graph, """
L1:
int_gt %i0, $0, %i2
- goto_if_not L2, %i2
+ goto_if_not %i2, L2
int_push %i1
int_copy %i0, %i1
int_pop %i0
@@ -94,7 +94,7 @@
self.check_assembler(graph, """
L1:
int_gt %i0, $0, %i0
- goto_if_not L2, %i0
+ goto_if_not %i0, L2
int_copy %i1, %i0
int_copy $2, %i1
goto L1
@@ -111,7 +111,7 @@
self.check_assembler(graph, """
L1:
int_gt %i0, $0, %i3
- goto_if_not L2, %i3
+ goto_if_not %i3, L2
int_push %i1
int_copy %i2, %i1
int_copy %i0, %i2
@@ -130,7 +130,7 @@
self.check_assembler(graph, """
L1:
int_gt %i0, $0, %i3
- goto_if_not L2, %i3
+ goto_if_not %i3, L2
int_copy %i2, %i1
goto L1
L2:
Modified: pypy/branch/blackhole-improvement/pypy/jit/metainterp/blackhole.py
==============================================================================
--- pypy/branch/blackhole-improvement/pypy/jit/metainterp/blackhole.py (original)
+++ pypy/branch/blackhole-improvement/pypy/jit/metainterp/blackhole.py Tue May 18 17:04:44 2010
@@ -1,6 +1,7 @@
from pypy.rlib.unroll import unrolling_iterable
from pypy.rlib.rarithmetic import intmask, LONG_BIT, r_uint, ovfcheck
from pypy.rlib.objectmodel import we_are_translated
+from pypy.rlib.debug import debug_start, debug_stop
from pypy.rlib.debug import make_sure_not_resized
from pypy.rpython.lltypesystem import lltype, llmemory, rclass
from pypy.rpython.lltypesystem.lloperation import llop
@@ -53,10 +54,11 @@
class BlackholeInterpBuilder(object):
verbose = True
- def __init__(self, codewriter):
+ def __init__(self, codewriter, metainterp_sd=None):
self.cpu = codewriter.cpu
self.setup_insns(codewriter.assembler.insns)
self.setup_descrs(codewriter.assembler.descrs)
+ self.metainterp_sd = metainterp_sd
self._freeze_()
def _freeze_(self):
@@ -81,7 +83,7 @@
def dispatch_loop(self, code, position):
while True:
if not we_are_translated():
- assert position in self._current_jitcode._startpoints, (
+ assert position in self.jitcode._startpoints, (
"the current position %d is in the middle of "
"an instruction!" % position)
opcode = ord(code[position])
@@ -233,18 +235,18 @@
return BlackholeInterpreter(self)
def release_interp(self, interp):
- interp.cleanup_registers_r()
+ interp.cleanup_registers()
self.blackholeinterps.append(interp)
class BlackholeInterpreter(object):
def __init__(self, builder):
+ self.builder = builder
self.cpu = builder.cpu
self.dispatch_loop = builder.dispatch_loop
self.descrs = builder.descrs
self.op_catch_exception = builder.op_catch_exception
- self.cleanup_required_in_registers_r = 0
#
if we_are_translated():
default_i = 0
@@ -257,6 +259,19 @@
self.registers_i = [default_i] * 256
self.registers_r = [default_r] * 256
self.registers_f = [default_f] * 256
+ self.jitcode = None
+
+ def setposition(self, jitcode, position):
+ if jitcode is not self.jitcode:
+ # the real performance impact of the following code is unclear,
+ # but it should be minimized by the fact that a given
+ # BlackholeInterpreter instance is likely to be reused with
+ # exactly the same jitcode, so we don't do the copy again.
+ self.copy_constants(self.registers_i, jitcode.constants_i)
+ self.copy_constants(self.registers_r, jitcode.constants_r)
+ self.copy_constants(self.registers_f, jitcode.constants_f)
+ self.jitcode = jitcode
+ self.position = position
def setarg_i(self, index, value):
self.registers_i[index] = value
@@ -267,21 +282,14 @@
def setarg_f(self, index, value):
self.registers_f[index] = value
- def run(self, jitcode, position):
- if not we_are_translated():
- self._current_jitcode = jitcode
- self.copy_constants(self.registers_i, jitcode.constants_i)
- self.copy_constants(self.registers_r, jitcode.constants_r)
- self.copy_constants(self.registers_f, jitcode.constants_f)
- code = jitcode.code
- self.cleanup_required_in_registers_r = max(
- self.cleanup_required_in_registers_r,
- jitcode.num_regs_r())
+ def run(self):
+ code = self.jitcode.code
+ position = self.position
while True:
try:
self.dispatch_loop(self, code, position)
except LeaveFrame:
- return
+ break
except Exception, e:
e = get_llexception(self.cpu, e)
position = self.handle_exception_in_frame(e, code)
@@ -290,7 +298,12 @@
return self.tmpreg_i
def get_result_r(self):
- return self.tmpreg_r
+ result = self.tmpreg_r
+ if we_are_translated():
+ self.tmpreg_r = NULL
+ else:
+ del self.tmpreg_r
+ return result
def get_result_f(self):
return self.tmpreg_f
@@ -303,14 +316,12 @@
if self._return_type == 'void': return None
raise ValueError(self._return_type)
- def cleanup_registers_r(self):
+ def cleanup_registers(self):
# To avoid keeping references alive, this cleans up the registers_r.
# It does not clear the references set by copy_constants(), but
# these are all prebuilt constants anyway.
- for i in range(self.cleanup_required_in_registers_r):
+ for i in range(self.jitcode.num_regs_r()):
self.registers_r[i] = NULL
- self.cleanup_required_in_registers_r = 0
- self.tmpreg_r = NULL
self.exception_last_value = None
def handle_exception_in_frame(self, e, code):
@@ -330,11 +341,12 @@
return target
# XXX must be specialized
- # XXX the real performance impact of the following loop is unclear
def copy_constants(self, registers, constants):
"""Copy jitcode.constants[0] to registers[255],
jitcode.constants[1] to registers[254],
jitcode.constants[2] to registers[253], etc."""
+ make_sure_not_resized(registers)
+ make_sure_not_resized(constants)
i = len(constants) - 1
while i >= 0:
j = 255 - i
@@ -342,6 +354,18 @@
registers[j] = constants[i]
i -= 1
+ def follow_jump(self):
+ """Assuming that self.position points just after a bytecode
+ instruction that ends with a label, follow that label."""
+ code = self.jitcode.code
+ position = self.position - 2
+ assert position >= 0
+ if not we_are_translated():
+ assert position in self.jitcode._alllabels
+ labelvalue = ord(code[position]) | (ord(code[position+1])<<8)
+ assert labelvalue < len(code)
+ self.position = labelvalue
+
# ----------
@arguments("i", "i", returns="i")
@@ -497,13 +521,13 @@
@arguments("self", returns="i")
def bhimpl_int_pop(self):
- return self.tmpreg_i
+ return self.get_result_i()
@arguments("self", returns="r")
def bhimpl_ref_pop(self):
- return self.tmpreg_r
+ return self.get_result_r()
@arguments("self", returns="f")
def bhimpl_float_pop(self):
- return self.tmpreg_f
+ return self.get_result_f()
# ----------
# float operations
@@ -590,85 +614,85 @@
self._return_type = "void"
raise LeaveFrame
- @arguments("L", "i", "pc", returns="L")
- def bhimpl_goto_if_not(target, a, pc):
+ @arguments("i", "L", "pc", returns="L")
+ def bhimpl_goto_if_not(a, target, pc):
if a:
return pc
else:
return target
- @arguments("L", "i", "i", "pc", returns="L")
- def bhimpl_goto_if_not_int_lt(target, a, b, pc):
+ @arguments("i", "i", "L", "pc", returns="L")
+ def bhimpl_goto_if_not_int_lt(a, b, target, pc):
if a < b:
return pc
else:
return target
- @arguments("L", "i", "i", "pc", returns="L")
- def bhimpl_goto_if_not_int_le(target, a, b, pc):
+ @arguments("i", "i", "L", "pc", returns="L")
+ def bhimpl_goto_if_not_int_le(a, b, target, pc):
if a <= b:
return pc
else:
return target
- @arguments("L", "i", "i", "pc", returns="L")
- def bhimpl_goto_if_not_int_eq(target, a, b, pc):
+ @arguments("i", "i", "L", "pc", returns="L")
+ def bhimpl_goto_if_not_int_eq(a, b, target, pc):
if a == b:
return pc
else:
return target
- @arguments("L", "i", "i", "pc", returns="L")
- def bhimpl_goto_if_not_int_ne(target, a, b, pc):
+ @arguments("i", "i", "L", "pc", returns="L")
+ def bhimpl_goto_if_not_int_ne(a, b, target, pc):
if a != b:
return pc
else:
return target
- @arguments("L", "i", "i", "pc", returns="L")
- def bhimpl_goto_if_not_int_gt(target, a, b, pc):
+ @arguments("i", "i", "L", "pc", returns="L")
+ def bhimpl_goto_if_not_int_gt(a, b, target, pc):
if a > b:
return pc
else:
return target
- @arguments("L", "i", "i", "pc", returns="L")
- def bhimpl_goto_if_not_int_ge(target, a, b, pc):
+ @arguments("i", "i", "L", "pc", returns="L")
+ def bhimpl_goto_if_not_int_ge(a, b, target, pc):
if a >= b:
return pc
else:
return target
- @arguments("L", "i", "pc", returns="L")
- def bhimpl_goto_if_not_int_is_zero(target, a, pc):
+ @arguments("i", "L", "pc", returns="L")
+ def bhimpl_goto_if_not_int_is_zero(a, target, pc):
if not a:
return pc
else:
return target
- @arguments("L", "r", "r", "pc", returns="L")
- def bhimpl_goto_if_not_ptr_eq(target, a, b, pc):
+ @arguments("r", "r", "L", "pc", returns="L")
+ def bhimpl_goto_if_not_ptr_eq(a, b, target, pc):
if a == b:
return pc
else:
return target
- @arguments("L", "r", "r", "pc", returns="L")
- def bhimpl_goto_if_not_ptr_ne(target, a, b, pc):
+ @arguments("r", "r", "L", "pc", returns="L")
+ def bhimpl_goto_if_not_ptr_ne(a, b, target, pc):
if a != b:
return pc
else:
return target
- @arguments("L", "r", "pc", returns="L")
- def bhimpl_goto_if_not_ptr_iszero(target, a, pc):
+ @arguments("r", "L", "pc", returns="L")
+ def bhimpl_goto_if_not_ptr_iszero(a, target, pc):
if not a:
return pc
else:
return target
- @arguments("L", "r", "pc", returns="L")
- def bhimpl_goto_if_not_ptr_nonzero(target, a, pc):
+ @arguments("r", "L", "pc", returns="L")
+ def bhimpl_goto_if_not_ptr_nonzero(a, target, pc):
if a:
return pc
else:
@@ -729,6 +753,15 @@
assert real_instance
raise real_instance
+ @arguments()
+ def bhimpl_can_enter_jit():
+ pass
+
+ @arguments("self", "I", "R", "F", "I", "R", "F")
+ def bhimpl_jit_merge_point(self, *results):
+ CRN = self.builder.metainterp_sd.ContinueRunningNormally
+ raise CRN(*results)
+
# ----------
# the following operations are directly implemented by the backend
@@ -904,3 +937,60 @@
@arguments("cpu", "r", "i", "i")
def bhimpl_unicodesetitem(cpu, unicode, index, newchr):
cpu.bh_unicodesetitem(unicode, index, newchr)
+
+# ____________________________________________________________
+
+def resume_in_blackhole(metainterp_sd, resumedescr):
+ from pypy.jit.metainterp.resume import blackhole_from_resumedata
+ debug_start('jit-blackhole')
+ metainterp_sd.profiler.start_blackhole()
+ blackholeinterp = blackhole_from_resumedata(
+ metainterp_sd.blackholeinterpbuilder,
+ resumedescr,
+ False) # XXX
+ # XXX virtualrefs
+ # XXX virtualizable
+ _prepare_resume_from_failure(blackholeinterp, resumedescr.guard_opnum)
+ try:
+ blackholeinterp = _resume_mainloop(
+ metainterp_sd.blackholeinterpbuilder, blackholeinterp)
+ finally:
+ metainterp_sd.profiler.end_blackhole()
+ debug_stop('jit-blackhole')
+ # rare case: we only get there if the blackhole interps all returned
+ # normally (in general we get a ContinueRunningNormally exception).
+ _done_with_this_frame(blackholeinterp)
+
+def _resume_mainloop(blackholeinterpbuilder, blackholeinterp):
+ while True:
+ try:
+ blackholeinterp.run()
+ finally:
+ blackholeinterpbuilder.release_interp(blackholeinterp)
+ #...x.x.x...
+ assert blackholeinterp.nextblackholeinterp is None # XXX
+ break
+ xxx
+ return blackholeinterp
+
+def _prepare_resume_from_failure(blackholeinterp, opnum):
+ from pypy.jit.metainterp.resoperation import rop
+ if opnum == rop.GUARD_TRUE: # a goto_if_not_xxx that jumps only now
+ blackholeinterp.follow_jump()
+ elif opnum == rop.GUARD_FALSE: # a goto_if_not that stops jumping
+ pass
+ else:
+ raise NotImplementedError(opnum)
+
+def _done_with_this_frame(blackholeinterp):
+ sd = blackholeinterp.builder.metainterp_sd
+ if sd.result_type == 'void':
+ raise sd.DoneWithThisFrameVoid()
+ elif sd.result_type == 'int':
+ raise sd.DoneWithThisFrameInt(blackholeinterp.get_result_i())
+ elif sd.result_type == 'ref':
+ raise sd.DoneWithThisFrameRef(blackholeinterp.get_result_r())
+ elif sd.result_type == 'float':
+ raise sd.DoneWithThisFrameFloat(blackholeinterp.get_result_f())
+ else:
+ assert False
Modified: pypy/branch/blackhole-improvement/pypy/jit/metainterp/compile.py
==============================================================================
--- pypy/branch/blackhole-improvement/pypy/jit/metainterp/compile.py (original)
+++ pypy/branch/blackhole-improvement/pypy/jit/metainterp/compile.py Tue May 18 17:04:44 2010
@@ -239,16 +239,20 @@
self._counter = ~i # use ~(index_of_guarded_box_in_fail_args)
def handle_fail(self, metainterp_sd):
+ from pypy.jit.metainterp.blackhole import resume_in_blackhole
+ return resume_in_blackhole(metainterp_sd, self)
+ XXX
from pypy.jit.metainterp.pyjitpl import MetaInterp
metainterp = MetaInterp(metainterp_sd)
return metainterp.handle_guard_failure(self)
- def must_compile(self, metainterp_sd, inputargs_and_holes):
+ def must_compile(self, metainterp_sd):
trace_eagerness = metainterp_sd.state.trace_eagerness
if self._counter >= 0:
self._counter += 1
return self._counter >= trace_eagerness
else:
+ XXX
box = inputargs_and_holes[~self._counter]
if self._counters is None:
self._counters = ResumeGuardCounters()
Modified: pypy/branch/blackhole-improvement/pypy/jit/metainterp/pyjitpl.py
==============================================================================
--- pypy/branch/blackhole-improvement/pypy/jit/metainterp/pyjitpl.py (original)
+++ pypy/branch/blackhole-improvement/pypy/jit/metainterp/pyjitpl.py Tue May 18 17:04:44 2010
@@ -36,11 +36,11 @@
return func
return decorate
-class XXX: # XXX temporary hack
+class FixME: # XXX temporary hack
def __init__(self, func):
self.func = func
def __getattr__(self, _):
- raise Exception("@XXX: " + self.func.__name__)
+ raise Exception("@FixME: " + self.func.__name__)
# ____________________________________________________________
@@ -236,8 +236,8 @@
def opimpl_goto(self, target):
self.pc = target
- @arguments("label", "box")
- def opimpl_goto_if_not(self, target, box):
+ @arguments("box", "label")
+ def opimpl_goto_if_not(self, box, target):
switchcase = box.getint()
if switchcase:
opnum = rop.GUARD_TRUE
@@ -249,19 +249,19 @@
for _opimpl in ['int_is_zero', 'ptr_iszero', 'ptr_nonzero']:
exec py.code.Source('''
- @arguments("label", "box")
- def opimpl_goto_if_not_%s(self, target, box):
+ @arguments("box", "label")
+ def opimpl_goto_if_not_%s(self, box, target):
condbox = self.execute(rop.%s, box)
- self.opimpl_goto_if_not(target, condbox)
+ self.opimpl_goto_if_not(condbox, target)
''' % (_opimpl, _opimpl.upper())).compile()
for _opimpl in ['int_lt', 'int_le', 'int_eq', 'int_ne', 'int_gt', 'int_ge',
'ptr_eq', 'ptr_ne']:
exec py.code.Source('''
- @arguments("label", "box", "box")
- def opimpl_goto_if_not_%s(self, target, b1, b2):
+ @arguments("box", "box", "label")
+ def opimpl_goto_if_not_%s(self, b1, b2, target):
condbox = self.execute(rop.%s, b1, b2)
- self.opimpl_goto_if_not(target, condbox)
+ self.opimpl_goto_if_not(condbox, target)
''' % (_opimpl, _opimpl.upper())).compile()
def follow_jump(self):
@@ -316,18 +316,18 @@
def opimpl_new_with_vtable(self, sizevtabledescr):
return self.execute_with_descr(rop.NEW_WITH_VTABLE, sizevtabledescr)
- @XXX #arguments("box")
+ @FixME #arguments("box")
def opimpl_runtimenew(self, classbox):
self.execute(rop.RUNTIMENEW, classbox)
- @XXX #arguments("orgpc", "box", "descr")
+ @FixME #arguments("orgpc", "box", "descr")
def opimpl_instanceof(self, pc, objbox, typedescr):
clsbox = self.cls_of_box(objbox)
if isinstance(objbox, Box):
self.generate_guard(pc, rop.GUARD_CLASS, objbox, [clsbox])
self.execute_with_descr(rop.INSTANCEOF, typedescr, objbox)
- @XXX #arguments("box", "box")
+ @FixME #arguments("box", "box")
def opimpl_subclassof(self, box1, box2):
self.execute(rop.SUBCLASSOF, box1, box2)
@@ -335,11 +335,11 @@
def opimpl_new_array(self, itemsizedescr, countbox):
return self.execute_with_descr(rop.NEW_ARRAY, itemsizedescr, countbox)
- @XXX #arguments("box", "descr", "box")
+ @FixME #arguments("box", "descr", "box")
def opimpl_getarrayitem_gc(self, arraybox, arraydesc, indexbox):
self.execute_with_descr(rop.GETARRAYITEM_GC, arraydesc, arraybox, indexbox)
- @XXX #arguments("box", "descr", "box")
+ @FixME #arguments("box", "descr", "box")
def opimpl_getarrayitem_gc_pure(self, arraybox, arraydesc, indexbox):
self.execute_with_descr(rop.GETARRAYITEM_GC_PURE, arraydesc, arraybox, indexbox)
@@ -352,18 +352,18 @@
opimpl_setarrayitem_gc_r = _opimpl_setarrayitem_gc
opimpl_setarrayitem_gc_f = _opimpl_setarrayitem_gc
- @XXX #arguments("box", "descr")
+ @FixME #arguments("box", "descr")
def opimpl_arraylen_gc(self, arraybox, arraydesc):
self.execute_with_descr(rop.ARRAYLEN_GC, arraydesc, arraybox)
- @XXX #arguments("descr", "box", "box", "box", "box", "box", "box", "descr")
+ @FixME #arguments("descr", "box", "box", "box", "box", "box", "box", "descr")
def opimpl_arraycopy(self, calldescr, fnptr, sourcebox, destbox,
source_startbox, dest_startbox, lengthbox, arraydescr):
self.execute_with_descr(rop.ARRAYCOPY, arraydescr, calldescr, fnptr,
sourcebox, destbox, source_startbox,
dest_startbox, lengthbox)
- @XXX #arguments("orgpc", "box", "descr", "box")
+ @FixME #arguments("orgpc", "box", "descr", "box")
def opimpl_check_neg_index(self, pc, arraybox, arraydesc, indexbox):
negbox = self.metainterp.execute_and_record(
rop.INT_LT, None, indexbox, ConstInt(0))
@@ -376,7 +376,7 @@
rop.INT_ADD, None, indexbox, lenbox)
self.make_result_box(indexbox)
- @XXX #arguments("descr", "descr", "descr", "descr", "box")
+ @FixME #arguments("descr", "descr", "descr", "descr", "box")
def opimpl_newlist(self, structdescr, lengthdescr, itemsdescr, arraydescr,
sizebox):
sbox = self.metainterp.execute_and_record(rop.NEW, structdescr)
@@ -388,20 +388,20 @@
sbox, abox)
self.make_result_box(sbox)
- @XXX #arguments("box", "descr", "descr", "box")
+ @FixME #arguments("box", "descr", "descr", "box")
def opimpl_getlistitem_gc(self, listbox, itemsdescr, arraydescr, indexbox):
arraybox = self.metainterp.execute_and_record(rop.GETFIELD_GC,
itemsdescr, listbox)
self.execute_with_descr(rop.GETARRAYITEM_GC, arraydescr, arraybox, indexbox)
- @XXX #arguments("box", "descr", "descr", "box", "box")
+ @FixME #arguments("box", "descr", "descr", "box", "box")
def opimpl_setlistitem_gc(self, listbox, itemsdescr, arraydescr, indexbox,
valuebox):
arraybox = self.metainterp.execute_and_record(rop.GETFIELD_GC,
itemsdescr, listbox)
self.execute_with_descr(rop.SETARRAYITEM_GC, arraydescr, arraybox, indexbox, valuebox)
- @XXX #arguments("orgpc", "box", "descr", "box")
+ @FixME #arguments("orgpc", "box", "descr", "box")
def opimpl_check_resizable_neg_index(self, pc, listbox, lengthdesc,
indexbox):
negbox = self.metainterp.execute_and_record(
@@ -415,7 +415,7 @@
rop.INT_ADD, None, indexbox, lenbox)
self.make_result_box(indexbox)
- @XXX #arguments("orgpc", "box")
+ @FixME #arguments("orgpc", "box")
def opimpl_check_zerodivisionerror(self, pc, box):
nonzerobox = self.metainterp.execute_and_record(
rop.INT_NE, None, box, ConstInt(0))
@@ -426,7 +426,7 @@
# division by zero!
return self.metainterp.raise_zero_division_error()
- @XXX #arguments("orgpc", "box", "box")
+ @FixME #arguments("orgpc", "box", "box")
def opimpl_check_div_overflow(self, pc, box1, box2):
# detect the combination "box1 = -sys.maxint-1, box2 = -1".
import sys
@@ -443,11 +443,11 @@
# division overflow!
return self.metainterp.raise_overflow_error()
- @XXX #arguments()
+ @FixME #arguments()
def opimpl_overflow_error(self):
return self.metainterp.raise_overflow_error()
- @XXX #arguments("orgpc", "box")
+ @FixME #arguments("orgpc", "box")
def opimpl_int_abs(self, pc, box):
nonneg = self.metainterp.execute_and_record(
rop.INT_GE, None, box, ConstInt(0))
@@ -457,7 +457,7 @@
else:
self.execute(rop.INT_NEG, box)
- @XXX #arguments("orgpc", "box")
+ @FixME #arguments("orgpc", "box")
def opimpl_oononnull(self, pc, box):
value = box.nonnull()
if value:
@@ -469,7 +469,7 @@
self.generate_guard(pc, opnum, box, [])
self.make_result_box(res)
- @XXX #arguments("orgpc", "box")
+ @FixME #arguments("orgpc", "box")
def opimpl_ooisnull(self, pc, box):
value = box.nonnull()
if value:
@@ -481,11 +481,11 @@
self.generate_guard(pc, opnum, box, [])
self.make_result_box(res)
- @XXX #arguments("box", "box")
+ @FixME #arguments("box", "box")
def opimpl_ptr_eq(self, box1, box2):
self.execute(rop.OOIS, box1, box2)
- @XXX #arguments("box", "box")
+ @FixME #arguments("box", "box")
def opimpl_ptr_ne(self, box1, box2):
self.execute(rop.OOISNOT, box1, box2)
@@ -557,7 +557,7 @@
vinfo = self.metainterp.staticdata.virtualizable_info
return vinfo.array_descrs[index]
- @XXX #arguments("orgpc", "box", "int")
+ @FixME #arguments("orgpc", "box", "int")
def opimpl_getfield_vable(self, pc, basebox, index):
if self._nonstandard_virtualizable(pc, basebox):
self.execute_with_descr(rop.GETFIELD_GC, self._get_virtualizable_field_descr(index), basebox)
@@ -565,7 +565,7 @@
self.metainterp.check_synchronized_virtualizable()
resbox = self.metainterp.virtualizable_boxes[index]
self.make_result_box(resbox)
- @XXX #arguments("orgpc", "box", "int", "box")
+ @FixME #arguments("orgpc", "box", "int", "box")
def opimpl_setfield_vable(self, pc, basebox, index, valuebox):
if self._nonstandard_virtualizable(pc, basebox):
self.execute_with_descr(rop.SETFIELD_GC, self._get_virtualizable_field_descr(index), basebox, valuebox)
@@ -585,7 +585,7 @@
assert 0 <= index < vinfo.get_array_length(virtualizable, arrayindex)
return vinfo.get_index_in_array(virtualizable, arrayindex, index)
- @XXX #arguments("orgpc", "box", "int", "box")
+ @FixME #arguments("orgpc", "box", "int", "box")
def opimpl_getarrayitem_vable(self, pc, basebox, arrayindex, indexbox):
if self._nonstandard_virtualizable(pc, basebox):
descr = self._get_virtualizable_array_field_descr(arrayindex)
@@ -599,7 +599,7 @@
index = self._get_arrayitem_vable_index(pc, arrayindex, indexbox)
resbox = self.metainterp.virtualizable_boxes[index]
self.make_result_box(resbox)
- @XXX #arguments("orgpc", "box", "int", "box", "box")
+ @FixME #arguments("orgpc", "box", "int", "box", "box")
def opimpl_setarrayitem_vable(self, pc, basebox, arrayindex, indexbox,
valuebox):
if self._nonstandard_virtualizable(pc, basebox):
@@ -614,7 +614,7 @@
self.metainterp.virtualizable_boxes[index] = valuebox
self.metainterp.synchronize_virtualizable()
# XXX only the index'th field needs to be synchronized, really
- @XXX #arguments("orgpc", "box", "int")
+ @FixME #arguments("orgpc", "box", "int")
def opimpl_arraylen_vable(self, pc, basebox, arrayindex):
if self._nonstandard_virtualizable(pc, basebox):
descr = self._get_virtualizable_array_field_descr(arrayindex)
@@ -671,11 +671,11 @@
opimpl_residual_call_irf_f = _opimpl_residual_call3
opimpl_residual_call_irf_v = _opimpl_residual_call3
- @XXX #arguments("descr", "varargs")
+ @FixME #arguments("descr", "varargs")
def opimpl_residual_call_loopinvariant(self, calldescr, varargs):
return self.execute_varargs(rop.CALL_LOOPINVARIANT, varargs, calldescr, exc=True)
- @XXX #arguments("orgpc", "descr", "varargs")
+ @FixME #arguments("orgpc", "descr", "varargs")
def opimpl_recursive_call(self, pc, calldescr, varargs):
warmrunnerstate = self.metainterp.staticdata.state
token = None
@@ -710,7 +710,7 @@
call_position)
return res
- @XXX #arguments("orgpc", "methdescr", "varargs")
+ @FixME #arguments("orgpc", "methdescr", "varargs")
def opimpl_oosend(self, pc, methdescr, varargs):
objbox = varargs[0]
clsbox = self.cls_of_box(objbox)
@@ -758,15 +758,15 @@
def opimpl_newunicode(self, lengthbox):
return self.execute(rop.NEWUNICODE, lengthbox)
- @XXX #arguments("descr", "varargs")
+ @FixME #arguments("descr", "varargs")
def opimpl_residual_oosend_canraise(self, methdescr, varargs):
return self.execute_varargs(rop.OOSEND, varargs, descr=methdescr, exc=True)
- @XXX #arguments("descr", "varargs")
+ @FixME #arguments("descr", "varargs")
def opimpl_residual_oosend_noraise(self, methdescr, varargs):
self.execute_varargs(rop.OOSEND, varargs, descr=methdescr, exc=False)
- @XXX #arguments("descr", "varargs")
+ @FixME #arguments("descr", "varargs")
def opimpl_residual_oosend_pure(self, methdescr, boxes):
self.execute_varargs(rop.OOSEND_PURE, boxes, descr=methdescr, exc=False)
@@ -784,17 +784,17 @@
self.generate_guard(rop.GUARD_CLASS, box, [clsbox])
return clsbox
-## @XXX #arguments("orgpc", "box", "builtin")
+## @FixME #arguments("orgpc", "box", "builtin")
## def opimpl_guard_builtin(self, pc, box, builtin):
## self.generate_guard(pc, "guard_builtin", box, [builtin])
-## @XXX #arguments("orgpc", "box", "builtin")
+## @FixME #arguments("orgpc", "box", "builtin")
## def opimpl_guard_len(self, pc, box, builtin):
## intbox = self.metainterp.cpu.execute_operation(
## 'len', [builtin.len_func, box], 'int')
## self.generate_guard(pc, "guard_len", box, [intbox])
- @XXX #arguments("box")
+ @FixME #arguments("box")
def opimpl_keepalive(self, box):
pass # xxx?
@@ -873,7 +873,7 @@
self.metainterp.popframe()
self.metainterp.finishframe_exception()
- @XXX #arguments("box")
+ @FixME #arguments("box")
def opimpl_virtual_ref(self, box):
# Details on the content of metainterp.virtualref_boxes:
#
@@ -907,7 +907,7 @@
metainterp.virtualref_boxes.append(resbox)
self.make_result_box(resbox)
- @XXX #arguments("box")
+ @FixME #arguments("box")
def opimpl_virtual_ref_finish(self, box):
# virtual_ref_finish() assumes that we have a stack-like, last-in
# first-out order.
@@ -1134,6 +1134,9 @@
RESULT = codewriter.portal_graph.getreturnvar().concretetype
self.result_type = history.getkind(RESULT)
#
+ from pypy.jit.metainterp.blackhole import BlackholeInterpBuilder
+ self.blackholeinterpbuilder = BlackholeInterpBuilder(codewriter, self)
+ #
warmrunnerdesc = self.warmrunnerdesc
if warmrunnerdesc is not None:
self.num_green_args = warmrunnerdesc.num_green_args
@@ -1460,6 +1463,7 @@
self.last_exc_value_box = None
def switch_to_blackhole(self, reason):
+ XXX
self.staticdata.profiler.count(reason)
debug_print('~~~ ABORTING TRACING')
debug_stop('jit-tracing')
@@ -1513,10 +1517,7 @@
try:
return self._compile_and_run_once(*args)
finally:
- if self.history is None:
- debug_stop('jit-blackhole')
- else:
- debug_stop('jit-tracing')
+ debug_stop('jit-tracing')
def _compile_and_run_once(self, *args):
original_boxes = self.initialize_state_from_start(*args)
@@ -1539,10 +1540,7 @@
try:
return self._handle_guard_failure(key)
finally:
- if self.history is None:
- debug_stop('jit-blackhole')
- else:
- debug_stop('jit-tracing')
+ debug_stop('jit-tracing')
def _handle_guard_failure(self, key):
from pypy.jit.metainterp.warmspot import ContinueRunningNormallyBase
@@ -1553,6 +1551,7 @@
self.current_merge_points = [(original_greenkey, -1)]
self.resumekey = key
self.seen_can_enter_jit = False
+ xxx
started_as_blackhole = self.is_blackholing()
try:
self.prepare_resume_from_failure(key.guard_opnum)
@@ -1741,6 +1740,7 @@
return original_boxes
def initialize_state_from_guard_failure(self, resumedescr):
+ XXX
# guard failure: rebuild a complete MIFrame stack
self.in_recursion = -1 # always one portal around
inputargs_and_holes = self.cpu.make_boxes_from_latest_values(
Modified: pypy/branch/blackhole-improvement/pypy/jit/metainterp/resume.py
==============================================================================
--- pypy/branch/blackhole-improvement/pypy/jit/metainterp/resume.py (original)
+++ pypy/branch/blackhole-improvement/pypy/jit/metainterp/resume.py Tue May 18 17:04:44 2010
@@ -1,10 +1,10 @@
import sys, os
-from pypy.jit.metainterp.history import Box, Const, ConstInt, INT, REF
+from pypy.jit.metainterp.history import Box, Const, ConstInt, INT, REF, FLOAT
from pypy.jit.metainterp.resoperation import rop
from pypy.jit.metainterp import jitprof
from pypy.rpython.lltypesystem import rffi
from pypy.rlib import rarithmetic
-from pypy.rlib.objectmodel import we_are_translated
+from pypy.rlib.objectmodel import we_are_translated, specialize
from pypy.rlib.debug import have_debug_prints
from pypy.rlib.debug import debug_start, debug_stop, debug_print
@@ -390,7 +390,9 @@
class AbstractVirtualInfo(object):
def allocate(self, metainterp):
raise NotImplementedError
- def setfields(self, metainterp, box, fn_decode_box):
+ #def setfields(self, decoder, struct):
+ # raise NotImplementedError
+ def bh_allocate(self, cpu):
raise NotImplementedError
def equals(self, fieldnums):
return tagged_list_eq(self.fieldnums, fieldnums)
@@ -405,12 +407,14 @@
self.fielddescrs = fielddescrs
#self.fieldnums = ...
- def setfields(self, metainterp, box, fn_decode_box):
+ @specialize.argtype(1)
+ def setfields(self, decoder, struct):
for i in range(len(self.fielddescrs)):
- fieldbox = fn_decode_box(self.fieldnums[i])
- metainterp.execute_and_record(rop.SETFIELD_GC,
- self.fielddescrs[i],
- box, fieldbox)
+ descr = self.fielddescrs[i]
+ decoder.setfield(descr, struct, self.fieldnums[i])
+## fieldbox = fn_decode_box(self.fieldnums[i], kind)
+## metainterp.execute_and_record(rop.SETFIELD_GC,
+## descr, box, fieldbox)
def debug_prints(self):
assert len(self.fielddescrs) == len(self.fieldnums)
@@ -455,12 +459,11 @@
self.arraydescr,
ConstInt(length))
- def setfields(self, metainterp, box, fn_decode_box):
+ @specialize.argtype(1)
+ def setfields(self, decoder, array):
+ arraydescr = self.arraydescr
for i in range(len(self.fieldnums)):
- itembox = fn_decode_box(self.fieldnums[i])
- metainterp.execute_and_record(rop.SETARRAYITEM_GC,
- self.arraydescr,
- box, ConstInt(i), itembox)
+ decoder.setarrayitem(descr, array, i, self.fieldnums[i])
def debug_prints(self):
debug_print("\tvarrayinfo", self.arraydescr)
@@ -496,7 +499,7 @@
return virtualizable_boxes, virtualref_boxes, resumereader.virtuals
-class ResumeDataReader(object):
+class ResumeDataBoxReader(object):
virtuals = None
def __init__(self, storage, liveboxes, metainterp=None):
@@ -545,7 +548,7 @@
self.cur_numb = numb.prev
return boxes
- def _decode_box(self, tagged):
+ def _decode_box(self, tagged, kind):
num, tag = untag(tagged)
if tag == TAGCONST:
if tagged_eq(tagged, NULLREF):
@@ -561,6 +564,164 @@
assert tag == TAGBOX
return self.liveboxes[num]
+
+def blackhole_from_resumedata(blackholeinterpbuilder, storage,
+ expects_virtualizables):
+ resumereader = ResumeDataDirectReader(storage, blackholeinterpbuilder.cpu)
+ if expects_virtualizables:
+ XXX
+ #virtualref_boxes = resumereader.consume_boxes()
+ resumereader.consume_one_section(None) # XXX
+ #
+ # First get a chain of blackhole interpreters whose length is given
+ # by the depth of rd_frame_info_list. The first one we get must be
+ # the bottom one, i.e. the last one in the chain, in order to make
+ # the comment in BlackholeInterpreter.setposition() valid.
+ nextbh = None
+ frameinfo = storage.rd_frame_info_list
+ while True:
+ curbh = blackholeinterpbuilder.acquire_interp()
+ curbh.nextblackholeinterp = nextbh
+ nextbh = curbh
+ frameinfo = frameinfo.prev
+ if frameinfo is None:
+ break
+ firstbh = nextbh
+ #
+ # Now fill the blackhole interpreters with resume data.
+ curbh = firstbh
+ frameinfo = storage.rd_frame_info_list
+ while True:
+ curbh.setposition(frameinfo.jitcode, frameinfo.pc)
+ resumereader.consume_one_section(curbh)
+ curbh = curbh.nextblackholeinterp
+ frameinfo = frameinfo.prev
+ if frameinfo is None:
+ break
+ resumereader.done()
+ return firstbh
+
+class ResumeDataDirectReader(object):
+ virtuals = None
+
+ def __init__(self, storage, cpu):
+ self.cur_numb = storage.rd_numb
+ self.consts = storage.rd_consts
+ self.cpu = cpu
+ self._prepare_virtuals(storage.rd_virtuals)
+ self._prepare_pendingfields(storage.rd_pendingfields)
+
+ def _prepare_virtuals(self, virtuals):
+ if virtuals:
+ self.virtuals = [None] * len(virtuals)
+ for i in range(len(virtuals)):
+ vinfo = virtuals[i]
+ if vinfo is not None:
+ self.virtuals[i] = vinfo.bh_allocate(self.cpu)
+ for i in range(len(virtuals)):
+ vinfo = virtuals[i]
+ if vinfo is not None:
+ vinfo.setfields(self, self.virtuals[i])
+
+ def _prepare_pendingfields(self, pendingfields):
+ if pendingfields is not None:
+ for descr, num, fieldnum in pendingfields:
+ struct = self._decode_ref(num)
+ self.setfield(descr, struct, fieldnum)
+
+ def setfield(self, descr, struct, fieldnum):
+ if descr.is_pointer_field():
+ newvalue = self._decode_ref(fieldnum)
+ self.cpu.bh_setfield_gc_r(struct, descr, newfield)
+ elif descr.is_float_field():
+ newvalue = self._decode_float(fieldnum)
+ self.cpu.bh_setfield_gc_f(struct, descr, newfield)
+ else:
+ newvalue = self._decode_int(fieldnum)
+ self.cpu.bh_setfield_gc_i(struct, descr, newfield)
+
+ def setarrayitem(self, arraydescr, array, index, fieldnum):
+ if arraydescr.is_array_of_pointers():
+ newvalue = self._decode_ref(fieldnum)
+ self.cpu.bh_setarrayitem_gc_r(arraydescr, array, index, newvalue)
+ elif arraydescr.is_array_of_floats():
+ newvalue = self._decode_float(fieldnum)
+ self.cpu.bh_setarrayitem_gc_f(arraydescr, array, index, newvalue)
+ else:
+ newvalue = self._decode_int(fieldnum)
+ self.cpu.bh_setarrayitem_gc_i(arraydescr, array, index, newvalue)
+
+ def consume_one_section(self, blackholeinterp):
+ numb = self.cur_numb
+ count_i = count_r = count_f = 0
+ for num in numb.nums:
+ kind = self._decode_kind(num)
+ if kind == INT:
+ blackholeinterp.setarg_i(count_i, self._decode_int(num))
+ count_i += 1
+ elif kind == REF:
+ blackholeinterp.setarg_r(count_r, self._decode_ref(num))
+ count_r += 1
+ elif kind == FLOAT:
+ blackholeinterp.setarg_f(count_f, self._decode_float(num))
+ count_f += 1
+ self.cur_numb = numb.prev
+
+ def _decode_kind(self, tagged):
+ num, tag = untag(tagged)
+ if tag == TAGCONST:
+ if tagged_eq(tagged, NULLREF):
+ return history.REF
+ return self.consts[num].type
+ elif tag == TAGVIRTUAL:
+ return history.REF
+ elif tag == TAGINT:
+ return history.INT
+ else:
+ assert tag == TAGBOX
+ return self.cpu.get_latest_value_kind(num)
+
+ def _decode_int(self, tagged):
+ num, tag = untag(tagged)
+ if tag == TAGCONST:
+ return self.consts[num].getint()
+ elif tag == TAGINT:
+ return num
+ else:
+ assert tag == TAGBOX
+ if num < 0:
+ num += self.cpu.get_latest_value_count()
+ return self.cpu.get_latest_value_int(num)
+
+ def _decode_ref(self, tagged):
+ num, tag = untag(tagged)
+ if tag == TAGCONST:
+ if tagged_eq(tagged, NULLREF):
+ return self.cpu.ts.NULLREF
+ return self.consts[num].getptr_base()
+ elif tag == TAGVIRTUAL:
+ virtuals = self.virtuals
+ assert virtuals is not None
+ return virtuals[num]
+ else:
+ assert tag == TAGBOX
+ if num < 0:
+ num += self.cpu.get_latest_value_count()
+ return self.cpu.get_latest_value_ref(num)
+
+ def _decode_float(self, tagged):
+ num, tag = untag(tagged)
+ if tag == TAGCONST:
+ return self.consts[num].getfloat()
+ else:
+ assert tag == TAGBOX
+ if num < 0:
+ num += self.cpu.get_latest_value_count()
+ return self.cpu.get_latest_value_float(num)
+
+ def done(self):
+ self.cpu.clear_latest_values()
+
# ____________________________________________________________
def dump_storage(storage, liveboxes):
Modified: pypy/branch/blackhole-improvement/pypy/jit/metainterp/test/test_basic.py
==============================================================================
--- pypy/branch/blackhole-improvement/pypy/jit/metainterp/test/test_basic.py (original)
+++ pypy/branch/blackhole-improvement/pypy/jit/metainterp/test/test_basic.py Tue May 18 17:04:44 2010
@@ -43,7 +43,8 @@
count_f += 1
else:
raise TypeError(T)
- blackholeinterp.run(cw.mainjitcode, 0)
+ blackholeinterp.setposition(cw.mainjitcode, 0)
+ blackholeinterp.run()
return blackholeinterp._get_result_anytype()
def _run_with_pyjitpl(cw, args, testself):
Modified: pypy/branch/blackhole-improvement/pypy/jit/metainterp/typesystem.py
==============================================================================
--- pypy/branch/blackhole-improvement/pypy/jit/metainterp/typesystem.py (original)
+++ pypy/branch/blackhole-improvement/pypy/jit/metainterp/typesystem.py Tue May 18 17:04:44 2010
@@ -45,7 +45,8 @@
BoxRef = history.BoxPtr
ConstRef = history.ConstPtr
loops_done_with_this_frame_ref = None # patched by compile.py
- CONST_NULL = history.ConstPtr(history.ConstPtr.value)
+ NULLREF = history.ConstPtr.value
+ CONST_NULL = history.ConstPtr(NULLREF)
CVAL_NULLREF = None # patched by optimizeopt.py
def new_ConstRef(self, x):
@@ -150,7 +151,8 @@
BoxRef = history.BoxObj
ConstRef = history.ConstObj
loops_done_with_this_frame_ref = None # patched by compile.py
- CONST_NULL = history.ConstObj(history.ConstObj.value)
+ NULLREF = history.ConstObj.value
+ CONST_NULL = history.ConstObj(NULLREF)
CVAL_NULLREF = None # patched by optimizeopt.py
def new_ConstRef(self, x):
Modified: pypy/branch/blackhole-improvement/pypy/jit/metainterp/warmspot.py
==============================================================================
--- pypy/branch/blackhole-improvement/pypy/jit/metainterp/warmspot.py (original)
+++ pypy/branch/blackhole-improvement/pypy/jit/metainterp/warmspot.py Tue May 18 17:04:44 2010
@@ -267,8 +267,7 @@
warmrunnerdesc=self)
def make_exception_classes(self):
- portalfunc_ARGS = unrolling_iterable(
- [(i, 'arg%d' % i, ARG) for i, ARG in enumerate(self.PORTAL_FUNCTYPE.ARGS)])
+
class DoneWithThisFrameVoid(JitException):
def __str__(self):
return 'DoneWithThisFrameVoid()'
@@ -302,18 +301,19 @@
return 'ExitFrameWithExceptionRef(%s)' % (self.value,)
class ContinueRunningNormally(ContinueRunningNormallyBase):
- def __init__(self, argboxes):
- # accepts boxes as argument, but unpacks them immediately
- # before we raise the exception -- the boxes' values will
- # be modified in a 'finally' by restore_patched_boxes().
- from pypy.jit.metainterp.warmstate import unwrap
- for i, name, ARG in portalfunc_ARGS:
- v = unwrap(ARG, argboxes[i])
- setattr(self, name, v)
-
+ def __init__(self, gi, gr, gf, ri, rr, rf):
+ # the six arguments are: lists of green ints, greens refs,
+ # green floats, red ints, red refs, and red floats.
+ self.green_int = gi
+ self.green_ref = gr
+ self.green_float = gf
+ self.red_int = ri
+ self.red_ref = rr
+ self.red_float = rf
def __str__(self):
- return 'ContinueRunningNormally(%s)' % (
- ', '.join(map(str, self.args)),)
+ return 'ContinueRunningNormally(%s, %s, %s, %s, %s, %s)' % (
+ self.green_int, self.green_ref, self.green_float,
+ self.red_int, self.red_ref, self.red_float)
self.DoneWithThisFrameVoid = DoneWithThisFrameVoid
self.DoneWithThisFrameInt = DoneWithThisFrameInt
@@ -327,6 +327,7 @@
self.metainterp_sd.DoneWithThisFrameFloat = DoneWithThisFrameFloat
self.metainterp_sd.ExitFrameWithExceptionRef = ExitFrameWithExceptionRef
self.metainterp_sd.ContinueRunningNormally = ContinueRunningNormally
+
def make_enter_function(self):
from pypy.jit.metainterp.warmstate import WarmEnterState
state = WarmEnterState(self)
@@ -497,13 +498,24 @@
# ____________________________________________________________
# Prepare the portal_runner() helper
#
+ from pypy.jit.metainterp.warmstate import specialize_value
portal_ptr = self.cpu.ts.functionptr(PORTALFUNC, 'portal',
graph = portalgraph)
self.portal_ptr = portal_ptr
- portalfunc_ARGS = unrolling_iterable(
- [(i, 'arg%d' % i, ARG) for i, ARG in enumerate(PORTALFUNC.ARGS)])
-
-
+ #
+ portalfunc_ARGS = []
+ nums = {}
+ for i, ARG in enumerate(PORTALFUNC.ARGS):
+ if i < len(self.jitdriver.greens):
+ color = 'green'
+ else:
+ color = 'red'
+ attrname = '%s_%s' % (color, history.getkind(ARG))
+ count = nums.get(attrname, 0)
+ nums[attrname] = count + 1
+ portalfunc_ARGS.append((ARG, attrname, count))
+ portalfunc_ARGS = unrolling_iterable(portalfunc_ARGS)
+ #
rtyper = self.translator.rtyper
RESULT = PORTALFUNC.RESULT
result_kind = history.getkind(RESULT)
@@ -517,21 +529,22 @@
portal_ptr)(*args)
except self.ContinueRunningNormally, e:
args = ()
- for _, name, _ in portalfunc_ARGS:
- v = getattr(e, name)
- args = args + (v,)
+ for ARGTYPE, attrname, count in portalfunc_ARGS:
+ x = getattr(e, attrname)[count]
+ x = specialize_value(ARGTYPE, x)
+ args = args + (x,)
except self.DoneWithThisFrameVoid:
assert result_kind == 'void'
return
except self.DoneWithThisFrameInt, e:
assert result_kind == 'int'
- return lltype.cast_primitive(RESULT, e.result)
+ return specialize_value(RESULT, e.result)
except self.DoneWithThisFrameRef, e:
assert result_kind == 'ref'
- return ts.cast_from_ref(RESULT, e.result)
+ return specialize_value(RESULT, e.result)
except self.DoneWithThisFrameFloat, e:
assert result_kind == 'float'
- return e.result
+ return specialize_value(RESULT, e.result)
except self.ExitFrameWithExceptionRef, e:
value = ts.cast_to_baseclass(e.value)
if not we_are_translated():
@@ -561,6 +574,7 @@
loop_token = fail_descr.handle_fail(self.metainterp_sd)
fail_descr = self.cpu.execute_token(loop_token)
except self.ContinueRunningNormally, e:
+ xxxxxxxxx
args = ()
for _, name, _ in portalfunc_ARGS:
v = getattr(e, name)
@@ -571,13 +585,13 @@
return
except self.DoneWithThisFrameInt, e:
assert result_kind == 'int'
- return lltype.cast_primitive(RESULT, e.result)
+ return specialize_value(RESULT, e.result)
except self.DoneWithThisFrameRef, e:
assert result_kind == 'ref'
- return ts.cast_from_ref(RESULT, e.result)
+ return specialize_value(RESULT, e.result)
except self.DoneWithThisFrameFloat, e:
assert result_kind == 'float'
- return e.result
+ return specialize_value(RESULT, e.result)
except self.ExitFrameWithExceptionRef, e:
value = ts.cast_to_baseclass(e.value)
if not we_are_translated():
Modified: pypy/branch/blackhole-improvement/pypy/jit/metainterp/warmstate.py
==============================================================================
--- pypy/branch/blackhole-improvement/pypy/jit/metainterp/warmstate.py (original)
+++ pypy/branch/blackhole-improvement/pypy/jit/metainterp/warmstate.py Tue May 18 17:04:44 2010
@@ -17,6 +17,20 @@
# ____________________________________________________________
@specialize.arg(0)
+def specialize_value(TYPE, x):
+ """'x' must be a Signed, a GCREF or a Float.
+ This function casts it to a more specialized type, like Char or Ptr(..).
+ """
+ INPUT = lltype.typeOf(x)
+ if INPUT is lltype.Signed:
+ return lltype.cast_primitive(TYPE, x) # XXX missing: Ptr(non-gc)
+ elif INPUT is lltype.Float:
+ assert TYPE is lltype.Float
+ return x
+ else:
+ return lltype.cast_opaque_ptr(TYPE, x)
+
+ at specialize.arg(0)
def unwrap(TYPE, box):
if TYPE is lltype.Void:
return None
More information about the Pypy-commit
mailing list