[pypy-svn] r69037 - in pypy/branch/jit-less-inlining/pypy/jit/metainterp: . test
cfbolz at codespeak.net
cfbolz at codespeak.net
Fri Nov 6 16:25:55 CET 2009
Author: cfbolz
Date: Fri Nov 6 16:25:53 2009
New Revision: 69037
Modified:
pypy/branch/jit-less-inlining/pypy/jit/metainterp/pyjitpl.py
pypy/branch/jit-less-inlining/pypy/jit/metainterp/test/test_pyjitpl.py
pypy/branch/jit-less-inlining/pypy/jit/metainterp/test/test_recursive.py
pypy/branch/jit-less-inlining/pypy/jit/metainterp/warmspot.py
pypy/branch/jit-less-inlining/pypy/jit/metainterp/warmstate.py
Log:
(pedronis, cfbolz, antocuni): If we abort due to a too long trace, we mark the
longest function as non-inlinable.
Modified: pypy/branch/jit-less-inlining/pypy/jit/metainterp/pyjitpl.py
==============================================================================
--- pypy/branch/jit-less-inlining/pypy/jit/metainterp/pyjitpl.py (original)
+++ pypy/branch/jit-less-inlining/pypy/jit/metainterp/pyjitpl.py Fri Nov 6 16:25:53 2009
@@ -648,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")
@@ -1129,6 +1129,7 @@
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
@@ -1343,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):
@@ -1436,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):
@@ -1826,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/branch/jit-less-inlining/pypy/jit/metainterp/test/test_pyjitpl.py
==============================================================================
--- pypy/branch/jit-less-inlining/pypy/jit/metainterp/test/test_pyjitpl.py (original)
+++ pypy/branch/jit-less-inlining/pypy/jit/metainterp/test/test_pyjitpl.py Fri Nov 6 16:25:53 2009
@@ -88,5 +88,18 @@
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/branch/jit-less-inlining/pypy/jit/metainterp/test/test_recursive.py
==============================================================================
--- pypy/branch/jit-less-inlining/pypy/jit/metainterp/test/test_recursive.py (original)
+++ pypy/branch/jit-less-inlining/pypy/jit/metainterp/test/test_recursive.py Fri Nov 6 16:25:53 2009
@@ -604,6 +604,49 @@
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):
Modified: pypy/branch/jit-less-inlining/pypy/jit/metainterp/warmspot.py
==============================================================================
--- pypy/branch/jit-less-inlining/pypy/jit/metainterp/warmspot.py (original)
+++ pypy/branch/jit-less-inlining/pypy/jit/metainterp/warmspot.py Fri Nov 6 16:25:53 2009
@@ -358,7 +358,7 @@
maybe_enter_jit._always_inline_ = True
self.maybe_enter_jit_fn = maybe_enter_jit
- can_inline = self.jitdriver.can_inline
+ 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)
Modified: pypy/branch/jit-less-inlining/pypy/jit/metainterp/warmstate.py
==============================================================================
--- pypy/branch/jit-less-inlining/pypy/jit/metainterp/warmstate.py (original)
+++ pypy/branch/jit-less-inlining/pypy/jit/metainterp/warmstate.py Fri Nov 6 16:25:53 2009
@@ -161,8 +161,16 @@
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
+
def attach_unoptimized_bridge_from_interp(self, greenkey,
entry_loop_token):
@@ -220,6 +228,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 +283,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 +438,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