[pypy-svn] r79163 - in pypy/branch/jit-free/pypy/jit: backend backend/llgraph metainterp metainterp/test
arigo at codespeak.net
arigo at codespeak.net
Tue Nov 16 19:25:28 CET 2010
Author: arigo
Date: Tue Nov 16 19:25:26 2010
New Revision: 79163
Modified:
pypy/branch/jit-free/pypy/jit/backend/llgraph/runner.py
pypy/branch/jit-free/pypy/jit/backend/model.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/pyjitpl.py
pypy/branch/jit-free/pypy/jit/metainterp/test/test_basic.py
pypy/branch/jit-free/pypy/jit/metainterp/test/test_compile.py
pypy/branch/jit-free/pypy/jit/metainterp/test/test_memmgr.py
pypy/branch/jit-free/pypy/jit/metainterp/test/test_optimizeopt.py
pypy/branch/jit-free/pypy/jit/metainterp/test/test_warmspot.py
pypy/branch/jit-free/pypy/jit/metainterp/warmstate.py
Log:
Merge r79155 from trunk, and hack until tests pass.
Modified: pypy/branch/jit-free/pypy/jit/backend/llgraph/runner.py
==============================================================================
--- pypy/branch/jit-free/pypy/jit/backend/llgraph/runner.py (original)
+++ pypy/branch/jit-free/pypy/jit/backend/llgraph/runner.py Tue Nov 16 19:25:26 2010
@@ -133,7 +133,8 @@
is not.
"""
c = llimpl.compile_start()
- assert not hasattr(loopdescr, '_llgraph_loop_and_bridges')
+ if not we_are_translated():
+ assert not hasattr(loopdescr, '_llgraph_loop_and_bridges')
loopdescr._llgraph_loop_and_bridges = [c]
loopdescr._llgraph_compiled_version = c
self._compile_loop_or_bridge(c, inputargs, operations)
Modified: pypy/branch/jit-free/pypy/jit/backend/model.py
==============================================================================
--- pypy/branch/jit-free/pypy/jit/backend/model.py (original)
+++ pypy/branch/jit-free/pypy/jit/backend/model.py Tue Nov 16 19:25:26 2010
@@ -25,9 +25,6 @@
n = len(lst)
lst.append(descr)
descr.index = n
- looptoken = descr.original_loop_token
- if looptoken is not None:
- looptoken.faildescr_indices.append(n)
return n
def get_fail_descr_from_number(self, n):
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 Tue Nov 16 19:25:26 2010
@@ -1,4 +1,4 @@
-
+import weakref
from pypy.rpython.lltypesystem import lltype
from pypy.rpython.ootypesystem import ootype
from pypy.objspace.flow.model import Constant, Variable
@@ -42,16 +42,43 @@
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
+def record_loop_or_bridge(loop):
+ """Do post-backend recordings and cleanups on 'loop'.
+ """
+ # get the original loop token (corresponding to 'loop', or if that is
+ # a bridge, to the loop that this bridge belongs to)
+ looptoken = loop.token
+ assert looptoken is not None
+ wref = weakref.ref(looptoken)
+ for op in loop.operations:
+ if op.is_guard():
+ resumedescr = op.getdescr()
+ assert isinstance(resumedescr, ResumeDescr)
+ resumedescr.wref_original_loop_token = wref # stick it there
+ n = resumedescr.index
+ if n >= 0: # we also record the resumedescr in this list
+ looptoken.faildescr_indices.append(n)
+ # record that 'looptoken' ends up jumping to 'target_loop_token'
+ target_loop_token = loop.operations[-1].getdescr()
+ if isinstance(target_loop_token, LoopToken):
+ # the following test is not enough to prevent more complicated
+ # cases of cycles, but at least it helps in simple tests of
+ # test_memgr.py
+ if target_loop_token is not looptoken:
+ looptoken.record_jump_to(target_loop_token)
+ loop.operations[-1].setdescr(None) # clear reference
+ # mostly for tests: make sure we don't keep a reference to the LoopToken
+ loop.token = None
+
# ____________________________________________________________
-def compile_new_loop(metainterp, old_loop_tokens, greenkey, start):
+def compile_new_loop(metainterp, old_loop_tokens, start):
"""Try to compile a new loop by closing the current history back
to the first operation.
"""
@@ -64,11 +91,9 @@
h_ops = history.operations
loop.operations = [h_ops[i].clone() for i in range(start, len(h_ops))]
metainterp_sd = metainterp.staticdata
+ cpu = metainterp.cpu
jitdriver_sd = metainterp.jitdriver_sd
- loop_token = metainterp.original_loop_token
- assert len(loop_token.specnodes) == len(loop.inputargs)
- assert loop_token.outermost_jitdriver_sd is jitdriver_sd
- assert loop_token.outermost_greenkey == greenkey
+ loop_token = make_loop_token(cpu, len(loop.inputargs), jitdriver_sd)
loop.token = loop_token
loop.operations[-1].setdescr(loop_token) # patch the target of the JUMP
try:
@@ -81,10 +106,7 @@
return old_loop_token
send_loop_to_backend(metainterp_sd, loop, "loop")
insert_loop_token(old_loop_tokens, loop_token)
- # mostly for tests: make sure we don't keep a reference to the LoopToken
- metainterp.original_loop_token.record_loop_or_bridge(loop)
- loop.token = None
- metainterp.original_loop_token = None
+ record_loop_or_bridge(loop)
return loop_token
def insert_loop_token(old_loop_tokens, loop_token):
@@ -220,8 +242,7 @@
}
class ResumeDescr(AbstractFailDescr):
- def __init__(self, wref_original_loop_token):
- self.wref_original_loop_token = wref_original_loop_token
+ pass
class ResumeGuardDescr(ResumeDescr):
_counter = 0 # if < 0, there is one counter per value;
@@ -324,13 +345,13 @@
def compile_and_attach(self, metainterp, new_loop):
# We managed to create a bridge. Attach the new operations
- # to the corrsponding guard_op and compile from there
+ # to the corresponding guard_op and compile from there
+ new_loop.token = metainterp.resumekey_original_loop_token
inputargs = metainterp.history.inputargs
if not we_are_translated():
self._debug_suboperations = new_loop.operations
send_bridge_to_backend(metainterp.staticdata, self, inputargs,
- new_loop.operations,
- metainterp.original_loop_token)
+ new_loop.operations, new_loop.token)
def copy_all_attrbutes_into(self, res):
# XXX a bit ugly to have to list them all here
@@ -342,14 +363,13 @@
res.rd_pendingfields = self.rd_pendingfields
def _clone_if_mutable(self):
- res = ResumeGuardDescr(self.wref_original_loop_token)
+ res = ResumeGuardDescr()
self.copy_all_attrbutes_into(res)
return res
class ResumeGuardForcedDescr(ResumeGuardDescr):
- def __init__(self, metainterp_sd, wref_original_loop_token, jitdriver_sd):
- ResumeGuardDescr.__init__(self, wref_original_loop_token)
+ def __init__(self, metainterp_sd, jitdriver_sd):
self.metainterp_sd = metainterp_sd
self.jitdriver_sd = jitdriver_sd
@@ -417,7 +437,6 @@
def _clone_if_mutable(self):
res = ResumeGuardForcedDescr(self.metainterp_sd,
- self.wref_original_loop_token,
self.jitdriver_sd)
self.copy_all_attrbutes_into(res)
return res
@@ -484,9 +503,8 @@
class ResumeFromInterpDescr(ResumeDescr):
- def __init__(self, wref_original_loop_token, redkey):
- ResumeDescr.__init__(self, wref_original_loop_token)
- self.redkey = redkey
+ def __init__(self, original_greenkey):
+ self.original_greenkey = original_greenkey
def compile_and_attach(self, metainterp, new_loop):
# We managed to create a bridge going from the interpreter
@@ -494,25 +512,25 @@
# a loop at all but ends in a jump to the target loop. It starts
# with completely unoptimized arguments, as in the interpreter.
metainterp_sd = metainterp.staticdata
+ cpu = metainterp.cpu
jitdriver_sd = metainterp.jitdriver_sd
- metainterp.history.inputargs = self.redkey
- new_loop_token = metainterp.original_loop_token
- # assert that the wref_original_loop_token was kept alive, because
- # it's just the same as metainterp.original_loop_token
- assert new_loop_token is self.wref_original_loop_token()
- new_loop.inputargs = self.redkey
+ redargs = new_loop.inputargs
+ # We make a new LoopToken for this entry bridge, and stick it
+ # to every guard in the loop.
+ new_loop_token = make_loop_token(cpu, len(redargs), jitdriver_sd)
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(
+ self.original_greenkey,
new_loop_token)
# store the new loop in compiled_merge_points_wref too
old_loop_tokens = metainterp.get_compiled_merge_points(
- new_loop_token.outermost_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(new_loop_token.outermost_greenkey,
+ metainterp.set_compiled_merge_points(self.original_greenkey,
old_loop_tokens)
def reset_counter_from_failure(self):
@@ -548,11 +566,7 @@
# know exactly what we must do (ResumeGuardDescr/ResumeFromInterpDescr)
prepare_last_operation(new_loop, target_loop_token)
resumekey.compile_and_attach(metainterp, new_loop)
- # mostly for tests: make sure we don't keep a reference
- # to the LoopToken
- metainterp.original_loop_token.record_loop_or_bridge(new_loop)
- metainterp.original_loop_token = None
- new_loop.token = None
+ record_loop_or_bridge(new_loop)
return target_loop_token
def prepare_last_operation(new_loop, target_loop_token):
@@ -586,7 +600,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 Tue Nov 16 19:25:26 2010
@@ -179,7 +179,6 @@
class AbstractFailDescr(AbstractDescr):
index = -1
- original_loop_token = None
def handle_fail(self, metainterp_sd, jitdriver_sd):
raise NotImplementedError
@@ -730,14 +729,13 @@
"""
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
number = -1
+ generation = r_longlong(0)
def __init__(self, cpu=None):
- assert 'CPU' in type(cpu).__name__ # xxx temporary
self.cpu = cpu
# See get_fail_descr_number() in backend/model.py: this growing
# list gives the 'descr_number' of all fail descrs that belong to
@@ -745,27 +743,11 @@
self.faildescr_indices = []
# For memory management of assembled loops
self._keepalive_target_looktokens = {} # set of other LoopTokens
- self.generation = r_longlong(0)
- def record_loop_or_bridge(self, loop):
- # Records that the loop starting at the LoopToken 'self' ends up
- # with 'loop', which may be either the loop itself or some pseudo-
- # loop representing some bridge.
- other_loop_token = loop.operations[-1].getdescr()
- if isinstance(other_loop_token, LoopToken):
- # the following test is not enough to prevent more complicated
- # cases of cycles, but at least it helps in simple tests of
- # test_memgr.py
- if other_loop_token is not self:
- self._keepalive_target_looktokens[other_loop_token] = None
- loop.operations[-1].setdescr(None) # clear reference
+ def record_jump_to(self, target_loop_token):
+ self._keepalive_target_looktokens[target_loop_token] = None
def __del__(self):
- for i in range(160):
- print '#',
- print repr(self), self.cpu
- if self.cpu is None:
- return
if self.generation > r_longlong(0):
# MemoryManager.keep_loop_alive() has been called on this
# loop token, which means that it has been successfully
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 Tue Nov 16 19:25:26 2010
@@ -1048,14 +1048,11 @@
else:
moreargs = list(extraargs)
metainterp_sd = metainterp.staticdata
- resumekey = metainterp.resumekey
- wref_original_loop_token = resumekey.wref_original_loop_token
if opnum == rop.GUARD_NOT_FORCED:
resumedescr = compile.ResumeGuardForcedDescr(metainterp_sd,
- wref_original_loop_token,
metainterp.jitdriver_sd)
else:
- resumedescr = compile.ResumeGuardDescr(wref_original_loop_token)
+ resumedescr = compile.ResumeGuardDescr()
guard_op = metainterp.history.record(opnum, moreargs, None,
descr=resumedescr)
virtualizable_boxes = None
@@ -1642,16 +1639,8 @@
self.current_merge_points = [(original_boxes, 0)]
num_green_args = self.jitdriver_sd.num_green_args
original_greenkey = original_boxes[:num_green_args]
- redkey = original_boxes[num_green_args:]
- # make a new loop token and store a strong ref to it for as long as
- # this MetaInterp is alive (we will give it to the MemoryManager after
- # the backend has emitted assembler)
- self.original_loop_token = compile.make_loop_token(self.cpu,
- len(redkey),
- self.jitdriver_sd,
- original_greenkey)
- self.resumekey = compile.ResumeFromInterpDescr(
- weakref.ref(self.original_loop_token), redkey)
+ self.resumekey = compile.ResumeFromInterpDescr(original_greenkey)
+ self.history.inputargs = original_boxes[num_green_args:]
self.seen_loop_header_for_jdindex = -1
try:
self.interpret()
@@ -1665,29 +1654,26 @@
debug_start('jit-tracing')
self.staticdata.profiler.start_tracing()
assert isinstance(key, compile.ResumeGuardDescr)
+ # store the resumekey.wref_original_loop_token() on 'self' to make
+ # sure that it stays alive as long as this MetaInterp
+ self.resumekey_original_loop_token = key.wref_original_loop_token()
self.initialize_state_from_guard_failure(key)
try:
return self._handle_guard_failure(key)
finally:
+ self.resumekey_original_loop_token = None
self.staticdata.profiler.end_tracing()
debug_stop('jit-tracing')
def _handle_guard_failure(self, key):
- # store the original_loop_token on 'self' to make sure that it stays
- # alive as long as this MetaInterp
+ self.current_merge_points = []
self.resumekey = key
- self.original_loop_token = key.wref_original_loop_token()
+ self.seen_loop_header_for_jdindex = -1
self.staticdata.try_to_free_some_loops()
try:
self.prepare_resume_from_failure(key.guard_opnum)
- if self.original_loop_token is None:
+ if self.resumekey_original_loop_token is None: # very rare case
raise SwitchToBlackhole(ABORT_BRIDGE)
- # 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
- original_greenkey = self.original_loop_token.outermost_greenkey
- self.current_merge_points = [(original_greenkey, -1)]
- self.seen_loop_header_for_jdindex = -1
self.interpret()
except GenerateMergePoint, gmp:
return self.designate_target_loop(gmp)
@@ -1747,7 +1733,7 @@
num_green_args = self.jitdriver_sd.num_green_args
for j in range(len(self.current_merge_points)-1, -1, -1):
original_boxes, start = self.current_merge_points[j]
- assert len(original_boxes) == len(live_arg_boxes) or start < 0
+ assert len(original_boxes) == len(live_arg_boxes)
for i in range(num_green_args):
box1 = original_boxes[i]
box2 = live_arg_boxes[i]
@@ -1756,10 +1742,6 @@
break
else:
# Found! Compile it as a loop.
- if start < 0:
- # we cannot reconstruct the beginning of the proper loop
- raise SwitchToBlackhole(ABORT_BRIDGE)
-
# raises in case it works -- which is the common case
self.compile(original_boxes, live_arg_boxes, start)
# creation of the loop was cancelled!
@@ -1829,8 +1811,7 @@
greenkey = original_boxes[:num_green_args]
old_loop_tokens = self.get_compiled_merge_points(greenkey)
self.history.record(rop.JUMP, live_arg_boxes[num_green_args:], None)
- loop_token = compile.compile_new_loop(self, old_loop_tokens,
- greenkey, start)
+ loop_token = compile.compile_new_loop(self, old_loop_tokens, start)
if loop_token is not None: # raise if it *worked* correctly
self.set_compiled_merge_points(greenkey, old_loop_tokens)
raise GenerateMergePoint(live_arg_boxes, loop_token)
Modified: pypy/branch/jit-free/pypy/jit/metainterp/test/test_basic.py
==============================================================================
--- pypy/branch/jit-free/pypy/jit/metainterp/test/test_basic.py (original)
+++ pypy/branch/jit-free/pypy/jit/metainterp/test/test_basic.py Tue Nov 16 19:25:26 2010
@@ -26,7 +26,7 @@
self.__compiled_merge_points = lst
class FakeWarmRunnerState:
- def attach_unoptimized_bridge_from_interp(self, newloop):
+ def attach_unoptimized_bridge_from_interp(self, greenkey, newloop):
pass
def jit_cell_at_key(self, greenkey):
Modified: pypy/branch/jit-free/pypy/jit/metainterp/test/test_compile.py
==============================================================================
--- pypy/branch/jit-free/pypy/jit/metainterp/test/test_compile.py (original)
+++ pypy/branch/jit-free/pypy/jit/metainterp/test/test_compile.py Tue Nov 16 19:25:26 2010
@@ -5,7 +5,6 @@
from pypy.jit.metainterp.compile import ResumeGuardDescr
from pypy.jit.metainterp.compile import ResumeGuardCountersInt
from pypy.jit.metainterp.compile import compile_tmp_callback
-from pypy.jit.metainterp.compile import send_loop_to_backend
from pypy.jit.metainterp import optimize, jitprof, typesystem, compile
from pypy.jit.metainterp.test.test_optimizefindnode import LLtypeMixin
from pypy.jit.tool.oparser import parse
@@ -55,6 +54,7 @@
stats = Stats()
profiler = jitprof.EmptyProfiler()
+ warmrunnerdesc = None
def log(self, msg, event_kind=None):
pass
@@ -86,7 +86,7 @@
metainterp.history.inputargs = loop.inputargs[:]
#
loop_tokens = []
- loop_token = compile_new_loop(metainterp, loop_tokens, [], 0)
+ loop_token = compile_new_loop(metainterp, loop_tokens, 0)
assert loop_tokens == [loop_token]
assert loop_token.number == 1
assert staticdata.globaldata.loopnumbering == 2
@@ -102,7 +102,7 @@
metainterp.history.operations = loop.operations[:]
metainterp.history.inputargs = loop.inputargs[:]
#
- loop_token_2 = compile_new_loop(metainterp, loop_tokens, [], 0)
+ loop_token_2 = compile_new_loop(metainterp, loop_tokens, 0)
assert loop_token_2 is loop_token
assert loop_tokens == [loop_token]
assert len(cpu.seen) == 0
@@ -213,7 +213,7 @@
cpu.set_future_value_int(2, -190)
fail_descr = cpu.execute_token(loop_token)
try:
- fail_descr.handle_fail(FakeMetaInterpSD())
+ fail_descr.handle_fail(FakeMetaInterpSD(), None)
except FakeMetaInterpSD.ExitFrameWithExceptionRef, e:
assert lltype.cast_opaque_ptr(lltype.Ptr(EXC), e.args[1]) == llexc
else:
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 Tue Nov 16 19:25:26 2010
@@ -144,3 +144,5 @@
res = self.meta_interp(f, [], loop_longevity=3)
assert res == 42
self.check_tree_loop_count(2 + 10*4) # 42 :-)
+
+ #XXXcall_assembler
Modified: pypy/branch/jit-free/pypy/jit/metainterp/test/test_optimizeopt.py
==============================================================================
--- pypy/branch/jit-free/pypy/jit/metainterp/test/test_optimizeopt.py (original)
+++ pypy/branch/jit-free/pypy/jit/metainterp/test/test_optimizeopt.py Tue Nov 16 19:25:26 2010
@@ -41,7 +41,7 @@
b1 = BoxInt()
opt = optimizeopt.Optimizer(FakeMetaInterpStaticData(LLtypeMixin.cpu),
None)
- fdescr = ResumeGuardDescr(history.LoopToken())
+ fdescr = ResumeGuardDescr()
op = ResOperation(rop.GUARD_TRUE, ['dummy'], None, descr=fdescr)
# setup rd data
fi0 = resume.FrameInfo(None, "code0", 11)
Modified: pypy/branch/jit-free/pypy/jit/metainterp/test/test_warmspot.py
==============================================================================
--- pypy/branch/jit-free/pypy/jit/metainterp/test/test_warmspot.py (original)
+++ pypy/branch/jit-free/pypy/jit/metainterp/test/test_warmspot.py Tue Nov 16 19:25:26 2010
@@ -388,7 +388,7 @@
assert isinstance(looptoken, FakeLoopToken)
self.looptoken = looptoken
- def handle_fail(self, metainterp_sd):
+ def handle_fail(self, metainterp_sd, jitdrivers_sd):
no = self.looptoken.no
if no == 0:
raise metainterp_sd.warmrunnerdesc.DoneWithThisFrameInt(3)
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 Tue Nov 16 19:25:26 2010
@@ -255,8 +255,9 @@
debug_print("disabled inlining", loc)
debug_stop("jit-disableinlining")
- def attach_unoptimized_bridge_from_interp(self, entry_loop_token):
- cell = self.jit_cell_at_key(entry_loop_token.outermost_greenkey)
+ def attach_unoptimized_bridge_from_interp(self, greenkey,
+ entry_loop_token):
+ cell = self.jit_cell_at_key(greenkey)
cell.counter = -1
old_token = cell.get_entry_loop_token()
cell.set_entry_loop_token(entry_loop_token)
More information about the Pypy-commit
mailing list