[pypy-svn] r71041 - in pypy/trunk/pypy/jit/metainterp: . test
arigo at codespeak.net
arigo at codespeak.net
Mon Feb 1 19:18:47 CET 2010
Author: arigo
Date: Mon Feb 1 19:18:45 2010
New Revision: 71041
Modified:
pypy/trunk/pypy/jit/metainterp/codewriter.py
pypy/trunk/pypy/jit/metainterp/pyjitpl.py
pypy/trunk/pypy/jit/metainterp/test/test_warmstate.py
pypy/trunk/pypy/jit/metainterp/warmstate.py
Log:
Probably fixes something... Hard to write tests :-(
The issue is what if reds show up at places that really
expect greens, like jit_merge_point or recursive_calls.
I think that it's likely that one of these bytecodes
might use the .value in the box without noticing that
it's really a red box, leading to broken generated code.
The fix is to add independent bytecodes before, each one
forcing (if needed) one red box to a green box.
Modified: pypy/trunk/pypy/jit/metainterp/codewriter.py
==============================================================================
--- pypy/trunk/pypy/jit/metainterp/codewriter.py (original)
+++ pypy/trunk/pypy/jit/metainterp/codewriter.py Mon Feb 1 19:18:45 2010
@@ -74,6 +74,7 @@
self.cpu = None
self.portal_runner_ptr = None
self.raise_analyzer = None
+ self.jitdriver = None
def find_all_graphs(self, portal_graph, leave_graph,
policy, supports_floats):
@@ -1187,16 +1188,30 @@
self.var_position(op.args[3]))
def serialize_op_jit_marker(self, op):
+ jitdriver = op.args[1].value
+ if self.codewriter.jitdriver is None:
+ self.codewriter.jitdriver = jitdriver
+ assert jitdriver is self.codewriter.jitdriver
key = op.args[0].value
getattr(self, 'handle_jit_marker__%s' % key)(op)
+ def promote_greens(self, args):
+ self.minimize_variables()
+ num_green_args = len(self.codewriter.jitdriver.greens)
+ for i in range(num_green_args):
+ pos = self.var_position(args[i])
+ if (pos % 2) == 0:
+ self.emit('guard_green', pos//2)
+
def handle_jit_marker__jit_merge_point(self, op):
assert self.portal, "jit_merge_point in non-main graph!"
+ self.promote_greens(op.args[2:])
self.emit('jit_merge_point')
assert ([self.var_position(i) for i in op.args[2:]] ==
range(0, 2*(len(op.args) - 2), 2))
def handle_jit_marker__can_enter_jit(self, op):
+ self.promote_greens(op.args[2:])
self.emit('can_enter_jit')
def serialize_op_direct_call(self, op):
@@ -1266,6 +1281,7 @@
self.register_var(op.result)
def handle_recursive_call(self, op):
+ self.promote_greens(op.args[1:])
self.minimize_variables()
args = op.args[1:]
calldescr, non_void_args = self.codewriter.getcalldescr(op.args[0],
Modified: pypy/trunk/pypy/jit/metainterp/pyjitpl.py
==============================================================================
--- pypy/trunk/pypy/jit/metainterp/pyjitpl.py (original)
+++ pypy/trunk/pypy/jit/metainterp/pyjitpl.py Mon Feb 1 19:18:45 2010
@@ -674,10 +674,10 @@
call_position = 0
if token is not None:
call_position = len(self.metainterp.history.operations)
- # guard value for all green args, needed to make sure
+ # verify that we have all green args, needed to make sure
# that assembler that we call is still correct
greenargs = varargs[1:num_green_args + 1]
- self.generate_guard_value_for_green_args(pc, greenargs)
+ self.verify_green_args(greenargs)
res = self.do_residual_call(varargs, descr=calldescr, exc=True)
if not self.metainterp.is_blackholing() and token is not None:
# XXX fix the call position, <UGLY!>
@@ -782,6 +782,17 @@
constbox = self.implement_guard_value(pc, box)
self.make_result_box(constbox)
+ @arguments("orgpc", "int")
+ def opimpl_guard_green(self, pc, boxindex):
+ """Like guard_value, but overwrites the original box with the const.
+ Used to prevent Boxes from showing up in the greenkey of some
+ operations, like jit_merge_point. The in-place overwriting is
+ convenient for jit_merge_point, which expects self.env to contain
+ not more than the greens+reds described in the jitdriver."""
+ box = self.env[boxindex]
+ constbox = self.implement_guard_value(pc, box)
+ self.env[boxindex] = constbox
+
@arguments("orgpc", "box")
def opimpl_guard_class(self, pc, box):
clsbox = self.cls_of_box(box)
@@ -803,10 +814,10 @@
def opimpl_keepalive(self, box):
pass # xxx?
- def generate_guard_value_for_green_args(self, pc, varargs):
+ def verify_green_args(self, varargs):
num_green_args = self.metainterp.staticdata.num_green_args
for i in range(num_green_args):
- varargs[i] = self.implement_guard_value(pc, varargs[i])
+ assert isinstance(varargs[i], Const)
def blackhole_reached_merge_point(self, varargs):
if self.metainterp.in_recursion:
@@ -829,8 +840,8 @@
else:
raise self.metainterp.staticdata.ContinueRunningNormally(varargs)
- @arguments("orgpc")
- def opimpl_can_enter_jit(self, pc):
+ @arguments()
+ def opimpl_can_enter_jit(self):
# Note: when running with a BlackHole history, this 'can_enter_jit'
# may be completely skipped by the logic that replaces perform_call
# with rop.CALL. But in that case, no-one will check the flag anyway,
@@ -840,10 +851,10 @@
raise CannotInlineCanEnterJit()
self.metainterp.seen_can_enter_jit = True
- @arguments("orgpc")
- def opimpl_jit_merge_point(self, pc):
+ @arguments()
+ def opimpl_jit_merge_point(self):
if not self.metainterp.is_blackholing():
- self.generate_guard_value_for_green_args(pc, self.env)
+ self.verify_green_args(self.env)
# xxx we may disable the following line in some context later
self.debug_merge_point()
if self.metainterp.seen_can_enter_jit:
@@ -1025,6 +1036,9 @@
return guard_op
def implement_guard_value(self, pc, box):
+ """Promote the given Box into a Const. Note: be careful, it's a
+ bit unclear what occurs if a single opcode needs to generate
+ several ones and/or ones not near the beginning."""
if isinstance(box, Const):
return box # no promotion needed, already a Const
else:
Modified: pypy/trunk/pypy/jit/metainterp/test/test_warmstate.py
==============================================================================
--- pypy/trunk/pypy/jit/metainterp/test/test_warmstate.py (original)
+++ pypy/trunk/pypy/jit/metainterp/test/test_warmstate.py Mon Feb 1 19:18:45 2010
@@ -145,7 +145,7 @@
green_args_spec = [lltype.Signed, lltype.Float]
state = WarmEnterState(FakeWarmRunnerDesc())
unwrap_greenkey = state.make_unwrap_greenkey()
- greenargs = unwrap_greenkey([BoxInt(42), BoxFloat(42.5)])
+ greenargs = unwrap_greenkey([ConstInt(42), ConstFloat(42.5)])
assert greenargs == (42, 42.5)
assert type(greenargs[0]) is int
@@ -155,7 +155,8 @@
get_jitcell_at_ptr = None
state = WarmEnterState(FakeWarmRunnerDesc())
get_jitcell = state.make_jitcell_getter()
- state.attach_unoptimized_bridge_from_interp([BoxInt(5), BoxFloat(2.25)],
+ state.attach_unoptimized_bridge_from_interp([ConstInt(5),
+ ConstFloat(2.25)],
"entry loop token")
cell1 = get_jitcell(5, 2.25)
assert cell1.counter < 0
@@ -174,9 +175,9 @@
return FakeCell()
state.jit_getter = jit_getter
state.make_jitdriver_callbacks()
- res = state.can_inline_callable([BoxInt(5), BoxFloat(42.5)])
+ res = state.can_inline_callable([ConstInt(5), ConstFloat(42.5)])
assert res is True
- res = state.get_location_str([BoxInt(5), BoxFloat(42.5)])
+ res = state.get_location_str([ConstInt(5), ConstFloat(42.5)])
assert res == '(no jitdriver.get_printable_location!)'
def test_make_jitdriver_callbacks_2():
@@ -199,7 +200,7 @@
return FakeCell()
state.jit_getter = jit_getter
state.make_jitdriver_callbacks()
- res = state.can_inline_callable([BoxInt(5), BoxFloat(42.5)])
+ res = state.can_inline_callable([ConstInt(5), ConstFloat(42.5)])
assert res is False
def test_make_jitdriver_callbacks_3():
@@ -218,7 +219,7 @@
get_jitcell_at_ptr = None
state = WarmEnterState(FakeWarmRunnerDesc())
state.make_jitdriver_callbacks()
- res = state.get_location_str([BoxInt(5), BoxFloat(42.5)])
+ res = state.get_location_str([ConstInt(5), ConstFloat(42.5)])
assert res == "hi there"
def test_make_jitdriver_callbacks_4():
Modified: pypy/trunk/pypy/jit/metainterp/warmstate.py
==============================================================================
--- pypy/trunk/pypy/jit/metainterp/warmstate.py (original)
+++ pypy/trunk/pypy/jit/metainterp/warmstate.py Mon Feb 1 19:18:45 2010
@@ -277,7 +277,9 @@
greenargs = ()
i = 0
for TYPE in green_args_spec:
- value = unwrap(TYPE, greenkey[i])
+ greenbox = greenkey[i]
+ assert isinstance(greenbox, history.Const)
+ value = unwrap(TYPE, greenbox)
greenargs += (value,)
i = i + 1
return greenargs
More information about the Pypy-commit
mailing list