Mercurial > vim
diff src/vim9execute.c @ 23717:e3720756acdc v8.2.2400
patch 8.2.2400: Vim9: compiled functions are not profiled
Commit: https://github.com/vim/vim/commit/b204990346ca857802b174afe8a7fbb05e4f318e
Author: Bram Moolenaar <Bram@vim.org>
Date: Sun Jan 24 12:53:53 2021 +0100
patch 8.2.2400: Vim9: compiled functions are not profiled
Problem: Vim9: compiled functions are not profiled.
Solution: Add initial changes to profile compiled functions. Fix that a
script-local function was hard to debug.
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Sun, 24 Jan 2021 13:00:06 +0100 |
parents | 317018f62643 |
children | 1a7c2685d780 |
line wrap: on
line diff
--- a/src/vim9execute.c +++ b/src/vim9execute.c @@ -294,7 +294,7 @@ call_dfunc(int cdf_idx, partial_T *pt, i // Set execution state to the start of the called function. ectx->ec_dfunc_idx = cdf_idx; ectx->ec_instr = dfunc->df_instr; - entry = estack_push_ufunc(dfunc->df_ufunc, 1); + entry = estack_push_ufunc(ufunc, 1); if (entry != NULL) { // Set the script context to the script where the function was defined. @@ -645,9 +645,10 @@ call_ufunc( int error; int idx; int did_emsg_before = did_emsg; - - if (ufunc->uf_def_status == UF_TO_BE_COMPILED - && compile_def_function(ufunc, FALSE, NULL) == FAIL) + int profiling = do_profiling == PROF_YES && ufunc->uf_profiling; + + if (func_needs_compiling(ufunc, profiling) + && compile_def_function(ufunc, FALSE, profiling, NULL) == FAIL) return FAIL; if (ufunc->uf_def_status == UF_COMPILED) { @@ -1130,6 +1131,7 @@ call_def_function( int save_did_emsg_def = did_emsg_def; int trylevel_at_start = trylevel; int orig_funcdepth; + int profiling = do_profiling == PROF_YES && ufunc->uf_profiling; // Get pointer to item in the stack. #define STACK_TV(idx) (((typval_T *)ectx.ec_stack.ga_data) + idx) @@ -1142,8 +1144,9 @@ call_def_function( #define STACK_TV_VAR(idx) (((typval_T *)ectx.ec_stack.ga_data) + ectx.ec_frame_idx + STACK_FRAME_SIZE + idx) if (ufunc->uf_def_status == UF_NOT_COMPILED - || (ufunc->uf_def_status == UF_TO_BE_COMPILED - && compile_def_function(ufunc, FALSE, NULL) == FAIL)) + || (func_needs_compiling(ufunc, profiling) + && compile_def_function(ufunc, FALSE, profiling, NULL) + == FAIL)) { if (did_emsg_cumul + did_emsg == did_emsg_before) semsg(_(e_function_is_not_compiled_str), @@ -1155,7 +1158,7 @@ call_def_function( // Check the function was really compiled. dfunc_T *dfunc = ((dfunc_T *)def_functions.ga_data) + ufunc->uf_dfunc_idx; - if (dfunc->df_instr == NULL) + if ((profiling ? dfunc->df_instr_prof : dfunc->df_instr) == NULL) { iemsg("using call_def_function() on not compiled function"); return FAIL; @@ -1294,7 +1297,7 @@ call_def_function( ++ectx.ec_stack.ga_len; } - ectx.ec_instr = dfunc->df_instr; + ectx.ec_instr = profiling ? dfunc->df_instr_prof : dfunc->df_instr; } // Following errors are in the function, not the caller. @@ -3495,6 +3498,26 @@ call_def_function( } break; + case ISN_PROF_START: + case ISN_PROF_END: + { + funccall_T cookie; + ufunc_T *cur_ufunc = + (((dfunc_T *)def_functions.ga_data) + + ectx.ec_dfunc_idx)->df_ufunc; + + cookie.func = cur_ufunc; + if (iptr->isn_type == ISN_PROF_START) + { + func_line_start(&cookie, iptr->isn_lnum); + // if we get here the instruction is executed + func_line_exec(&cookie); + } + else + func_line_end(&cookie); + } + break; + case ISN_SHUFFLE: { typval_T tmp_tv; @@ -3642,6 +3665,7 @@ ex_disassemble(exarg_T *eap) ufunc_T *ufunc; dfunc_T *dfunc; isn_T *instr; + int instr_count; int current; int line_idx = 0; int prev_current = 0; @@ -3677,8 +3701,8 @@ ex_disassemble(exarg_T *eap) semsg(_(e_cannot_find_function_str), eap->arg); return; } - if (ufunc->uf_def_status == UF_TO_BE_COMPILED - && compile_def_function(ufunc, FALSE, NULL) == FAIL) + if (func_needs_compiling(ufunc, eap->forceit) + && compile_def_function(ufunc, FALSE, eap->forceit, NULL) == FAIL) return; if (ufunc->uf_def_status != UF_COMPILED) { @@ -3691,8 +3715,10 @@ ex_disassemble(exarg_T *eap) msg((char *)ufunc->uf_name); dfunc = ((dfunc_T *)def_functions.ga_data) + ufunc->uf_dfunc_idx; - instr = dfunc->df_instr; - for (current = 0; current < dfunc->df_instr_count; ++current) + instr = eap->forceit ? dfunc->df_instr_prof : dfunc->df_instr; + instr_count = eap->forceit ? dfunc->df_instr_prof_count + : dfunc->df_instr_count; + for (current = 0; current < instr_count; ++current) { isn_T *iptr = &instr[current]; char *line; @@ -4319,6 +4345,14 @@ ex_disassemble(exarg_T *eap) } case ISN_CMDMOD_REV: smsg("%4d CMDMOD_REV", current); break; + case ISN_PROF_START: + smsg("%4d PROFILE START line %d", current, iptr->isn_lnum); + break; + + case ISN_PROF_END: + smsg("%4d PROFILE END", current); + break; + case ISN_UNPACK: smsg("%4d UNPACK %d%s", current, iptr->isn_arg.unpack.unp_count, iptr->isn_arg.unpack.unp_semicolon ? " semicolon" : "");