Author: Armin Rigo <ar...@tunes.org> Branch: improve-vmprof-testing Changeset: r86046:11f391e1f1d6 Date: 2016-08-06 16:56 +0200 http://bitbucket.org/pypy/pypy/changeset/11f391e1f1d6/
Log: rvmprof: record the correct Python frames during pyjitpl 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 @@ -452,6 +452,8 @@ prepare = self._handle_math_sqrt_call elif oopspec_name.startswith('rgc.'): prepare = self._handle_rgc_call + elif oopspec_name.startswith('rvmprof.'): + prepare = self._handle_rvmprof_call elif oopspec_name.endswith('dict.lookup'): # also ordereddict.lookup prepare = self._handle_dict_lookup_call @@ -2079,6 +2081,22 @@ else: raise NotImplementedError(oopspec_name) + def _handle_rvmprof_call(self, op, oopspec_name, args): + if oopspec_name == 'rvmprof.enter_code': + leaving = 0 + elif oopspec_name == 'rvmprof.leave_code': + leaving = 1 + else: + raise NotImplementedError(oopspec_name) + c_leaving = Constant(leaving, lltype.Signed) + v_uniqueid = op.args[-1] + ops = [SpaceOperation('rvmprof_code', [c_leaving, v_uniqueid], None)] + if op.result.concretetype is not lltype.Void: + c_null = Constant(lltype.nullptr(op.result.concretetype.TO), + op.result.concretetype) + ops.append(c_null) + return ops + def rewrite_op_ll_read_timestamp(self, op): op1 = self.prepare_builtin_call(op, "ll_read_timestamp", []) return self.handle_residual_call(op1, 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 @@ -140,7 +140,6 @@ def encoding_test(self, func, args, expected, transform=False, liveness=False, cc=None, jd=None): - graphs = self.make_graphs(func, args) #graphs[0].show() if transform: @@ -1112,6 +1111,20 @@ assert str(e.value).startswith("A virtualizable array is passed aroun") assert "<Descr>" in str(e.value) + def test_rvmprof_code(self): + from rpython.rlib.rvmprof import cintf + class MyFakeCallControl(FakeCallControl): + def guess_call_kind(self, op): + return 'builtin' + def f(x): + s = cintf.enter_code(x) + cintf.leave_code(s, x) + self.encoding_test(f, [42], """ + rvmprof_code $0, %i0 + rvmprof_code $1, %i0 + void_return + """, transform=True, cc=MyFakeCallControl()) + def check_force_cast(FROM, TO, operations, value): """Check that the test is correctly written...""" diff --git a/rpython/jit/metainterp/blackhole.py b/rpython/jit/metainterp/blackhole.py --- a/rpython/jit/metainterp/blackhole.py +++ b/rpython/jit/metainterp/blackhole.py @@ -1501,6 +1501,10 @@ def bhimpl_copyunicodecontent(cpu, src, dst, srcstart, dststart, length): cpu.bh_copyunicodecontent(src, dst, srcstart, dststart, length) + @arguments("i", "i") + def bhimpl_rvmprof_code(leaving, unique_id): + pass #import pdb;pdb.set_trace() + # ---------- # helpers to resume running in blackhole mode when a guard failed diff --git a/rpython/jit/metainterp/pyjitpl.py b/rpython/jit/metainterp/pyjitpl.py --- a/rpython/jit/metainterp/pyjitpl.py +++ b/rpython/jit/metainterp/pyjitpl.py @@ -1453,6 +1453,15 @@ metainterp.history.record(rop.VIRTUAL_REF_FINISH, [vrefbox, nullbox], None) + @arguments("int", "box") + def opimpl_rvmprof_code(self, leaving, box_unique_id): + from rpython.rlib.rvmprof import cintf + unique_id = box_unique_id.getint() + if not leaving: + cintf.enter_code(unique_id) + else: + cintf.leave_code_check(unique_id) + # ------------------------------ def setup_call(self, argboxes): 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 @@ -6,7 +6,7 @@ from rpython.rtyper.lltypesystem import lltype, llmemory, rffi from rpython.translator.tool.cbuild import ExternalCompilationInfo from rpython.rtyper.tool import rffi_platform as platform -from rpython.rlib import rthread +from rpython.rlib import rthread, jit class VMProfPlatformUnsupported(Exception): pass @@ -86,6 +86,22 @@ ExternalCompilationInfo(includes=['vmprof_stack.h'], include_dirs = [SRC])) +# JIT notes: +# +# - When running JIT-generated assembler code, we have different custom +# code to build the VMPROFSTACK, so the functions below are not used. +# +# - The jitcode for decorated_function() in rvmprof.py still contains +# calls to these two oopspec functions, which are represented with +# the 'rvmprof_code' jitcode opcode. +# +# - When meta-interpreting, the 'rvmprof_code' opcode causes pyjitpl +# to call enter_code()/leave_code_check(), but otherwise +# 'rvmprof_code' is ignored, i.e. doesn't produce any resop. +# +# - Blackhole: ... + +@jit.oopspec("rvmprof.enter_code(unique_id)") def enter_code(unique_id): do_use_eci() s = lltype.malloc(VMPROFSTACK, flavor='raw') @@ -95,6 +111,12 @@ vmprof_tl_stack.setraw(s) return s -def leave_code(s): +@jit.oopspec("rvmprof.leave_code(s, unique_id)") +def leave_code(s, unique_id): vmprof_tl_stack.setraw(s.c_next) lltype.free(s, flavor='raw') + +def leave_code_check(unique_id): + s = vmprof_tl_stack.getraw() + assert s.c_value == unique_id + leave_code(s, unique_id) 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 @@ -1,6 +1,6 @@ import sys, os from rpython.rlib.objectmodel import specialize, we_are_translated -from rpython.rlib import jit, rposix +from rpython.rlib import rposix from rpython.rlib.rvmprof import cintf from rpython.rtyper.annlowlevel import cast_instance_to_gcref from rpython.rtyper.annlowlevel import cast_base_ptr_to_instance @@ -162,12 +162,19 @@ """ if _hack_update_stack_untranslated: from rpython.rtyper.annlowlevel import llhelper - enter_code = llhelper(lltype.Ptr( + from rpython.rlib import jit + enter_code_untr = llhelper(lltype.Ptr( lltype.FuncType([lltype.Signed], cintf.PVMPROFSTACK)), cintf.enter_code) - leave_code = llhelper(lltype.Ptr( - lltype.FuncType([cintf.PVMPROFSTACK], lltype.Void)), + leave_code_untr = llhelper(lltype.Ptr( + lltype.FuncType([cintf.PVMPROFSTACK, lltype.Signed], lltype.Void)), cintf.leave_code) + @jit.oopspec("rvmprof.enter_code(unique_id)") + def enter_code(unique_id): + return enter_code_untr(unique_id) + @jit.oopspec("rvmprof.leave_code(s)") + def leave_code(s, unique_id): + leave_code_untr(s, unique_id) else: enter_code = cintf.enter_code leave_code = cintf.leave_code @@ -179,17 +186,12 @@ return func def decorated_function(*args): - # If we are being JITted, we want to skip the trampoline, else the - # JIT cannot see through it. - if not jit.we_are_jitted(): - unique_id = get_code_fn(*args)._vmprof_unique_id - x = enter_code(unique_id) - try: - return func(*args) - finally: - leave_code(x) - else: + unique_id = get_code_fn(*args)._vmprof_unique_id + x = enter_code(unique_id) + try: return func(*args) + finally: + leave_code(x, unique_id) decorated_function.__name__ = func.__name__ + '_rvmprof' return decorated_function _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit