[pypy-svn] pypy out-of-line-guards: Some general progress on out-of-line guards. Merge with preambles and start
fijal
commits-noreply at bitbucket.org
Thu Feb 17 16:07:30 CET 2011
Author: Maciej Fijalkowski <fijall at gmail.com>
Branch: out-of-line-guards
Changeset: r42112:9a10c0355d10
Date: 2011-02-17 07:55 -0700
http://bitbucket.org/pypy/pypy/changeset/9a10c0355d10/
Log: Some general progress on out-of-line guards. Merge with preambles
and start doing the right thing when we fail such a guard
diff --git a/pypy/jit/codewriter/codewriter.py b/pypy/jit/codewriter/codewriter.py
--- a/pypy/jit/codewriter/codewriter.py
+++ b/pypy/jit/codewriter/codewriter.py
@@ -49,7 +49,8 @@
# which means mostly producing a linear list of operations and
# inserting jumps or conditional jumps. This is a list of tuples
# of the shape ("opname", arg1, ..., argN) or (Label(...),).
- ssarepr = flatten_graph(graph, regallocs, jitcode.entry_point)
+ ssarepr = flatten_graph(graph, regallocs,
+ entry_point=jitcode.entry_point)
#
# step 3b: compute the liveness around certain operations
compute_liveness(ssarepr)
diff --git a/pypy/jit/metainterp/compile.py b/pypy/jit/metainterp/compile.py
--- a/pypy/jit/metainterp/compile.py
+++ b/pypy/jit/metainterp/compile.py
@@ -105,6 +105,7 @@
loop.preamble = create_empty_loop(metainterp, 'Preamble ')
loop.preamble.inputargs = loop.inputargs
loop.preamble.token = make_loop_token(len(loop.inputargs), jitdriver_sd)
+ loop.preamble.token.invalidated_array = metainterp.invalidated_array
loop.preamble.start_resumedescr = start_resumedescr
try:
@@ -400,6 +401,23 @@
self.copy_all_attrbutes_into(res)
return res
+class ResumeGuardInvalidatedDescr(ResumeGuardDescr):
+ def __init__(self, metainterp_sd, jitdriver_sd):
+ self.metainterp_sd = metainterp_sd
+ self.jitdriver_sd = jitdriver_sd
+
+ def handle_fail(self, metainterp_sd, jitdriver_sd):
+ # Failures of GUARD_NOT_INVALIDATED are never compiled,
+ # but always blackhole.
+ from pypy.jit.metainterp.blackhole import resume_in_blackhole
+ resume_in_blackhole(metainterp_sd, jitdriver_sd, self)
+ assert 0
+
+ def _clone_if_mutable(self):
+ res = ResumeGuardInvalidatedDescr(self.metainterp_sd, self.jitdriver_sd)
+ self.copy_all_attrbutes_into(res)
+ return res
+
class ResumeGuardForcedDescr(ResumeGuardDescr):
def __init__(self, metainterp_sd, jitdriver_sd):
diff --git a/pypy/jit/backend/llgraph/runner.py b/pypy/jit/backend/llgraph/runner.py
--- a/pypy/jit/backend/llgraph/runner.py
+++ b/pypy/jit/backend/llgraph/runner.py
@@ -123,7 +123,8 @@
clt = original_loop_token.compiled_loop_token
clt.loop_and_bridges.append(c)
clt.compiling_a_bridge()
- self._compile_loop_or_bridge(c, inputargs, operations)
+ self._compile_loop_or_bridge(c, inputargs, operations,
+ original_loop_token.invalidated_array)
old, oldindex = faildescr._compiled_fail
llimpl.compile_redirect_fail(old, oldindex, c)
@@ -138,14 +139,16 @@
clt.loop_and_bridges = [c]
clt.compiled_version = c
looptoken.compiled_loop_token = clt
- self._compile_loop_or_bridge(c, inputargs, operations)
+ self._compile_loop_or_bridge(c, inputargs, operations,
+ looptoken.invalidated_array)
def free_loop_and_bridges(self, compiled_loop_token):
for c in compiled_loop_token.loop_and_bridges:
llimpl.mark_as_free(c)
model.AbstractCPU.free_loop_and_bridges(self, compiled_loop_token)
- def _compile_loop_or_bridge(self, c, inputargs, operations):
+ def _compile_loop_or_bridge(self, c, inputargs, operations,
+ invalidated_array):
var2index = {}
for box in inputargs:
if isinstance(box, history.BoxInt):
@@ -158,6 +161,7 @@
else:
raise Exception("box is: %r" % (box,))
self._compile_operations(c, operations, var2index)
+ llimpl.compile_add_inv_array(c, invalidated_array)
return c
def _compile_operations(self, c, operations, var2index):
diff --git a/pypy/jit/backend/llgraph/llimpl.py b/pypy/jit/backend/llgraph/llimpl.py
--- a/pypy/jit/backend/llgraph/llimpl.py
+++ b/pypy/jit/backend/llgraph/llimpl.py
@@ -168,7 +168,6 @@
class CompiledLoop(object):
has_been_freed = False
- invalidated = False
def __init__(self):
self.inputargs = []
@@ -294,34 +293,15 @@
del _variables[:]
return _to_opaque(CompiledLoop())
+def compile_add_inv_array(loop, inv_array):
+ loop = _from_opaque(loop)
+ loop.invalidated_array = inv_array
+
def mark_as_free(loop):
loop = _from_opaque(loop)
assert not loop.has_been_freed
loop.has_been_freed = True
-def mark_as_invalid(loop):
- _mark_as_invalid(_from_opaque(loop))
-
-def _mark_as_invalid(loop):
- assert not loop.has_been_freed
- for op in loop.operations:
- if op.is_guard() and op.jump_target is not None:
- _mark_as_invalid(op.jump_target)
- loop.invalidated = True
-
-def invalidate_call_asm(from_loop, ctl):
- from_loop = _from_opaque(from_loop)
- _invalidate_call_asm(from_loop, ctl)
-
-def _invalidate_call_asm(from_loop, ctl):
- for op in from_loop.operations:
- if op.opnum == rop.CALL_ASSEMBLER:
- call_target = op.descr().compiled_loop_token
- if call_target is ctl:
- op.descr = weakref.ref(op.descr()._tmp_token)
- if op.is_guard() and op.jump_target is not None:
- _invalidate_call_asm(op.jump_target, to_loop)
-
def compile_start_int_var(loop):
return compile_start_ref_var(loop, lltype.Signed)
@@ -901,7 +881,6 @@
ctl = loop_token.compiled_loop_token
if hasattr(ctl, 'redirected'):
return self._do_call_assembler(ctl.redirected, *args)
- assert not loop_token.invalidated
assert not self._forced
self._may_force = self.opindex
try:
@@ -960,7 +939,7 @@
raise GuardFailed
def op_guard_not_invalidated(self, descr):
- if self.loop.invalidated:
+ if self.loop.invalidated_array[0]:
raise GuardFailed
class OOFrame(Frame):
@@ -1693,9 +1672,8 @@
setannotation(compile_add_fail, annmodel.SomeInteger())
setannotation(compile_add_fail_arg, annmodel.s_None)
setannotation(compile_redirect_fail, annmodel.s_None)
+setannotation(compile_add_inv_array, annmodel.s_None)
setannotation(mark_as_free, annmodel.s_None)
-setannotation(mark_as_invalid, annmodel.s_None)
-setannotation(invalidate_call_asm, annmodel.s_None)
setannotation(new_frame, s_Frame)
setannotation(frame_clear, annmodel.s_None)
diff --git a/pypy/jit/metainterp/pyjitpl.py b/pypy/jit/metainterp/pyjitpl.py
--- a/pypy/jit/metainterp/pyjitpl.py
+++ b/pypy/jit/metainterp/pyjitpl.py
@@ -1085,6 +1085,9 @@
if opnum == rop.GUARD_NOT_FORCED:
resumedescr = compile.ResumeGuardForcedDescr(metainterp_sd,
metainterp.jitdriver_sd)
+ elif opnum == rop.GUARD_NOT_INVALIDATED:
+ resumedescr = compile.ResumeGuardInvalidatedDescr(metainterp_sd,
+ metainterp.jitdriver_sd)
else:
resumedescr = compile.ResumeGuardDescr()
guard_op = metainterp.history.record(opnum, moreargs, None,
@@ -1696,6 +1699,7 @@
self.resumekey = compile.ResumeFromInterpDescr(original_greenkey)
self.history.inputargs = original_boxes[num_green_args:]
self.seen_loop_header_for_jdindex = -1
+ self.record_guard_not_invalidated()
try:
self.interpret()
except GenerateMergePoint, gmp:
@@ -2302,6 +2306,9 @@
self.history.operations[-1] = newop
return resbox
+ def record_guard_not_invalidated(self):
+ self.framestack[-1].generate_guard(rop.GUARD_NOT_INVALIDATED, None)
+
def direct_assembler_call(self, targetjitdriver_sd):
""" Generate a direct call to assembler for portal entry point,
patching the CALL_MAY_FORCE that occurred just now.
More information about the Pypy-commit
mailing list