[pypy-svn] r69047 - in pypy/trunk/pypy/jit/metainterp: . test
cfbolz at codespeak.net
cfbolz at codespeak.net
Sat Nov 7 16:02:19 CET 2009
Author: cfbolz
Date: Sat Nov 7 16:02:16 2009
New Revision: 69047
Modified:
pypy/trunk/pypy/jit/metainterp/pyjitpl.py
pypy/trunk/pypy/jit/metainterp/test/test_basic.py
pypy/trunk/pypy/jit/metainterp/test/test_blackhole.py
pypy/trunk/pypy/jit/metainterp/test/test_codewriter.py
pypy/trunk/pypy/jit/metainterp/test/test_pyjitpl.py
pypy/trunk/pypy/jit/metainterp/test/test_recursive.py
pypy/trunk/pypy/jit/metainterp/test/test_slist.py
pypy/trunk/pypy/jit/metainterp/test/test_warmstate.py
pypy/trunk/pypy/jit/metainterp/warmspot.py
pypy/trunk/pypy/jit/metainterp/warmstate.py
Log:
(pedronis, cfbolz): merge the jit-less-inlining branch:
------------------------------------------------------------------------
r69045 | cfbolz | 2009-11-07 12:27:08 +0100 (Sat, 07 Nov 2009) | 2 lines
Changed paths:
M /pypy/branch/jit-less-inlining/pypy/jit/metainterp/warmstate.py
(pedronis, cfbolz): add a debug print for disabling inlining of a function
------------------------------------------------------------------------
r69040 | cfbolz | 2009-11-06 16:51:18 +0100 (Fri, 06 Nov 2009) | 2 lines
Changed paths:
M /pypy/branch/jit-less-inlining/pypy/jit/metainterp/test/test_warmstate.py
M /pypy/branch/jit-less-inlining/pypy/jit/metainterp/warmspot.py
(cfbolz, antocuni): fix some more tests
------------------------------------------------------------------------
r69039 | cfbolz | 2009-11-06 16:32:41 +0100 (Fri, 06 Nov 2009) | 2 lines
Changed paths:
M /pypy/branch/jit-less-inlining/pypy/jit/metainterp/test/test_slist.py
fix test_slist
------------------------------------------------------------------------
r69038 | cfbolz | 2009-11-06 16:30:51 +0100 (Fri, 06 Nov 2009) | 2 lines
Changed paths:
M /pypy/branch/jit-less-inlining/pypy/jit/metainterp/test/test_blackhole.py
fix test_blackhole
------------------------------------------------------------------------
r69037 | cfbolz | 2009-11-06 16:25:53 +0100 (Fri, 06 Nov 2009) | 3 lines
Changed paths:
M /pypy/branch/jit-less-inlining/pypy/jit/metainterp/pyjitpl.py
M /pypy/branch/jit-less-inlining/pypy/jit/metainterp/test/test_pyjitpl.py
M /pypy/branch/jit-less-inlining/pypy/jit/metainterp/test/test_recursive.py
M /pypy/branch/jit-less-inlining/pypy/jit/metainterp/warmspot.py
M /pypy/branch/jit-less-inlining/pypy/jit/metainterp/warmstate.py
(pedronis, cfbolz, antocuni): If we abort due to a too long trace, we mark the
longest function as non-inlinable.
------------------------------------------------------------------------
r69036 | cfbolz | 2009-11-06 15:12:48 +0100 (Fri, 06 Nov 2009) | 3 lines
Changed paths:
M /pypy/branch/jit-less-inlining/pypy/jit/metainterp/pyjitpl.py
M /pypy/branch/jit-less-inlining/pypy/jit/metainterp/test/test_pyjitpl.py
(pedronis, cfbolz): make the metainterp keep track of where in the history the
high-level functions start and return.
------------------------------------------------------------------------
r69035 | cfbolz | 2009-11-06 15:11:26 +0100 (Fri, 06 Nov 2009) | 3 lines
Changed paths:
M /pypy/branch/jit-less-inlining/pypy/jit/metainterp/warmspot.py
(pedronis, cfbolz): push and pull to order things in such a way that the
translation tests work again.
------------------------------------------------------------------------
r69034 | cfbolz | 2009-11-06 15:10:51 +0100 (Fri, 06 Nov 2009) | 2 lines
Changed paths:
M /pypy/branch/jit-less-inlining/pypy/jit/metainterp/test/test_codewriter.py
(pedronis, cfbolz): forgot to fix those
------------------------------------------------------------------------
r69033 | cfbolz | 2009-11-06 14:18:03 +0100 (Fri, 06 Nov 2009) | 2 lines
Changed paths:
M /pypy/branch/jit-less-inlining/pypy/jit/metainterp/history.py
(pedronis, cfbolz): this was not meant to be checked in at all.
------------------------------------------------------------------------
r69032 | cfbolz | 2009-11-06 14:07:06 +0100 (Fri, 06 Nov 2009) | 2 lines
Changed paths:
M /pypy/branch/jit-less-inlining/pypy/jit/metainterp/warmspot.py
(pedronis, cfbolz): oops, can_inline can be None
------------------------------------------------------------------------
r69031 | cfbolz | 2009-11-06 14:02:46 +0100 (Fri, 06 Nov 2009) | 3 lines
Changed paths:
M /pypy/branch/jit-less-inlining/pypy/jit/metainterp/history.py
M /pypy/branch/jit-less-inlining/pypy/jit/metainterp/test/test_basic.py
M /pypy/branch/jit-less-inlining/pypy/jit/metainterp/test/test_recursive.py
M /pypy/branch/jit-less-inlining/pypy/jit/metainterp/warmspot.py
(pedronis, cfbolz): a first step towards nirvana: start tracing from the
beginning of functions that cannot be inlined.
Modified: pypy/trunk/pypy/jit/metainterp/pyjitpl.py
==============================================================================
--- pypy/trunk/pypy/jit/metainterp/pyjitpl.py (original)
+++ pypy/trunk/pypy/jit/metainterp/pyjitpl.py Sat Nov 7 16:02:16 2009
@@ -106,7 +106,7 @@
parent_resumedata_snapshot = None
parent_resumedata_frame_info_list = None
- def __init__(self, metainterp, jitcode):
+ def __init__(self, metainterp, jitcode, greenkey=None):
assert isinstance(jitcode, codewriter.JitCode)
self.metainterp = metainterp
self.jitcode = jitcode
@@ -114,6 +114,8 @@
self.constants = jitcode.constants
self.exception_target = -1
self.name = jitcode.name # purely for having name attribute
+ # this is not None for frames that are recursive portal calls
+ self.greenkey = greenkey
# ------------------------------
# Decoding of the JitCode
@@ -589,7 +591,7 @@
result = vinfo.get_array_length(virtualizable, arrayindex)
self.make_result_box(ConstInt(result))
- def perform_call(self, jitcode, varargs):
+ def perform_call(self, jitcode, varargs, greenkey=None):
if (self.metainterp.is_blackholing() and
jitcode.calldescr is not None):
# when producing only a BlackHole, we can implement this by
@@ -613,7 +615,7 @@
return res
else:
# when tracing, this bytecode causes the subfunction to be entered
- f = self.metainterp.newframe(jitcode)
+ f = self.metainterp.newframe(jitcode, greenkey)
f.setup_call(varargs)
return True
@@ -646,7 +648,7 @@
portal_code = self.metainterp.staticdata.portal_code
greenkey = varargs[1:num_green_args + 1]
if warmrunnerstate.can_inline_callable(greenkey):
- return self.perform_call(portal_code, varargs[1:])
+ return self.perform_call(portal_code, varargs[1:], greenkey)
return self.execute_varargs(rop.CALL, varargs, descr=calldescr, exc=True)
@arguments("descr", "varargs")
@@ -1126,14 +1128,19 @@
def __init__(self, staticdata):
self.staticdata = staticdata
self.cpu = staticdata.cpu
+ self.portal_trace_positions = []
+ self.greenkey_of_huge_function = None
def is_blackholing(self):
return self.history is None
- def newframe(self, jitcode):
+ def newframe(self, jitcode, greenkey=None):
if jitcode is self.staticdata.portal_code:
self.in_recursion += 1
- f = MIFrame(self, jitcode)
+ if greenkey is not None and not self.is_blackholing():
+ self.portal_trace_positions.append(
+ (greenkey, len(self.history.operations)))
+ f = MIFrame(self, jitcode, greenkey)
self.framestack.append(f)
return f
@@ -1141,6 +1148,9 @@
frame = self.framestack.pop()
if frame.jitcode is self.staticdata.portal_code:
self.in_recursion -= 1
+ if frame.greenkey is not None and not self.is_blackholing():
+ self.portal_trace_positions.append(
+ (None, len(self.history.operations)))
return frame
def finishframe(self, resultbox):
@@ -1334,6 +1344,8 @@
warmrunnerstate = self.staticdata.state
if len(self.history.operations) > warmrunnerstate.trace_limit:
self.staticdata.profiler.count(ABORT_TOO_LONG)
+ self.greenkey_of_huge_function = self.find_biggest_function()
+ self.portal_trace_positions = None
self.switch_to_blackhole()
def _interpret(self):
@@ -1427,7 +1439,7 @@
except ContinueRunningNormallyBase:
if not started_as_blackhole:
warmrunnerstate = self.staticdata.state
- warmrunnerstate.reset_counter_from_failure(key)
+ warmrunnerstate.reset_counter_from_failure(key, self)
raise
def forget_consts(self, boxes, startindex=0):
@@ -1817,6 +1829,30 @@
if boxes[i] is oldbox:
boxes[i] = newbox
+ def find_biggest_function(self):
+ assert not self.is_blackholing()
+
+ start_stack = []
+ max_size = 0
+ max_key = None
+ for pair in self.portal_trace_positions:
+ key, pos = pair
+ if key is not None:
+ start_stack.append(pair)
+ else:
+ greenkey, startpos = start_stack.pop()
+ size = pos - startpos
+ if size > max_size:
+ max_size = size
+ max_key = greenkey
+ if start_stack:
+ key, pos = start_stack[0]
+ size = len(self.history.operations) - pos
+ if size > max_size:
+ max_size = size
+ max_key = key
+ return max_key
+
class GenerateMergePoint(Exception):
def __init__(self, args, target_loop_token):
Modified: pypy/trunk/pypy/jit/metainterp/test/test_basic.py
==============================================================================
--- pypy/trunk/pypy/jit/metainterp/test/test_basic.py (original)
+++ pypy/trunk/pypy/jit/metainterp/test/test_basic.py Sat Nov 7 16:02:16 2009
@@ -109,7 +109,12 @@
else:
raise Exception("FAILED")
- def check_history_(self, expected=None, **isns):
+ def check_history(self, expected=None, **isns):
+ # this can be used after calling meta_interp
+ get_stats().check_history(expected, **isns)
+
+ def check_operations_history(self, expected=None, **isns):
+ # this can be used after interp_operations
self.metainterp.staticdata.stats.check_history(expected, **isns)
@@ -304,7 +309,7 @@
return externfn(n, n+1)
res = self.interp_operations(f, [6])
assert res == 42
- self.check_history_(int_add=1, int_mul=0, call=1, guard_no_exception=0)
+ self.check_operations_history(int_add=1, int_mul=0, call=1, guard_no_exception=0)
def test_residual_call_pure(self):
def externfn(x, y):
@@ -315,7 +320,7 @@
return externfn(n, n+1)
res = self.interp_operations(f, [6])
assert res == 42
- self.check_history_(int_add=0, int_mul=0, call=0)
+ self.check_operations_history(int_add=0, int_mul=0, call=0)
def test_constant_across_mp(self):
myjitdriver = JitDriver(greens = [], reds = ['n'])
@@ -417,7 +422,7 @@
return a.foo * x
res = self.interp_operations(f, [42])
assert res == 210
- self.check_history_(getfield_gc=1)
+ self.check_operations_history(getfield_gc=1)
def test_getfield_immutable(self):
class A:
@@ -434,7 +439,7 @@
return a.foo * x
res = self.interp_operations(f, [42])
assert res == 210
- self.check_history_(getfield_gc=0)
+ self.check_operations_history(getfield_gc=0)
def test_setfield_bool(self):
class A:
@@ -748,7 +753,7 @@
return isinstance(obj, B)
res = self.interp_operations(fn, [0])
assert res
- self.check_history_(guard_class=1)
+ self.check_operations_history(guard_class=1)
res = self.interp_operations(fn, [1])
assert not res
@@ -769,7 +774,7 @@
return obj.a
res = self.interp_operations(fn, [1])
assert res == 1
- self.check_history_(guard_class=0, instanceof=0)
+ self.check_operations_history(guard_class=0, instanceof=0)
def test_r_dict(self):
from pypy.rlib.objectmodel import r_dict
@@ -901,7 +906,7 @@
return g(a, b)
res = self.interp_operations(f, [3, 5])
assert res == 8
- self.check_history_(int_add=0, call=1)
+ self.check_operations_history(int_add=0, call=1)
def test_listcomp(self):
myjitdriver = JitDriver(greens = [], reds = ['x', 'y', 'lst'])
@@ -925,7 +930,7 @@
return tup[1]
res = self.interp_operations(f, [3, 5])
assert res == 5
- self.check_history_(setfield_gc=2, getfield_gc_pure=1)
+ self.check_operations_history(setfield_gc=2, getfield_gc_pure=1)
def test_oosend_look_inside_only_one(self):
class A:
Modified: pypy/trunk/pypy/jit/metainterp/test/test_blackhole.py
==============================================================================
--- pypy/trunk/pypy/jit/metainterp/test/test_blackhole.py (original)
+++ pypy/trunk/pypy/jit/metainterp/test/test_blackhole.py Sat Nov 7 16:02:16 2009
@@ -6,8 +6,8 @@
class BlackholeTests(object):
def meta_interp(self, *args):
- def counting_init(frame, metainterp, jitcode):
- previnit(frame, metainterp, jitcode)
+ def counting_init(frame, metainterp, jitcode, greenkey=None):
+ previnit(frame, metainterp, jitcode, greenkey)
self.seen_frames.append(jitcode.name)
#
previnit = pyjitpl.MIFrame.__init__.im_func
Modified: pypy/trunk/pypy/jit/metainterp/test/test_codewriter.py
==============================================================================
--- pypy/trunk/pypy/jit/metainterp/test/test_codewriter.py (original)
+++ pypy/trunk/pypy/jit/metainterp/test/test_codewriter.py Sat Nov 7 16:02:16 2009
@@ -356,7 +356,7 @@
return y.x + 5
res = self.interp_operations(f, [23])
assert res == 28
- self.check_history_(getfield_gc=0, getfield_gc_pure=1, int_add=1)
+ self.check_operations_history(getfield_gc=0, getfield_gc_pure=1, int_add=1)
def test_array(self):
class X(object):
@@ -371,7 +371,7 @@
return a.y[index]
res = self.interp_operations(f, [2], listops=True)
assert res == 30
- self.check_history_(getfield_gc=0, getfield_gc_pure=1,
+ self.check_operations_history(getfield_gc=0, getfield_gc_pure=1,
getarrayitem_gc=0, getarrayitem_gc_pure=1)
@@ -389,7 +389,7 @@
return y.lst[index] + y.y + 5
res = self.interp_operations(f, [23, 0], listops=True)
assert res == 23 + 24 + 5
- self.check_history_(getfield_gc=0, getfield_gc_pure=2,
+ self.check_operations_history(getfield_gc=0, getfield_gc_pure=2,
getarrayitem_gc=0, getarrayitem_gc_pure=1,
int_add=3)
Modified: pypy/trunk/pypy/jit/metainterp/test/test_pyjitpl.py
==============================================================================
--- pypy/trunk/pypy/jit/metainterp/test/test_pyjitpl.py (original)
+++ pypy/trunk/pypy/jit/metainterp/test/test_pyjitpl.py Sat Nov 7 16:02:16 2009
@@ -62,3 +62,44 @@
# 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
+ portal = codewriter.JitCode("portal")
+ portal.code = portal.constants = None
+ class FakeStaticData:
+ cpu = None
+ portal_code = portal
+
+ metainterp = pyjitpl.MetaInterp(FakeStaticData())
+ metainterp.framestack = []
+ class FakeHistory:
+ operations = []
+ history = metainterp.history = FakeHistory()
+ metainterp.newframe(portal, "green1")
+ history.operations.append(1)
+ metainterp.newframe(jitcode)
+ history.operations.append(2)
+ metainterp.newframe(portal, "green2")
+ history.operations.append(3)
+ metainterp.popframe()
+ history.operations.append(4)
+ metainterp.popframe()
+ history.operations.append(5)
+ metainterp.popframe()
+ history.operations.append(6)
+ assert metainterp.portal_trace_positions == [("green1", 0), ("green2", 2),
+ (None, 3), (None, 5)]
+ assert metainterp.find_biggest_function() == "green1"
+
+ metainterp.newframe(portal, "green3")
+ history.operations.append(7)
+ metainterp.newframe(jitcode)
+ history.operations.append(8)
+ assert metainterp.portal_trace_positions == [("green1", 0), ("green2", 2),
+ (None, 3), (None, 5), ("green3", 6)]
+ assert metainterp.find_biggest_function() == "green1"
+
+ history.operations.extend([9, 10, 11, 12])
+ assert metainterp.find_biggest_function() == "green3"
Modified: pypy/trunk/pypy/jit/metainterp/test/test_recursive.py
==============================================================================
--- pypy/trunk/pypy/jit/metainterp/test/test_recursive.py (original)
+++ pypy/trunk/pypy/jit/metainterp/test/test_recursive.py Sat Nov 7 16:02:16 2009
@@ -564,6 +564,91 @@
res = self.meta_interp(main, [100], optimizer=OPTIMIZER_SIMPLE, inline=True)
assert res == main(100)
+ def test_trace_from_start(self):
+ def p(code, pc):
+ code = hlstr(code)
+ return "%s %d %s" % (code, pc, code[pc])
+ def c(code, pc):
+ return "l" not in hlstr(code)
+ myjitdriver = JitDriver(greens=['code', 'pc'], reds=['n'],
+ get_printable_location=p, can_inline=c)
+
+ def f(code, n):
+ pc = 0
+ while pc < len(code):
+
+ myjitdriver.jit_merge_point(n=n, code=code, pc=pc)
+ op = code[pc]
+ if op == "+":
+ n += 7
+ if op == "-":
+ n -= 1
+ if op == "c":
+ n = f('---', n)
+ elif op == "l":
+ if n > 0:
+ myjitdriver.can_enter_jit(n=n, code=code, pc=1)
+ pc = 1
+ continue
+ else:
+ assert 0
+ pc += 1
+ return n
+ def g(m):
+ if m > 1000000:
+ f('', 0)
+ result = 0
+ for i in range(m):
+ result += f('+-cl--', i)
+ self.meta_interp(g, [50], backendopt=True)
+ self.check_tree_loop_count(3)
+ self.check_history(int_add=1)
+
+ def test_dont_inline_huge_stuff(self):
+ def p(code, pc):
+ code = hlstr(code)
+ return "%s %d %s" % (code, pc, code[pc])
+ def c(code, pc):
+ return "l" not in hlstr(code)
+ myjitdriver = JitDriver(greens=['code', 'pc'], reds=['n'],
+ get_printable_location=p, can_inline=c)
+
+ def f(code, n):
+ pc = 0
+ while pc < len(code):
+
+ myjitdriver.jit_merge_point(n=n, code=code, pc=pc)
+ op = code[pc]
+ if op == "-":
+ n -= 1
+ elif op == "c":
+ f('--------------------', n)
+ elif op == "l":
+ if n > 0:
+ myjitdriver.can_enter_jit(n=n, code=code, pc=0)
+ pc = 0
+ continue
+ else:
+ assert 0
+ pc += 1
+ return n
+ def g(m):
+ myjitdriver.set_param('inlining', True)
+ # carefully chosen threshold to make sure that the inner function
+ # cannot be inlined, but the inner function on its own is small
+ # enough
+ myjitdriver.set_param('trace_limit', 40)
+ if m > 1000000:
+ f('', 0)
+ result = 0
+ for i in range(m):
+ result += f('-c-----------l-', i+100)
+ self.meta_interp(g, [10], backendopt=True)
+ self.check_aborted_count(1)
+ self.check_history(call=1)
+ self.check_tree_loop_count(3)
+
+
class TestLLtype(RecursiveTests, LLJitMixin):
pass
Modified: pypy/trunk/pypy/jit/metainterp/test/test_slist.py
==============================================================================
--- pypy/trunk/pypy/jit/metainterp/test/test_slist.py (original)
+++ pypy/trunk/pypy/jit/metainterp/test/test_slist.py Sat Nov 7 16:02:16 2009
@@ -35,7 +35,7 @@
return m
res = self.interp_operations(f, [11], listops=True)
assert res == 49
- self.check_history_(call=5)
+ self.check_operations_history(call=5)
def test_list_of_voids(self):
myjitdriver = JitDriver(greens = [], reds = ['n', 'lst'])
@@ -88,7 +88,7 @@
return lst[n]
res = self.interp_operations(f, [-2], listops=True)
assert res == 41
- self.check_history_(call=1)
+ self.check_operations_history(call=1)
# we don't support resizable lists on ootype
#class TestOOtype(ListTests, OOJitMixin):
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 Sat Nov 7 16:02:16 2009
@@ -165,7 +165,13 @@
class FakeWarmRunnerDesc:
can_inline_ptr = None
get_printable_location_ptr = None
+ green_args_spec = [lltype.Signed, lltype.Float]
+ class FakeCell:
+ dont_trace_here = False
state = WarmEnterState(FakeWarmRunnerDesc())
+ def jit_getter(*args):
+ return FakeCell()
+ state.jit_getter = jit_getter
state.make_jitdriver_callbacks()
res = state.can_inline_callable([BoxInt(5), BoxFloat(42.5)])
assert res is True
@@ -179,12 +185,17 @@
return False
CAN_INLINE = lltype.Ptr(lltype.FuncType([lltype.Signed, lltype.Float],
lltype.Bool))
+ class FakeCell:
+ dont_trace_here = False
class FakeWarmRunnerDesc:
rtyper = None
green_args_spec = [lltype.Signed, lltype.Float]
can_inline_ptr = llhelper(CAN_INLINE, can_inline)
get_printable_location_ptr = None
state = WarmEnterState(FakeWarmRunnerDesc())
+ def jit_getter(*args):
+ return FakeCell()
+ state.jit_getter = jit_getter
state.make_jitdriver_callbacks()
res = state.can_inline_callable([BoxInt(5), BoxFloat(42.5)])
assert res is False
Modified: pypy/trunk/pypy/jit/metainterp/warmspot.py
==============================================================================
--- pypy/trunk/pypy/jit/metainterp/warmspot.py (original)
+++ pypy/trunk/pypy/jit/metainterp/warmspot.py Sat Nov 7 16:02:16 2009
@@ -161,18 +161,19 @@
self.build_meta_interp(CPUClass, **kwds)
self.make_args_specification()
- self.rewrite_jit_merge_point(policy)
- self.make_driverhook_graphs()
if self.jitdriver.virtualizables:
from pypy.jit.metainterp.virtualizable import VirtualizableInfo
self.metainterp_sd.virtualizable_info = VirtualizableInfo(self)
+ self.make_exception_classes()
+ self.make_driverhook_graphs()
+ self.make_enter_function()
+ self.rewrite_jit_merge_point(policy)
self.codewriter.generate_bytecode(self.metainterp_sd,
self.portal_graph,
self.leave_graph,
self.portal_runner_ptr
)
- self.make_enter_function()
self.rewrite_can_enter_jit()
self.rewrite_set_param()
self.add_profiler_finish()
@@ -262,7 +263,68 @@
self.stats, opt,
ProfilerClass=ProfilerClass,
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()'
+
+ class DoneWithThisFrameInt(JitException):
+ def __init__(self, result):
+ assert lltype.typeOf(result) is lltype.Signed
+ self.result = result
+ def __str__(self):
+ return 'DoneWithThisFrameInt(%s)' % (self.result,)
+
+ class DoneWithThisFrameRef(JitException):
+ def __init__(self, cpu, result):
+ assert lltype.typeOf(result) == cpu.ts.BASETYPE
+ self.result = result
+ def __str__(self):
+ return 'DoneWithThisFrameRef(%s)' % (self.result,)
+
+ class DoneWithThisFrameFloat(JitException):
+ def __init__(self, result):
+ assert lltype.typeOf(result) is lltype.Float
+ self.result = result
+ def __str__(self):
+ return 'DoneWithThisFrameFloat(%s)' % (self.result,)
+
+ class ExitFrameWithExceptionRef(JitException):
+ def __init__(self, cpu, value):
+ assert lltype.typeOf(value) == cpu.ts.BASETYPE
+ self.value = value
+ def __str__(self):
+ 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 __str__(self):
+ return 'ContinueRunningNormally(%s)' % (
+ ', '.join(map(str, self.args)),)
+
+ self.DoneWithThisFrameVoid = DoneWithThisFrameVoid
+ self.DoneWithThisFrameInt = DoneWithThisFrameInt
+ self.DoneWithThisFrameRef = DoneWithThisFrameRef
+ self.DoneWithThisFrameFloat = DoneWithThisFrameFloat
+ self.ExitFrameWithExceptionRef = ExitFrameWithExceptionRef
+ self.ContinueRunningNormally = ContinueRunningNormally
+ self.metainterp_sd.DoneWithThisFrameVoid = DoneWithThisFrameVoid
+ self.metainterp_sd.DoneWithThisFrameInt = DoneWithThisFrameInt
+ self.metainterp_sd.DoneWithThisFrameRef = DoneWithThisFrameRef
+ 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)
@@ -294,9 +356,16 @@
def maybe_enter_jit(*args):
maybe_compile_and_run(*args)
maybe_enter_jit._always_inline_ = True
-
self.maybe_enter_jit_fn = maybe_enter_jit
+ can_inline = self.state.can_inline_greenargs
+ def maybe_enter_from_start(*args):
+ if can_inline is not None and not can_inline(*args[:self.num_green_args]):
+ maybe_compile_and_run(*args)
+ maybe_enter_from_start._always_inline_ = True
+ self.maybe_enter_from_start_fn = maybe_enter_from_start
+
+
def make_leave_jit_graph(self):
self.leave_graph = None
if self.jitdriver.leave:
@@ -439,64 +508,7 @@
portalfunc_ARGS = unrolling_iterable(
[(i, 'arg%d' % i, ARG) for i, ARG in enumerate(PORTALFUNC.ARGS)])
- class DoneWithThisFrameVoid(JitException):
- def __str__(self):
- return 'DoneWithThisFrameVoid()'
-
- class DoneWithThisFrameInt(JitException):
- def __init__(self, result):
- assert lltype.typeOf(result) is lltype.Signed
- self.result = result
- def __str__(self):
- return 'DoneWithThisFrameInt(%s)' % (self.result,)
-
- class DoneWithThisFrameRef(JitException):
- def __init__(self, cpu, result):
- assert lltype.typeOf(result) == cpu.ts.BASETYPE
- self.result = result
- def __str__(self):
- return 'DoneWithThisFrameRef(%s)' % (self.result,)
-
- class DoneWithThisFrameFloat(JitException):
- def __init__(self, result):
- assert lltype.typeOf(result) is lltype.Float
- self.result = result
- def __str__(self):
- return 'DoneWithThisFrameFloat(%s)' % (self.result,)
-
- class ExitFrameWithExceptionRef(JitException):
- def __init__(self, cpu, value):
- assert lltype.typeOf(value) == cpu.ts.BASETYPE
- self.value = value
- def __str__(self):
- 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 __str__(self):
- return 'ContinueRunningNormally(%s)' % (
- ', '.join(map(str, self.args)),)
-
- self.DoneWithThisFrameVoid = DoneWithThisFrameVoid
- self.DoneWithThisFrameInt = DoneWithThisFrameInt
- self.DoneWithThisFrameRef = DoneWithThisFrameRef
- self.DoneWithThisFrameFloat = DoneWithThisFrameFloat
- self.ExitFrameWithExceptionRef = ExitFrameWithExceptionRef
- self.ContinueRunningNormally = ContinueRunningNormally
- self.metainterp_sd.DoneWithThisFrameVoid = DoneWithThisFrameVoid
- self.metainterp_sd.DoneWithThisFrameInt = DoneWithThisFrameInt
- self.metainterp_sd.DoneWithThisFrameRef = DoneWithThisFrameRef
- self.metainterp_sd.DoneWithThisFrameFloat = DoneWithThisFrameFloat
- self.metainterp_sd.ExitFrameWithExceptionRef = ExitFrameWithExceptionRef
- self.metainterp_sd.ContinueRunningNormally = ContinueRunningNormally
rtyper = self.translator.rtyper
RESULT = PORTALFUNC.RESULT
result_kind = history.getkind(RESULT)
@@ -505,26 +517,27 @@
def ll_portal_runner(*args):
while 1:
try:
+ self.maybe_enter_from_start_fn(*args)
return support.maybe_on_top_of_llinterp(rtyper,
portal_ptr)(*args)
- except ContinueRunningNormally, e:
+ except self.ContinueRunningNormally, e:
args = ()
for _, name, _ in portalfunc_ARGS:
v = getattr(e, name)
args = args + (v,)
- except DoneWithThisFrameVoid:
+ except self.DoneWithThisFrameVoid:
assert result_kind == 'void'
return
- except DoneWithThisFrameInt, e:
+ except self.DoneWithThisFrameInt, e:
assert result_kind == 'int'
return lltype.cast_primitive(RESULT, e.result)
- except DoneWithThisFrameRef, e:
+ except self.DoneWithThisFrameRef, e:
assert result_kind == 'ref'
return ts.cast_from_ref(RESULT, e.result)
- except DoneWithThisFrameFloat, e:
+ except self.DoneWithThisFrameFloat, e:
assert result_kind == 'float'
return e.result
- except ExitFrameWithExceptionRef, e:
+ except self.ExitFrameWithExceptionRef, e:
value = ts.cast_to_baseclass(e.value)
if not we_are_translated():
raise LLException(ts.get_typeptr(value), value)
Modified: pypy/trunk/pypy/jit/metainterp/warmstate.py
==============================================================================
--- pypy/trunk/pypy/jit/metainterp/warmstate.py (original)
+++ pypy/trunk/pypy/jit/metainterp/warmstate.py Sat Nov 7 16:02:16 2009
@@ -10,7 +10,7 @@
from pypy.rlib.jit import PARAMETERS, OPTIMIZER_SIMPLE, OPTIMIZER_FULL
from pypy.rlib.jit import DEBUG_PROFILE
from pypy.rlib.jit import BaseJitCell
-from pypy.rlib.debug import debug_start, debug_stop
+from pypy.rlib.debug import debug_start, debug_stop, debug_print
from pypy.jit.metainterp import support, history
# ____________________________________________________________
@@ -161,8 +161,20 @@
key.counter += 1
return key.counter >= self.trace_eagerness
- def reset_counter_from_failure(self, key):
+ def reset_counter_from_failure(self, key, metainterp):
key.counter = 0
+ self.disable_noninlinable_function(metainterp)
+
+ def disable_noninlinable_function(self, metainterp):
+ greenkey = metainterp.greenkey_of_huge_function
+ if greenkey is not None:
+ cell = self.jit_cell_at_key(greenkey)
+ cell.dont_trace_here = True
+ debug_start("jit-disableinlining")
+ sd = self.warmrunnerdesc.metainterp_sd
+ loc = sd.state.get_location_str(greenkey)
+ debug_print("disabled inlining", loc)
+ debug_stop("jit-disableinlining")
def attach_unoptimized_bridge_from_interp(self, greenkey,
entry_loop_token):
@@ -220,6 +232,7 @@
except ContinueRunningNormally:
# the trace got too long, reset the counter
cell.counter = 0
+ self.disable_noninlinable_function(metainterp)
raise
else:
# machine code was already compiled for these greenargs
@@ -274,6 +287,7 @@
class JitCell(BaseJitCell):
counter = 0
compiled_merge_points = None
+ dont_trace_here = False
#
if self.warmrunnerdesc.get_jitcell_at_ptr is None:
jit_getter = self._make_jitcell_getter_default(JitCell)
@@ -428,18 +442,27 @@
return
#
can_inline_ptr = self.warmrunnerdesc.can_inline_ptr
+ unwrap_greenkey = self.make_unwrap_greenkey()
if can_inline_ptr is None:
- def can_inline_callable(greenkey):
+ def can_inline_callable(*greenargs):
return True
else:
rtyper = self.warmrunnerdesc.rtyper
- unwrap_greenkey = self.make_unwrap_greenkey()
#
- def can_inline_callable(greenkey):
- greenargs = unwrap_greenkey(greenkey)
+ def can_inline_callable(*greenargs):
fn = support.maybe_on_top_of_llinterp(rtyper, can_inline_ptr)
return fn(*greenargs)
- self.can_inline_callable = can_inline_callable
+ def can_inline(*greenargs):
+ cell = self.jit_getter(*greenargs)
+ if cell.dont_trace_here:
+ return False
+ return can_inline_callable(*greenargs)
+ self.can_inline_greenargs = can_inline
+ def can_inline_greenkey(greenkey):
+ greenargs = unwrap_greenkey(greenkey)
+ return can_inline(*greenargs)
+ self.can_inline_callable = can_inline_greenkey
+
#
get_location_ptr = self.warmrunnerdesc.get_printable_location_ptr
if get_location_ptr is None:
More information about the Pypy-commit
mailing list