[pypy-svn] r76984 - in pypy/branch/jit-generator/pypy/jit: backend/llgraph metainterp metainterp/test
arigo at codespeak.net
arigo at codespeak.net
Thu Sep 9 19:38:25 CEST 2010
Author: arigo
Date: Thu Sep 9 19:38:23 2010
New Revision: 76984
Modified:
pypy/branch/jit-generator/pypy/jit/backend/llgraph/llimpl.py
pypy/branch/jit-generator/pypy/jit/metainterp/compile.py
pypy/branch/jit-generator/pypy/jit/metainterp/jitdriver.py
pypy/branch/jit-generator/pypy/jit/metainterp/pyjitpl.py
pypy/branch/jit-generator/pypy/jit/metainterp/test/test_compile.py
pypy/branch/jit-generator/pypy/jit/metainterp/warmstate.py
Log:
In-progress. Based on compile_tmp_callback() which makes machine code
which actually just calls the portal (and thus the interpreter). With
this, we can at least always use CALL_ASSEMBLER, even if no real machine
code was produced for the target so far. The next step is to patch the
machine code's original CALL_ASSEMBLER to jump to the real place.
Modified: pypy/branch/jit-generator/pypy/jit/backend/llgraph/llimpl.py
==============================================================================
--- pypy/branch/jit-generator/pypy/jit/backend/llgraph/llimpl.py (original)
+++ pypy/branch/jit-generator/pypy/jit/backend/llgraph/llimpl.py Thu Sep 9 19:38:23 2010
@@ -128,7 +128,7 @@
'getarrayitem_raw_pure' : (('ref', 'int'), 'intorptr'),
'arraylen_gc' : (('ref',), 'int'),
'call' : (('ref', 'varargs'), 'intorptr'),
- 'call_assembler' : (('ref', 'varargs'), 'intorptr'),
+ 'call_assembler' : (('varargs',), 'intorptr'),
'cond_call_gc_wb' : (('ptr', 'ptr'), None),
'oosend' : (('varargs',), 'intorptr'),
'oosend_pure' : (('varargs',), 'intorptr'),
Modified: pypy/branch/jit-generator/pypy/jit/metainterp/compile.py
==============================================================================
--- pypy/branch/jit-generator/pypy/jit/metainterp/compile.py (original)
+++ pypy/branch/jit-generator/pypy/jit/metainterp/compile.py Thu Sep 9 19:38:23 2010
@@ -14,6 +14,7 @@
from pypy.jit.metainterp.specnode import NotSpecNode, more_general_specnodes
from pypy.jit.metainterp.typesystem import llhelper, oohelper
from pypy.jit.metainterp.optimizeutil import InvalidLoop
+from pypy.jit.codewriter import heaptracker
def giveup():
from pypy.jit.metainterp.pyjitpl import SwitchToBlackhole
@@ -547,3 +548,51 @@
descr = target_loop_token.finishdescr
new_op = ResOperation(rop.FINISH, op.args, None, descr=descr)
new_loop.operations[-1] = new_op
+
+# ____________________________________________________________
+
+class PropagateExceptionDescr(AbstractFailDescr):
+ def handle_fail(self, metainterp_sd, jitdriver_sd):
+ cpu = metainterp_sd.cpu
+ exception = self.cpu.grab_exc_value()
+ raise metainterp_sd.ExitFrameWithExceptionRef(cpu, exception)
+
+def compile_tmp_callback(cpu, jitdriver_sd, greenkey, redboxes):
+ """Make a LoopToken that corresponds to assembler code that just
+ calls back the interpreter. Used temporarily: a fully compiled
+ version of the code may end up replacing it.
+ """
+ # 'redboxes' is only used to know the types of red arguments
+ inputargs = [box.clonebox() for box in redboxes]
+ loop_token = make_loop_token(len(inputargs), jitdriver_sd)
+ #
+ k = jitdriver_sd.portal_runner_adr
+ funcbox = history.ConstInt(heaptracker.adr2int(k))
+ args = [funcbox] + greenkey + inputargs
+ #
+ result_type = jitdriver_sd.result_type
+ if result_type == history.INT:
+ result = BoxInt()
+ elif result_type == history.REF:
+ result = BoxPtr()
+ elif result_type == history.FLOAT:
+ result = BoxFloat()
+ elif result_type == history.VOID:
+ result = None
+ else:
+ assert 0, "bad result_type"
+ if result is not None:
+ finishargs = []
+ else:
+ finishargs = [result]
+ #
+ jd = jitdriver_sd
+ faildescr = PropagateExceptionDescr()
+ operations = [
+ ResOperation(rop.CALL, args, result, descr=jd.portal_calldescr),
+ ResOperation(rop.GUARD_NO_EXCEPTION, [], None, descr=faildescr),
+ ResOperation(rop.FINISH, finishargs, None, descr=jd.portal_finishtoken)
+ ]
+ operations[1].fail_args = []
+ cpu.compile_loop(inputargs, operations, loop_token)
+ return loop_token
Modified: pypy/branch/jit-generator/pypy/jit/metainterp/jitdriver.py
==============================================================================
--- pypy/branch/jit-generator/pypy/jit/metainterp/jitdriver.py (original)
+++ pypy/branch/jit-generator/pypy/jit/metainterp/jitdriver.py Thu Sep 9 19:38:23 2010
@@ -14,6 +14,7 @@
# self.virtualizable_info... pypy.jit.metainterp.warmspot
# self.warmstate ... pypy.jit.metainterp.warmspot
# self.handle_jitexc_from_bh pypy.jit.metainterp.warmspot
+ # self.portal_finishtoken... pypy.jit.metainterp.pyjitpl
# self.index ... pypy.jit.codewriter.call
# self.mainjitcode ... pypy.jit.codewriter.call
@@ -21,6 +22,7 @@
# self.assembler_helper_adr
# self.index_of_virtualizable
# self.vable_token_descr
+ # self.portal_calldescr
# warmspot sets extra attributes starting with '_' for its own use.
Modified: pypy/branch/jit-generator/pypy/jit/metainterp/pyjitpl.py
==============================================================================
--- pypy/branch/jit-generator/pypy/jit/metainterp/pyjitpl.py (original)
+++ pypy/branch/jit-generator/pypy/jit/metainterp/pyjitpl.py Thu Sep 9 19:38:23 2010
@@ -696,7 +696,7 @@
portal_code = targetjitdriver_sd.mainjitcode
return self.metainterp.perform_call(portal_code, allboxes,
greenkey=greenboxes)
- token = warmrunnerstate.get_assembler_token(greenboxes)
+ token = warmrunnerstate.get_assembler_token(greenboxes, redboxes)
# verify that we have all green args, needed to make sure
# that assembler that we call is still correct
self.verify_green_args(targetjitdriver_sd, greenboxes)
@@ -829,7 +829,7 @@
self.pc = saved_pc
else:
warmrunnerstate = jitdriver_sd.warmstate
- token = warmrunnerstate.get_assembler_token(greenboxes)
+ token = warmrunnerstate.get_assembler_token(greenboxes, redboxes)
# warning! careful here. We have to return from the current
# frame containing the jit_merge_point, and then use
# do_recursive_call() to follow the recursive call. This is
@@ -1217,6 +1217,7 @@
history.FLOAT: 'float',
history.VOID: 'void'}[jd.result_type]
tokens = getattr(self, 'loop_tokens_done_with_this_frame_%s' % name)
+ jd.portal_finishtoken = tokens[0].finishdescr
num = self.cpu.get_fail_descr_number(tokens[0].finishdescr)
setattr(self.cpu, 'done_with_this_frame_%s_v' % name, num)
#
Modified: pypy/branch/jit-generator/pypy/jit/metainterp/test/test_compile.py
==============================================================================
--- pypy/branch/jit-generator/pypy/jit/metainterp/test/test_compile.py (original)
+++ pypy/branch/jit-generator/pypy/jit/metainterp/test/test_compile.py Thu Sep 9 19:38:23 2010
@@ -1,10 +1,11 @@
from pypy.jit.metainterp.history import LoopToken, ConstInt, History, Stats
-from pypy.jit.metainterp.history import BoxInt
+from pypy.jit.metainterp.history import BoxInt, INT
from pypy.jit.metainterp.specnode import NotSpecNode, ConstantSpecNode
from pypy.jit.metainterp.compile import insert_loop_token, compile_new_loop
from pypy.jit.metainterp.compile import ResumeGuardDescr
from pypy.jit.metainterp.compile import ResumeGuardCountersInt
-from pypy.jit.metainterp import optimize, jitprof, typesystem
+from pypy.jit.metainterp.compile import compile_tmp_callback
+from pypy.jit.metainterp import optimize, jitprof, typesystem, compile
from pypy.jit.metainterp.test.oparser import parse
from pypy.jit.metainterp.test.test_optimizefindnode import LLtypeMixin
@@ -154,3 +155,47 @@
count = rgc.see_int(192)
assert count == 1
assert rgc.counters == [1, 1, 7, 6, 1]
+
+
+def test_compile_tmp_callback():
+ from pypy.jit.codewriter import heaptracker
+ from pypy.jit.backend.llgraph import runner
+ from pypy.rpython.lltypesystem import lltype, llmemory
+ from pypy.rpython.annlowlevel import llhelper
+ from pypy.rpython.llinterp import LLException
+ #
+ cpu = runner.LLtypeCPU(None)
+ FUNC = lltype.FuncType([lltype.Signed]*4, lltype.Signed)
+ def ll_portal_runner(g1, g2, r3, r4):
+ assert (g1, g2, r3, r4) == (12, 34, -156, -178)
+ if raiseme:
+ raise raiseme
+ else:
+ return 54321
+ #
+ class FakeJitDriverSD:
+ portal_runner_ptr = llhelper(lltype.Ptr(FUNC), ll_portal_runner)
+ portal_runner_adr = llmemory.cast_ptr_to_adr(portal_runner_ptr)
+ portal_calldescr = cpu.calldescrof(FUNC, FUNC.ARGS, FUNC.RESULT)
+ portal_finishtoken = compile.DoneWithThisFrameDescrInt()
+ result_type = INT
+ #
+ loop_token = compile_tmp_callback(cpu, FakeJitDriverSD(),
+ [ConstInt(12), ConstInt(34)],
+ [BoxInt(56), ConstInt(78)])
+ #
+ raiseme = None
+ cpu.set_future_value_int(0, -156)
+ cpu.set_future_value_int(1, -178)
+ fail_descr = cpu.execute_token(loop_token)
+ assert fail_descr is FakeJitDriverSD().portal_finishtoken
+ #
+ EXC = lltype.GcStruct('EXC')
+ llexc = lltype.malloc(EXC)
+ raiseme = LLException("exception class", llexc)
+ cpu.set_future_value_int(0, -156)
+ cpu.set_future_value_int(1, -178)
+ fail_descr = cpu.execute_token(loop_token)
+ assert isinstance(fail_descr, compile.PropagateExceptionDescr)
+ got = cpu.grab_exc_value()
+ assert lltype.cast_opaque_ptr(lltype.Ptr(EXC), got) == llexc
Modified: pypy/branch/jit-generator/pypy/jit/metainterp/warmstate.py
==============================================================================
--- pypy/branch/jit-generator/pypy/jit/metainterp/warmstate.py (original)
+++ pypy/branch/jit-generator/pypy/jit/metainterp/warmstate.py Thu Sep 9 19:38:23 2010
@@ -491,6 +491,8 @@
#
unwrap_greenkey = self.make_unwrap_greenkey()
jit_getter = self.make_jitcell_getter()
+ jd = self.jitdriver_sd
+ cpu = warmrunnerdesc.cpu
def can_inline_greenargs(*greenargs):
if can_never_inline(*greenargs):
@@ -505,11 +507,14 @@
self.can_inline_greenargs = can_inline_greenargs
self.can_inline_callable = can_inline_callable
- def get_assembler_token(greenkey):
+ def get_assembler_token(greenkey, redboxes):
+ # 'redboxes' is only used to know the types of red arguments
greenargs = unwrap_greenkey(greenkey)
- cell = jit_getter(False, *greenargs)
- if cell is None or cell.counter >= 0:
- return None
+ cell = jit_getter(True, *greenargs)
+ if cell.entry_loop_token is None:
+ from pypy.jit.metainterp.compile import compile_tmp_callback
+ cell.entry_loop_token = compile_tmp_callback(cpu, jd, greenkey,
+ redboxes)
return cell.entry_loop_token
self.get_assembler_token = get_assembler_token
More information about the Pypy-commit
mailing list