[pypy-svn] r79118 - in pypy/branch/jit-free/pypy/jit/metainterp: . test
arigo at codespeak.net
arigo at codespeak.net
Mon Nov 15 19:06:46 CET 2010
Author: arigo
Date: Mon Nov 15 19:06:44 2010
New Revision: 79118
Modified:
pypy/branch/jit-free/pypy/jit/metainterp/blackhole.py
pypy/branch/jit-free/pypy/jit/metainterp/compile.py
pypy/branch/jit-free/pypy/jit/metainterp/history.py
pypy/branch/jit-free/pypy/jit/metainterp/memmgr.py
pypy/branch/jit-free/pypy/jit/metainterp/pyjitpl.py
pypy/branch/jit-free/pypy/jit/metainterp/resume.py
pypy/branch/jit-free/pypy/jit/metainterp/test/test_memmgr.py
pypy/branch/jit-free/pypy/jit/metainterp/warmspot.py
pypy/branch/jit-free/pypy/jit/metainterp/warmstate.py
Log:
In-progress: revert the "cleanup" part of r79094.
It was a really bad idea after all to put a strong reference
from the ResumeDescrs to the LoopToken. Indeed, the LoopTokens
are supposed to be only stored in weak lists on JitCell and be
only be kept alive carefully by memmgr.py.
Modified: pypy/branch/jit-free/pypy/jit/metainterp/blackhole.py
==============================================================================
--- pypy/branch/jit-free/pypy/jit/metainterp/blackhole.py (original)
+++ pypy/branch/jit-free/pypy/jit/metainterp/blackhole.py Mon Nov 15 19:06:44 2010
@@ -1362,12 +1362,14 @@
# We will continue to loop in _run_forever() from the parent level.
return blackholeinterp, lle
-def resume_in_blackhole(metainterp_sd, resumedescr, all_virtuals=None):
+def resume_in_blackhole(metainterp_sd, jitdriver_sd, resumedescr,
+ all_virtuals=None):
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,
+ jitdriver_sd,
resumedescr,
all_virtuals)
current_exc = blackholeinterp._prepare_resume_from_failure(
Modified: pypy/branch/jit-free/pypy/jit/metainterp/compile.py
==============================================================================
--- pypy/branch/jit-free/pypy/jit/metainterp/compile.py (original)
+++ pypy/branch/jit-free/pypy/jit/metainterp/compile.py Mon Nov 15 19:06:44 2010
@@ -42,11 +42,10 @@
name = metainterp.staticdata.stats.name_for_new_loop()
return TreeLoop(name)
-def make_loop_token(cpu, nb_args, jitdriver_sd, greenkey):
+def make_loop_token(cpu, nb_args, jitdriver_sd):
loop_token = LoopToken(cpu)
loop_token.specnodes = [prebuiltNotSpecNode] * nb_args
loop_token.outermost_jitdriver_sd = jitdriver_sd
- loop_token.outermost_greenkey = greenkey
return loop_token
# ____________________________________________________________
@@ -66,7 +65,7 @@
metainterp_sd = metainterp.staticdata
jitdriver_sd = metainterp.jitdriver_sd
loop_token = make_loop_token(metainterp.cpu, len(loop.inputargs),
- jitdriver_sd, greenkey)
+ jitdriver_sd)
loop.token = loop_token
loop.operations[-1].setdescr(loop_token) # patch the target of the JUMP
try:
@@ -143,32 +142,32 @@
pass
class DoneWithThisFrameDescrVoid(_DoneWithThisFrameDescr):
- def handle_fail(self, metainterp_sd):
- #assert jitdriver_sd.result_type == history.VOID
+ def handle_fail(self, metainterp_sd, jitdriver_sd):
+ assert jitdriver_sd.result_type == history.VOID
raise metainterp_sd.DoneWithThisFrameVoid()
class DoneWithThisFrameDescrInt(_DoneWithThisFrameDescr):
- def handle_fail(self, metainterp_sd):
- #assert jitdriver_sd.result_type == history.INT
+ def handle_fail(self, metainterp_sd, jitdriver_sd):
+ assert jitdriver_sd.result_type == history.INT
result = metainterp_sd.cpu.get_latest_value_int(0)
raise metainterp_sd.DoneWithThisFrameInt(result)
class DoneWithThisFrameDescrRef(_DoneWithThisFrameDescr):
- def handle_fail(self, metainterp_sd):
- #assert jitdriver_sd.result_type == history.REF
+ def handle_fail(self, metainterp_sd, jitdriver_sd):
+ assert jitdriver_sd.result_type == history.REF
cpu = metainterp_sd.cpu
result = cpu.get_latest_value_ref(0)
cpu.clear_latest_values(1)
raise metainterp_sd.DoneWithThisFrameRef(cpu, result)
class DoneWithThisFrameDescrFloat(_DoneWithThisFrameDescr):
- def handle_fail(self, metainterp_sd):
- #assert jitdriver_sd.result_type == history.FLOAT
+ def handle_fail(self, metainterp_sd, jitdriver_sd):
+ assert jitdriver_sd.result_type == history.FLOAT
result = metainterp_sd.cpu.get_latest_value_float(0)
raise metainterp_sd.DoneWithThisFrameFloat(result)
class ExitFrameWithExceptionDescrRef(_DoneWithThisFrameDescr):
- def handle_fail(self, metainterp_sd):
+ def handle_fail(self, metainterp_sd, jitdriver_sd):
cpu = metainterp_sd.cpu
value = cpu.get_latest_value_ref(0)
cpu.clear_latest_values(1)
@@ -210,9 +209,8 @@
}
class ResumeDescr(AbstractFailDescr):
- def __init__(self, original_loop_token):
- assert isinstance(original_loop_token, history.LoopToken)
- self.original_loop_token = original_loop_token
+ def __init__(self, original_greenkey):
+ self.original_greenkey = original_greenkey
class ResumeGuardDescr(ResumeDescr):
_counter = 0 # if < 0, there is one counter per value;
@@ -255,29 +253,26 @@
# a negative value
self._counter = cnt | i
- def handle_fail(self, metainterp_sd):
- if self.must_compile(metainterp_sd):
- return self._trace_and_compile_from_bridge(metainterp_sd)
+ def handle_fail(self, metainterp_sd, jitdriver_sd):
+ if self.must_compile(metainterp_sd, jitdriver_sd):
+ return self._trace_and_compile_from_bridge(metainterp_sd,
+ jitdriver_sd)
else:
from pypy.jit.metainterp.blackhole import resume_in_blackhole
- resume_in_blackhole(metainterp_sd, self)
+ resume_in_blackhole(metainterp_sd, jitdriver_sd, self)
assert 0, "unreachable"
- def _trace_and_compile_from_bridge(self, metainterp_sd):
+ def _trace_and_compile_from_bridge(self, metainterp_sd, jitdriver_sd):
+ # 'jitdriver_sd' corresponds to the outermost one, i.e. the one
+ # of the jit_merge_point where we started the loop, even if the
+ # loop itself may contain temporarily recursion into other
+ # jitdrivers.
from pypy.jit.metainterp.pyjitpl import MetaInterp
- metainterp = MetaInterp(metainterp_sd, self.get_jitdriver_sd())
+ metainterp = MetaInterp(metainterp_sd, jitdriver_sd)
return metainterp.handle_guard_failure(self)
_trace_and_compile_from_bridge._dont_inline_ = True
- def get_jitdriver_sd(self):
- # Returns the jitdriver_sd that corresponds to the outermost
- # level, i.e. the level of the jit_merge_point where we started
- # the loop, even if the loop itself may contain some recursion
- # into other jitdrivers.
- return self.original_loop_token.outermost_jitdriver_sd
-
- def must_compile(self, metainterp_sd):
- jitdriver_sd = self.get_jitdriver_sd()
+ def must_compile(self, metainterp_sd, jitdriver_sd):
trace_eagerness = jitdriver_sd.warmstate.trace_eagerness
if self._counter >= 0:
self._counter += 1
@@ -335,18 +330,18 @@
res.rd_pendingfields = self.rd_pendingfields
def _clone_if_mutable(self):
- res = ResumeGuardDescr(self.original_loop_token)
+ res = ResumeGuardDescr(self.original_greenkey)
self.copy_all_attrbutes_into(res)
return res
class ResumeGuardForcedDescr(ResumeGuardDescr):
- def __init__(self, metainterp_sd, original_loop_token, jitdriver_sd):
- ResumeGuardDescr.__init__(self, original_loop_token)
+ def __init__(self, metainterp_sd, original_greenkey, jitdriver_sd):
+ ResumeGuardDescr.__init__(self, original_greenkey)
self.metainterp_sd = metainterp_sd
self.jitdriver_sd = jitdriver_sd
- def handle_fail(self, metainterp_sd):
+ def handle_fail(self, metainterp_sd, jitdriver_sd):
# Failures of a GUARD_NOT_FORCED are never compiled, but
# always just blackholed. First fish for the data saved when
# the virtualrefs and virtualizable have been forced by
@@ -356,7 +351,8 @@
all_virtuals = self.fetch_data(token)
if all_virtuals is None:
all_virtuals = []
- resume_in_blackhole(metainterp_sd, self, all_virtuals)
+ assert jitdriver_sd is self.jitdriver_sd
+ resume_in_blackhole(metainterp_sd, jitdriver_sd, self, all_virtuals)
assert 0, "unreachable"
@staticmethod
@@ -409,7 +405,7 @@
def _clone_if_mutable(self):
res = ResumeGuardForcedDescr(self.metainterp_sd,
- self.original_loop_token,
+ self.original_greenkey,
self.jitdriver_sd)
self.copy_all_attrbutes_into(res)
return res
@@ -476,11 +472,8 @@
class ResumeFromInterpDescr(ResumeDescr):
- def __init__(self, metainterp, greenkey, redkey):
- original_loop_token = make_loop_token(metainterp.cpu, len(redkey),
- metainterp.jitdriver_sd,
- greenkey)
- ResumeDescr.__init__(self, original_loop_token)
+ def __init__(self, original_greenkey, redkey):
+ ResumeDescr.__init__(self, original_greenkey)
self.redkey = redkey
def compile_and_attach(self, metainterp, new_loop):
@@ -491,22 +484,22 @@
metainterp_sd = metainterp.staticdata
jitdriver_sd = metainterp.jitdriver_sd
metainterp.history.inputargs = self.redkey
- new_loop_token = self.original_loop_token
- original_greenkey = new_loop_token.outermost_greenkey
+ new_loop_token = make_loop_token(metainterp.cpu, len(self.redkey),
+ metainterp.jitdriver_sd)
new_loop.inputargs = self.redkey
new_loop.token = new_loop_token
send_loop_to_backend(metainterp_sd, new_loop, "entry bridge")
# send the new_loop to warmspot.py, to be called directly the next time
jitdriver_sd.warmstate.attach_unoptimized_bridge_from_interp(
- original_greenkey,
+ self.original_greenkey,
new_loop_token)
# store the new loop in compiled_merge_points_wref too
old_loop_tokens = metainterp.get_compiled_merge_points(
- original_greenkey)
+ self.original_greenkey)
# it always goes at the end of the list, as it is the most
# general loop token
old_loop_tokens.append(new_loop_token)
- metainterp.set_compiled_merge_points(original_greenkey,
+ metainterp.set_compiled_merge_points(self.original_greenkey,
old_loop_tokens)
def reset_counter_from_failure(self):
@@ -561,7 +554,7 @@
# ____________________________________________________________
class PropagateExceptionDescr(AbstractFailDescr):
- def handle_fail(self, metainterp_sd):
+ def handle_fail(self, metainterp_sd, jitdriver_sd):
cpu = metainterp_sd.cpu
exception = cpu.grab_exc_value()
raise metainterp_sd.ExitFrameWithExceptionRef(cpu, exception)
@@ -575,7 +568,7 @@
"""
# 'redboxes' is only used to know the types of red arguments.
inputargs = [box.clonebox() for box in redboxes]
- loop_token = make_loop_token(cpu, len(inputargs), jitdriver_sd, greenboxes)
+ loop_token = make_loop_token(cpu, len(inputargs), jitdriver_sd)
# 'nb_red_args' might be smaller than len(redboxes),
# because it doesn't include the virtualizable boxes.
nb_red_args = jitdriver_sd.num_red_args
Modified: pypy/branch/jit-free/pypy/jit/metainterp/history.py
==============================================================================
--- pypy/branch/jit-free/pypy/jit/metainterp/history.py (original)
+++ pypy/branch/jit-free/pypy/jit/metainterp/history.py Mon Nov 15 19:06:44 2010
@@ -181,7 +181,7 @@
index = -1
original_loop_token = None
- def handle_fail(self, metainterp_sd):
+ def handle_fail(self, metainterp_sd, jitdriver_sd):
raise NotImplementedError
def compile_and_attach(self, metainterp, new_loop):
raise NotImplementedError
@@ -730,7 +730,6 @@
"""
terminating = False # see TerminatingLoopToken in compile.py
outermost_jitdriver_sd = None
- outermost_greenkey = None
# specnodes = ...
# and more data specified by the backend when the loop is compiled
cpu = None
@@ -759,6 +758,9 @@
self.cpu.free_loop_and_bridges(self)
debug_stop("jit-free-looptoken")
+ def __repr__(self):
+ return '<Loop %d, gen=%d>' % (self.number, self.generation)
+
def repr_of_descr(self):
return '<Loop%d>' % self.number
Modified: pypy/branch/jit-free/pypy/jit/metainterp/memmgr.py
==============================================================================
--- pypy/branch/jit-free/pypy/jit/metainterp/memmgr.py (original)
+++ pypy/branch/jit-free/pypy/jit/metainterp/memmgr.py Mon Nov 15 19:06:44 2010
@@ -59,6 +59,8 @@
def _kill_old_loops_now(self):
debug_start("jit-free-memmgr")
oldtotal = len(self.alive_loops)
+ print self.alive_loops.keys()
+ debug_print("Current generation:", self.current_generation)
debug_print("Loop tokens before:", oldtotal)
max_generation = self.current_generation - self.max_age
for looptoken in self.alive_loops.keys():
@@ -67,4 +69,5 @@
newtotal = len(self.alive_loops)
debug_print("Loop tokens freed: ", oldtotal - newtotal)
debug_print("Loop tokens left: ", newtotal)
+ print self.alive_loops.keys()
debug_stop("jit-free-memmgr")
Modified: pypy/branch/jit-free/pypy/jit/metainterp/pyjitpl.py
==============================================================================
--- pypy/branch/jit-free/pypy/jit/metainterp/pyjitpl.py (original)
+++ pypy/branch/jit-free/pypy/jit/metainterp/pyjitpl.py Mon Nov 15 19:06:44 2010
@@ -1048,13 +1048,13 @@
else:
moreargs = list(extraargs)
metainterp_sd = metainterp.staticdata
- original_loop_token = metainterp.resumekey.original_loop_token
+ original_greenkey = metainterp.resumekey.original_greenkey
if opnum == rop.GUARD_NOT_FORCED:
- resumedescr = compile.ResumeGuardForcedDescr(metainterp.staticdata,
- original_loop_token,
- metainterp.jitdriver_sd)
+ resumedescr = compile.ResumeGuardForcedDescr(metainterp_sd,
+ original_greenkey,
+ metainterp.jitdriver_sd)
else:
- resumedescr = compile.ResumeGuardDescr(original_loop_token)
+ resumedescr = compile.ResumeGuardDescr(original_greenkey)
guard_op = metainterp.history.record(opnum, moreargs, None,
descr=resumedescr)
virtualizable_boxes = None
@@ -1326,6 +1326,11 @@
return jitcode
return None
+ def try_to_free_some_loops(self):
+ # Increase here the generation recorded by the memory manager.
+ if self.warmrunnerdesc is not None: # for tests
+ self.warmrunnerdesc.memory_manager.next_generation()
+
# ---------------- logging ------------------------
def log(self, msg):
@@ -1369,9 +1374,6 @@
self.portal_trace_positions = []
self.free_frames_list = []
self.last_exc_value_box = None
- # Increase here the generation recorded by the memory manager.
- if self.staticdata.warmrunnerdesc is not None: # for tests
- self.staticdata.warmrunnerdesc.memory_manager.next_generation()
def perform_call(self, jitcode, boxes, greenkey=None):
# causes the metainterp to enter the given subfunction
@@ -1622,6 +1624,7 @@
# is also available as 'self.jitdriver_sd', because we need to
# specialize this function and a few other ones for the '*args'.
debug_start('jit-tracing')
+ self.staticdata.try_to_free_some_loops()
self.staticdata._setup_once()
self.staticdata.profiler.start_tracing()
assert jitdriver_sd is self.jitdriver_sd
@@ -1639,7 +1642,7 @@
num_green_args = self.jitdriver_sd.num_green_args
original_greenkey = original_boxes[:num_green_args]
redkey = original_boxes[num_green_args:]
- self.resumekey = compile.ResumeFromInterpDescr(self, original_greenkey,
+ self.resumekey = compile.ResumeFromInterpDescr(original_greenkey,
redkey)
self.seen_loop_header_for_jdindex = -1
try:
@@ -1652,6 +1655,7 @@
def handle_guard_failure(self, key):
debug_start('jit-tracing')
+ self.staticdata.try_to_free_some_loops()
self.staticdata.profiler.start_tracing()
assert isinstance(key, compile.ResumeGuardDescr)
self.initialize_state_from_guard_failure(key)
@@ -1662,7 +1666,7 @@
debug_stop('jit-tracing')
def _handle_guard_failure(self, key):
- original_greenkey = key.original_loop_token.outermost_greenkey
+ original_greenkey = key.original_greenkey
# notice that here we just put the greenkey
# use -1 to mark that we will have to give up
# because we cannot reconstruct the beginning of the proper loop
Modified: pypy/branch/jit-free/pypy/jit/metainterp/resume.py
==============================================================================
--- pypy/branch/jit-free/pypy/jit/metainterp/resume.py (original)
+++ pypy/branch/jit-free/pypy/jit/metainterp/resume.py Mon Nov 15 19:06:44 2010
@@ -915,11 +915,10 @@
# ---------- when resuming for blackholing, get direct values ----------
-def blackhole_from_resumedata(blackholeinterpbuilder, storage,
+def blackhole_from_resumedata(blackholeinterpbuilder, jitdriver_sd, storage,
all_virtuals=None):
resumereader = ResumeDataDirectReader(blackholeinterpbuilder.metainterp_sd,
storage, all_virtuals)
- jitdriver_sd = storage.get_jitdriver_sd()
vinfo = jitdriver_sd.virtualizable_info
ginfo = jitdriver_sd.greenfield_info
vrefinfo = blackholeinterpbuilder.metainterp_sd.virtualref_info
Modified: pypy/branch/jit-free/pypy/jit/metainterp/test/test_memmgr.py
==============================================================================
--- pypy/branch/jit-free/pypy/jit/metainterp/test/test_memmgr.py (original)
+++ pypy/branch/jit-free/pypy/jit/metainterp/test/test_memmgr.py Mon Nov 15 19:06:44 2010
@@ -1,7 +1,6 @@
from pypy.jit.metainterp.memmgr import MemoryManager
-
-##missing:
-## contains_jumps_to needs to be filled
+from pypy.jit.metainterp.test.test_basic import LLJitMixin
+from pypy.rlib.jit import JitDriver
class FakeLoopToken:
@@ -57,3 +56,23 @@
assert tokens[i] not in memmgr.alive_loops
else:
assert tokens[i] in memmgr.alive_loops
+
+
+class TestIntegration(LLJitMixin):
+
+ def test_loop_kept_alive(self):
+ myjitdriver = JitDriver(greens=[], reds=['n'])
+ def g():
+ n = 10
+ while n > 0:
+ myjitdriver.can_enter_jit(n=n)
+ myjitdriver.jit_merge_point(n=n)
+ n = n - 1
+ return 21
+ def f():
+ for i in range(6):
+ g()
+ return 42
+
+ res = self.meta_interp(f, [], loop_longevity=1)
+ assert res == 42
Modified: pypy/branch/jit-free/pypy/jit/metainterp/warmspot.py
==============================================================================
--- pypy/branch/jit-free/pypy/jit/metainterp/warmspot.py (original)
+++ pypy/branch/jit-free/pypy/jit/metainterp/warmspot.py Mon Nov 15 19:06:44 2010
@@ -67,7 +67,8 @@
def jittify_and_run(interp, graph, args, repeat=1,
backendopt=False, trace_limit=sys.maxint,
- debug_level=DEBUG_STEPS, inline=False, **kwds):
+ debug_level=DEBUG_STEPS, inline=False,
+ loop_longevity=0, **kwds):
from pypy.config.config import ConfigError
translator = interp.typer.annotator.translator
try:
@@ -85,6 +86,7 @@
jd.warmstate.set_param_trace_limit(trace_limit)
jd.warmstate.set_param_inlining(inline)
jd.warmstate.set_param_debug(debug_level)
+ jd.warmstate.set_param_loop_longevity(loop_longevity)
warmrunnerdesc.finish()
res = interp.eval_graph(graph, args)
if not kwds.get('translate_support_code', False):
@@ -713,7 +715,7 @@
vinfo.VTYPEPTR, virtualizableref)
vinfo.reset_vable_token(virtualizable)
try:
- loop_token = fail_descr.handle_fail(self.metainterp_sd)
+ loop_token = fail_descr.handle_fail(self.metainterp_sd, jd)
except JitException, e:
return handle_jitexception(e)
fail_descr = self.execute_token(loop_token)
@@ -820,4 +822,5 @@
debug_stop("jit-running")
self.metainterp_sd.profiler.end_running()
self.memory_manager.keep_loop_alive(loop_token)
+ print loop_token
return fail_descr
Modified: pypy/branch/jit-free/pypy/jit/metainterp/warmstate.py
==============================================================================
--- pypy/branch/jit-free/pypy/jit/metainterp/warmstate.py (original)
+++ pypy/branch/jit-free/pypy/jit/metainterp/warmstate.py Mon Nov 15 19:06:44 2010
@@ -340,7 +340,8 @@
fail_descr = warmrunnerdesc.execute_token(loop_token)
if vinfo is not None:
vinfo.reset_vable_token(virtualizable)
- loop_token = fail_descr.handle_fail(metainterp_sd)
+ loop_token = fail_descr.handle_fail(metainterp_sd,
+ jitdriver_sd)
maybe_compile_and_run._dont_inline_ = True
self.maybe_compile_and_run = maybe_compile_and_run
More information about the Pypy-commit
mailing list