Author: Armin Rigo <[email protected]>
Branch: improve-vmprof-testing
Changeset: r86053:2de09f51a345
Date: 2016-08-07 10:46 +0200
http://bitbucket.org/pypy/pypy/changeset/2de09f51a345/
Log: in-progress
diff --git a/rpython/jit/backend/test/test_rvmprof.py
b/rpython/jit/backend/test/test_rvmprof.py
--- a/rpython/jit/backend/test/test_rvmprof.py
+++ b/rpython/jit/backend/test/test_rvmprof.py
@@ -55,7 +55,6 @@
driver.jit_merge_point(code=code, c=c, i=i, codes=codes, n=n)
if code.name == "main":
c = f(codes, codes[1], 1, c)
- driver.can_enter_jit(code=code, c=c, i=i, codes=codes, n=n)
else:
llfn()
c -= 1
@@ -74,6 +73,46 @@
assert visited[:3] == [[(1, 12), (1, 8)], [(1, 12), (1, 8)], [(1, 12),
(1, 8)]]
+ def test_leaving_with_exception(self):
+ visited, llfn, CodeObj, get_code_fn, get_name = self.misc
+ driver = jit.JitDriver(greens=['code'], reds=['c', 'i', 'n', 'codes'])
+
+ class MyExc(Exception):
+ def __init__(self, c):
+ self.c = c
+
+ @vmprof_execute_code("main", get_code_fn,
+ _hack_update_stack_untranslated=True)
+ def f(codes, code, n, c):
+ i = 0
+ while i < n:
+ driver.jit_merge_point(code=code, c=c, i=i, codes=codes, n=n)
+ if code.name == "main":
+ try:
+ f(codes, codes[1], 1, c)
+ except MyExc as e:
+ c = e.c
+ else:
+ llfn()
+ c -= 1
+ i += 1
+ raise MyExc(c)
+
+ def main(n):
+ codes = [CodeObj("main"), CodeObj("not main")]
+ for code in codes:
+ register_code(code, get_name)
+ try:
+ f(codes, codes[0], n, 8)
+ except MyExc as e:
+ return e.c
+
+ null = lltype.nullptr(cintf.VMPROFSTACK)
+ cintf.vmprof_tl_stack.setraw(null)
+ self.meta_interp(main, [30], inline=True)
+ assert visited[:3] == [[(1, 12), (1, 8)], [(1, 12), (1, 8)], [(1, 12),
(1, 8)]]
+
+
def test_one(self):
# py.test.skip("needs thread-locals in the JIT, which is only available
"
# "after translation")
diff --git a/rpython/jit/codewriter/jtransform.py
b/rpython/jit/codewriter/jtransform.py
--- a/rpython/jit/codewriter/jtransform.py
+++ b/rpython/jit/codewriter/jtransform.py
@@ -2082,10 +2082,30 @@
raise NotImplementedError(oopspec_name)
def _handle_rvmprof_call(self, op, oopspec_name, args):
- if oopspec_name != 'rvmprof.code':
+ if oopspec_name != 'rvmprof.jitted':
raise NotImplementedError(oopspec_name)
- c_leaving, v_uniqueid = args
- return SpaceOperation('rvmprof_code', [c_leaving, v_uniqueid], None)
+ c_entering = Constant(0, lltype.Signed)
+ c_leaving = Constant(1, lltype.Signed)
+ v_uniqueid = args[0]
+ op1 = SpaceOperation('rvmprof_code', [c_entering, v_uniqueid], None)
+ op2 = SpaceOperation('rvmprof_code', [c_leaving, v_uniqueid], None)
+ #
+ # fish fish inside the oopspec's graph for the ll_func pointer
+ block = op.args[0].value._obj.graph.startblock
+ while True:
+ assert len(block.exits) == 1
+ nextblock = block.exits[0].target
+ if nextblock.operations == ():
+ break
+ block = nextblock
+ last_op = block.operations[-1]
+ assert last_op.opname == 'direct_call'
+ c_ll_func = last_op.args[0]
+ #
+ args = [c_ll_func] + op.args[2:]
+ ops = self.rewrite_op_direct_call(SpaceOperation('direct_call',
+ args, op.result))
+ return [op1] + ops + [op2]
def rewrite_op_ll_read_timestamp(self, op):
op1 = self.prepare_builtin_call(op, "ll_read_timestamp", [])
diff --git a/rpython/jit/codewriter/test/test_flatten.py
b/rpython/jit/codewriter/test/test_flatten.py
--- a/rpython/jit/codewriter/test/test_flatten.py
+++ b/rpython/jit/codewriter/test/test_flatten.py
@@ -1115,23 +1115,22 @@
from rpython.rlib.rvmprof import cintf
class MyFakeCallControl(FakeCallControl):
def guess_call_kind(self, op):
- if '_code' in repr(op):
+ if 'jitted' in repr(op):
return 'builtin'
return 'residual'
class X:
pass
- def g():
+ def g(x, y):
debug.debug_print("foo")
return X()
- g._dont_inline_ = True
- def f(x):
- cintf.jit_rvmprof_code(0, x)
- res = g()
- cintf.jit_rvmprof_code(1, x)
- return res
- self.encoding_test(f, [42], """
+ @jit.oopspec("rvmprof.jitted(unique_id)")
+ def decorated_jitted_function(unique_id, *args):
+ return g(*args)
+ def f(id, x, y):
+ return decorated_jitted_function(id, x, y)
+ self.encoding_test(f, [42, 56, 74], """
rvmprof_code $0, %i0
- residual_call_r_r $<* fn g>, R[], <Descr> -> %r0
+ residual_call_ir_r $<* fn g>, I[%i1, %i2], R[], <Descr> -> %r0
-live-
rvmprof_code $1, %i0
ref_return %r0
diff --git a/rpython/rlib/rvmprof/cintf.py b/rpython/rlib/rvmprof/cintf.py
--- a/rpython/rlib/rvmprof/cintf.py
+++ b/rpython/rlib/rvmprof/cintf.py
@@ -7,6 +7,7 @@
from rpython.translator.tool.cbuild import ExternalCompilationInfo
from rpython.rtyper.tool import rffi_platform as platform
from rpython.rlib import rthread, jit
+from rpython.rlib.objectmodel import we_are_translated
class VMProfPlatformUnsupported(Exception):
pass
@@ -96,6 +97,8 @@
return s
def leave_code(s):
+ if not we_are_translated():
+ assert vmprof_tl_stack.getraw() == s
vmprof_tl_stack.setraw(s.c_next)
lltype.free(s, flavor='raw')
@@ -107,40 +110,35 @@
# (It uses kind == VMPROF_JITTED_TAG and the VMPROFSTACK is allocated
# in the C stack.)
#
-# - The jitcode for decorated_jitted_function() in rvmprof.py, if
-# we_are_jitted() calls the oopspec'ed function jit_rvmprof_code(),
-# which turns into a simple jitcode opcode. The jitcode has a
-# simple structure:
+# - The jitcode for decorated_jitted_function() in rvmprof.py is
+# special-cased by jtransform.py to produce this:
#
# rvmprof_code(0, unique_id)
-# res = inline_call FUNC
+# res = inline_call FUNC <- for func(*args)
# rvmprof_code(1, unique_id)
+# return res
#
-# with no catch_exception logic for a "finally:" block. Instead the
-# blackhole interp looks for this simple pattern. This is needed
-# because, when a guard fails, the blackhole interp first rebuilds
-# all the intermediate RPython frames; at that point it needs to
-# call enter_code() on all intermediate RPython frames, so it does
-# pattern matching to recognize frames and learn about unique_id.
+# There is no 'catch_exception', but the second 'rvmprof_code' is
+# meant to be executed even in case there was an exception. This is
+# done by a special case in pyjitpl.py and blackhole.py. The point
+# is that the above simple pattern can be detected by the blackhole
+# interp, when it first rebuilds all the intermediate RPython
+# frames; at that point it needs to call jit_enter_code() on all
+# intermediate RPython frames, so it does pattern matching to
+# recognize when it must call that and with which 'unique_id' value.
#
# - The jitcode opcode 'rvmprof_code' doesn't produce any resop. When
-# meta-interpreting, it causes pyjitpl to call jit_enter_code(), and
-# jit_leave_code(). There is logic to call jit_leave_code() even if
-# we exit with an exception, even though there is no
-# 'catch_exception'.
-#
-# - When blackholing, the call to jit_enter_code() occurs imediately
-# as described above. For calling jit_leave_code(), we use the same
-# logic, detecting when we need to call it even though there is no
-# 'catch_exception'.
+# meta-interpreting, it causes pyjitpl to call jit_enter_code() or
+# jit_leave_code(). As mentioned above, there is logic to call
+# jit_leave_code() even if we exit with an exception, even though
+# there is no 'catch_exception'. There is similar logic inside
+# the blackhole interpreter.
[email protected]("rvmprof.code(leaving, unique_id)")
-def jit_rvmprof_code(leaving, unique_id):
- """Marker for the JIT. Also called directly from the metainterp and
- the blackhole interp."""
- if not leaving:
- enter_code(unique_id) # ignore the return value
- else:
- s = vmprof_tl_stack.getraw()
- assert s.c_value == unique_id
- leave_code(s)
+
+def jit_enter_code(unique_id):
+ enter_code(unique_id) # ignore the return value
+
+def jit_leave_code(unique_id):
+ s = vmprof_tl_stack.getraw()
+ assert s.c_value == unique_id
+ leave_code(s)
diff --git a/rpython/rlib/rvmprof/rvmprof.py b/rpython/rlib/rvmprof/rvmprof.py
--- a/rpython/rlib/rvmprof/rvmprof.py
+++ b/rpython/rlib/rvmprof/rvmprof.py
@@ -178,12 +178,9 @@
except cintf.VMProfPlatformUnsupported:
return func
+ @jit.oopspec("rvmprof.jitted(unique_id)")
def decorated_jitted_function(unique_id, *args):
- cintf.jit_rvmprof_code(0, unique_id)
- res = func(*args)
- cintf.jit_rvmprof_code(1, unique_id) # no 'finally:', see
cintf.py
- return res
- decorated_jitted_function._dont_inline_ = True
+ return func(*args)
def decorated_function(*args):
unique_id = get_code_fn(*args)._vmprof_unique_id
@@ -195,7 +192,6 @@
leave_code(x)
else:
return decorated_jitted_function(unique_id, *args)
- decorated_function._always_inline_ = True
decorated_function.__name__ = func.__name__ + '_rvmprof'
return decorated_function
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit