[pypy-svn] pypy out-of-line-guards: replace ropaque calls with simple flag on the looptoken. Backends have to
fijal
commits-noreply at bitbucket.org
Wed Feb 9 10:28:23 CET 2011
Author: Maciej Fijalkowski <fijall at gmail.com>
Branch: out-of-line-guards
Changeset: r41725:4a84157ae216
Date: 2011-02-07 20:47 +0200
http://bitbucket.org/pypy/pypy/changeset/4a84157ae216/
Log: replace ropaque calls with simple flag on the looptoken. Backends
have to be adjusted.
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
@@ -81,6 +81,7 @@
"""Try to compile a new loop by closing the current history back
to the first operation.
"""
+ assert not metainterp.invalidated_array[0]
history = metainterp.history
loop = create_empty_loop(metainterp)
loop.inputargs = history.inputargs
@@ -92,6 +93,7 @@
metainterp_sd = metainterp.staticdata
jitdriver_sd = metainterp.jitdriver_sd
loop_token = make_loop_token(len(loop.inputargs), jitdriver_sd)
+ loop_token.invalidated_array = metainterp.invalidated_array
loop.token = loop_token
loop.operations[-1].setdescr(loop_token) # patch the target of the JUMP
try:
@@ -102,9 +104,6 @@
if old_loop_token is not None:
metainterp.staticdata.log("reusing old loop")
return old_loop_token
- if we_are_translated() or hasattr(metainterp, 'remember_jit_invariants'):
- # for tests
- metainterp.remember_jit_invariants(loop)
send_loop_to_backend(metainterp_sd, loop, "loop")
insert_loop_token(old_loop_tokens, loop_token)
record_loop_or_bridge(loop)
@@ -547,6 +546,7 @@
#
# Attempt to use optimize_bridge(). This may return None in case
# it does not work -- i.e. none of the existing old_loop_tokens match.
+ assert not metainterp.invalidated_array[0]
new_loop = create_empty_loop(metainterp)
new_loop.inputargs = metainterp.history.inputargs
# clone ops, as optimize_bridge can mutate the ops
@@ -567,9 +567,6 @@
# know exactly what we must do (ResumeGuardDescr/ResumeFromInterpDescr)
prepare_last_operation(new_loop, target_loop_token)
resumekey.compile_and_attach(metainterp, new_loop)
- if we_are_translated() or hasattr(metainterp, 'remember_jit_invariants'):
- # for tests
- metainterp.remember_jit_invariants(new_loop)
record_loop_or_bridge(new_loop)
return target_loop_token
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
@@ -5,7 +5,7 @@
import sys
from pypy.rlib.unroll import unrolling_iterable
from pypy.rlib.objectmodel import we_are_translated
-from pypy.rpython.lltypesystem import lltype, llmemory, rclass
+from pypy.rpython.lltypesystem import lltype, llmemory, rclass, rffi
from pypy.rpython.ootypesystem import ootype
from pypy.rpython.llinterp import LLInterpreter
from pypy.jit.metainterp import history
@@ -21,7 +21,6 @@
class MiniStats:
pass
-
class Descr(history.AbstractDescr):
def __init__(self, ofs, typeinfo, extrainfo=None, name=None,
@@ -285,6 +284,9 @@
return self.getdescr(symbolic.get_size(S))
+# can't be on LLtypeCPU thanks to closures not rendered correctly
+INVALIDATED_ARRAY_TP = rffi.CArray(lltype.Signed)
+
class LLtypeCPU(BaseCPU):
is_oo = False
ts = llhelper
@@ -488,32 +490,21 @@
self.latest_frame = frame
return self.get_fail_descr_from_number(fail_index)
+ def create_invalidate_array(self):
+ v = lltype.malloc(INVALIDATED_ARRAY_TP, 1, flavor='raw',
+ track_allocation=False)
+ v[0] = 0
+ return v
+
def get_invalidate_asm(self, TP, fieldname):
def invalidate_asm(arg):
next = getattr(arg, fieldname)
all = []
while next:
- llx = llmemory.weakref_deref(ropaque.ROPAQUE, next.address)
+ llx = rffi.cast(lltype.Ptr(INVALIDATED_ARRAY_TP), next.address)
if llx:
- all.append(ropaque.cast_ropaque_to_obj(history.LoopToken,
- llx))
+ llx[0] = 1
next = next.next
-
- while all:
- next = all.pop()
- next.invalidated = True
- compiled = next.compiled_loop_token.compiled_version
- llimpl.mark_as_invalid(compiled)
- for elem in next._back_looptokens_call_asm:
- token = elem()
- if token:
- tk = token.compiled_loop_token.compiled_version
- llimpl.invalidate_call_asm(tk,
- next.compiled_loop_token)
- for elem in next._back_looptokens:
- elem = elem()
- if elem:
- all.append(elem)
return invalidate_asm
class OOtypeCPU_xxx_disabled(BaseCPU):
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
@@ -1,5 +1,5 @@
import py, os, sys
-from pypy.rpython.lltypesystem import lltype, llmemory, rclass
+from pypy.rpython.lltypesystem import lltype, llmemory, rclass, rffi
from pypy.rpython.annlowlevel import cast_instance_to_base_ptr
from pypy.rlib.objectmodel import we_are_translated
from pypy.rlib.unroll import unrolling_iterable
@@ -512,7 +512,7 @@
@arguments("box", "descr", "box")
def _opimpl_getfield_gc_invariant_any(self, box, fielddescr, c_func):
- self.metainterp.invariant_structs.append((box, c_func))
+ self.metainterp.mark_invariant_struct(box, c_func)
return self.execute_with_descr(rop.GETFIELD_GC_PURE, fielddescr, box)
opimpl_getfield_gc_i_invariant = _opimpl_getfield_gc_invariant_any
opimpl_getfield_gc_r_invariant = _opimpl_getfield_gc_invariant_any
@@ -1402,7 +1402,7 @@
self.portal_trace_positions = []
self.free_frames_list = []
self.last_exc_value_box = None
- self.invariant_structs = []
+ self.invalidated_array = self.cpu.create_invalidate_array()
def perform_call(self, jitcode, boxes, greenkey=None):
# causes the metainterp to enter the given subfunction
@@ -1842,13 +1842,16 @@
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, 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)
+ if not self.invalidated_array[0]:
+ 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)
self.history.operations.pop() # remove the JUMP
def compile_bridge(self, live_arg_boxes):
+ if self.invalidated_array[0]:
+ return
num_green_args = self.jitdriver_sd.num_green_args
greenkey = live_arg_boxes[:num_green_args]
old_loop_tokens = self.get_compiled_merge_points(greenkey)
@@ -1863,6 +1866,9 @@
def compile_done_with_this_frame(self, exitbox):
self.gen_store_back_in_virtualizable()
+ if self.invalidated_array[0]:
+ compile.giveup()
+ return
# temporarily put a JUMP to a pseudo-loop
sd = self.staticdata
result_type = self.jitdriver_sd.result_type
@@ -1889,7 +1895,10 @@
def compile_exit_frame_with_exception(self, valuebox):
self.gen_store_back_in_virtualizable()
- # temporarily put a JUMP to a pseudo-loop
+ if self.invalidated_array[0]:
+ compile.giveup()
+ return
+ # temporarily put a JUMP to a pseudo-loop
self.history.record(rop.JUMP, [valuebox], None)
sd = self.staticdata
loop_tokens = sd.loop_tokens_exit_frame_with_exception_ref
@@ -2237,17 +2246,12 @@
op = op.copy_and_change(rop.CALL_ASSEMBLER, args=args, descr=token)
self.history.operations.append(op)
- def remember_jit_invariants(self, loop):
- lllooptoken = ropaque.cast_obj_to_ropaque(loop.token)
- lltoken_weakref = llmemory.weakref_create(lllooptoken)
- seen = {}
- for b_struct, c_appender in self.invariant_structs:
- if (b_struct, c_appender) not in seen:
- adr = heaptracker.int2adr(c_appender.getint())
- ptr = llmemory.cast_adr_to_ptr(adr,
- rclass.ASMCODE_APPENDER_PTR)
- ptr(b_struct.getref_base(), lltoken_weakref)
- seen[(b_struct, c_appender)] = None
+ def mark_invariant_struct(self, b_struct, c_appender):
+ addr = rffi.cast(lltype.Signed, self.invalidated_array)
+ func_addr = heaptracker.int2adr(c_appender.getint())
+ funcptr = llmemory.cast_adr_to_ptr(func_addr,
+ rclass.ASMCODE_APPENDER_PTR)
+ funcptr(b_struct.getref_base(), addr)
# ____________________________________________________________
diff --git a/pypy/jit/codewriter/jtransform.py b/pypy/jit/codewriter/jtransform.py
--- a/pypy/jit/codewriter/jtransform.py
+++ b/pypy/jit/codewriter/jtransform.py
@@ -606,7 +606,7 @@
prev.next = new_asmcode
args_s = [lltype_to_annotation(llmemory.GCREF),
- lltype_to_annotation(llmemory.WeakRefPtr)]
+ lltype_to_annotation(lltype.Signed)]
s_result = lltype_to_annotation(lltype.Void)
mixlevelann = MixLevelHelperAnnotator(self.cpu.rtyper)
c_appender = mixlevelann.constfunc(appender, args_s, s_result)
diff --git a/pypy/jit/metainterp/memmgr.py b/pypy/jit/metainterp/memmgr.py
--- a/pypy/jit/metainterp/memmgr.py
+++ b/pypy/jit/metainterp/memmgr.py
@@ -67,6 +67,7 @@
for looptoken in self.alive_loops.keys():
if (looptoken.invalidated or
0 <= looptoken.generation < max_generation):
+ # XXX free looptoken invalidated ptr
del self.alive_loops[looptoken]
newtotal = len(self.alive_loops)
debug_print("Loop tokens freed: ", oldtotal - newtotal)
diff --git a/pypy/rpython/lltypesystem/rclass.py b/pypy/rpython/lltypesystem/rclass.py
--- a/pypy/rpython/lltypesystem/rclass.py
+++ b/pypy/rpython/lltypesystem/rclass.py
@@ -86,11 +86,13 @@
# a linked-list of assembler codes to invalidate in case jit_invariant_fields
# are modified
+# address is a pointer to a loop-level one-element raw array that's
+# either 0 or 1
ASMCODE = lltype.GcForwardReference()
-ASMCODE.become(GcStruct('asmcode', ('address', llmemory.WeakRefPtr),
+ASMCODE.become(GcStruct('asmcode', ('address', lltype.Signed),
('next', lltype.Ptr(ASMCODE))))
-ASMCODE_APPENDER = lltype.FuncType([llmemory.GCREF, llmemory.WeakRefPtr],
+ASMCODE_APPENDER = lltype.FuncType([llmemory.GCREF, lltype.Signed],
lltype.Void)
ASMCODE_APPENDER_PTR = lltype.Ptr(ASMCODE_APPENDER)
More information about the Pypy-commit
mailing list