Skip to content

Commit e5ea346

Browse files
committed
patch 8.2.2409: Vim9: profiling only works for one function
Problem: Vim9: profiling only works for one function. Solution: Select the right instructions when calling and returning. (closes #7743)
1 parent 5c829bf commit e5ea346

5 files changed

Lines changed: 54 additions & 26 deletions

File tree

src/testdir/test_profile.vim

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ CheckFeature profile
55

66
source shared.vim
77
source screendump.vim
8+
source vim9.vim
89

910
func Test_profile_func()
1011
call RunProfileFunc('func', 'let', 'let')
@@ -583,4 +584,21 @@ func Test_profile_typed_func()
583584
call delete('XtestProfile')
584585
endfunc
585586

587+
func Test_vim9_profiling()
588+
" only tests that compiling and calling functions doesn't crash
589+
let lines =<< trim END
590+
vim9script
591+
def Func()
592+
Crash()
593+
enddef
594+
def Crash()
595+
enddef
596+
prof start /tmp/profile.log
597+
prof func Func
598+
Func()
599+
END
600+
call CheckScriptSuccess(lines)
601+
endfunc
602+
603+
586604
" vim: shiftwidth=2 sts=2 expandtab

src/version.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -750,6 +750,8 @@ static char *(features[]) =
750750

751751
static int included_patches[] =
752752
{ /* Add new patch number below this line */
753+
/**/
754+
2409,
753755
/**/
754756
2408,
755757
/**/

src/vim9.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -408,3 +408,13 @@ extern garray_T def_functions;
408408

409409
// Used for "lnum" when a range is to be taken from the stack and "!" is used.
410410
#define LNUM_VARIABLE_RANGE_ABOVE -888
411+
412+
#ifdef FEAT_PROFILE
413+
# define PROFILING(ufunc) (do_profiling == PROF_YES && (ufunc)->uf_profiling)
414+
# define INSTRUCTIONS(dfunc) \
415+
((do_profiling == PROF_YES && (dfunc->df_ufunc)->uf_profiling) \
416+
? (dfunc)->df_instr_prof : (dfunc)->df_instr)
417+
#else
418+
# define PROFILING FALSE
419+
# define INSTRUCTIONS(dfunc) ((dfunc)->df_instr)
420+
#endif

src/vim9compile.c

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1775,9 +1775,9 @@ generate_CALL(cctx_T *cctx, ufunc_T *ufunc, int pushed_argcount)
17751775
return FAIL;
17761776
}
17771777
}
1778-
if (func_needs_compiling(ufunc, cctx->ctx_profiling)
1778+
if (func_needs_compiling(ufunc, PROFILING(ufunc))
17791779
&& compile_def_function(ufunc, ufunc->uf_ret_type == NULL,
1780-
cctx->ctx_profiling, NULL) == FAIL)
1780+
PROFILING(ufunc), NULL) == FAIL)
17811781
return FAIL;
17821782
}
17831783

@@ -2615,8 +2615,8 @@ generate_funcref(cctx_T *cctx, char_u *name)
26152615
return FAIL;
26162616

26172617
// Need to compile any default values to get the argument types.
2618-
if (func_needs_compiling(ufunc, cctx->ctx_profiling)
2619-
&& compile_def_function(ufunc, TRUE, cctx->ctx_profiling, NULL)
2618+
if (func_needs_compiling(ufunc, PROFILING(ufunc))
2619+
&& compile_def_function(ufunc, TRUE, PROFILING(ufunc), NULL)
26202620
== FAIL)
26212621
return FAIL;
26222622
return generate_PUSHFUNC(cctx, ufunc->uf_name, ufunc->uf_func_type);
@@ -3111,7 +3111,7 @@ compile_lambda(char_u **arg, cctx_T *cctx)
31113111
clear_tv(&rettv);
31123112

31133113
// Compile the function into instructions.
3114-
compile_def_function(ufunc, TRUE, cctx->ctx_profiling, cctx);
3114+
compile_def_function(ufunc, TRUE, PROFILING(ufunc), cctx);
31153115

31163116
clear_evalarg(&evalarg, NULL);
31173117

@@ -5088,8 +5088,8 @@ compile_nested_function(exarg_T *eap, cctx_T *cctx)
50885088
r = eap->skip ? OK : FAIL;
50895089
goto theend;
50905090
}
5091-
if (func_needs_compiling(ufunc, cctx->ctx_profiling)
5092-
&& compile_def_function(ufunc, TRUE, cctx->ctx_profiling, cctx)
5091+
if (func_needs_compiling(ufunc, PROFILING(ufunc))
5092+
&& compile_def_function(ufunc, TRUE, PROFILING(ufunc), cctx)
50935093
== FAIL)
50945094
{
50955095
func_ptr_unref(ufunc);

src/vim9execute.c

Lines changed: 17 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,16 @@ call_dfunc(int cdf_idx, partial_T *pt, int argcount_arg, ectx_T *ectx)
181181
return FAIL;
182182
}
183183

184+
#ifdef FEAT_PROFILE
185+
// Profiling might be enabled/disabled along the way. This should not
186+
// fail, since the function was compiled before and toggling profiling
187+
// doesn't change any errors.
188+
if (func_needs_compiling(ufunc, PROFILING(ufunc))
189+
&& compile_def_function(ufunc, FALSE, PROFILING(ufunc), NULL)
190+
== FAIL)
191+
return FAIL;
192+
#endif
193+
184194
if (ufunc->uf_va_name != NULL)
185195
{
186196
// Need to make a list out of the vararg arguments.
@@ -293,7 +303,7 @@ call_dfunc(int cdf_idx, partial_T *pt, int argcount_arg, ectx_T *ectx)
293303

294304
// Set execution state to the start of the called function.
295305
ectx->ec_dfunc_idx = cdf_idx;
296-
ectx->ec_instr = dfunc->df_instr;
306+
ectx->ec_instr = INSTRUCTIONS(dfunc);
297307
entry = estack_push_ufunc(ufunc, 1);
298308
if (entry != NULL)
299309
{
@@ -542,7 +552,7 @@ func_return(ectx_T *ectx)
542552
ectx->ec_frame_idx = STACK_TV(ectx->ec_frame_idx
543553
+ STACK_FRAME_IDX_OFF)->vval.v_number;
544554
dfunc = ((dfunc_T *)def_functions.ga_data) + ectx->ec_dfunc_idx;
545-
ectx->ec_instr = dfunc->df_instr;
555+
ectx->ec_instr = INSTRUCTIONS(dfunc);
546556

547557
if (ret_idx > 0)
548558
{
@@ -1103,6 +1113,7 @@ fill_partial_and_closure(partial_T *pt, ufunc_T *ufunc, ectx_T *ectx)
11031113
return OK;
11041114
}
11051115

1116+
11061117
/*
11071118
* Call a "def" function from old Vim script.
11081119
* Return OK or FAIL.
@@ -1135,11 +1146,6 @@ call_def_function(
11351146
int save_did_emsg_def = did_emsg_def;
11361147
int trylevel_at_start = trylevel;
11371148
int orig_funcdepth;
1138-
#ifdef FEAT_PROFILE
1139-
int profiling = do_profiling == PROF_YES && ufunc->uf_profiling;
1140-
#else
1141-
# define profiling FALSE
1142-
#endif
11431149

11441150
// Get pointer to item in the stack.
11451151
#define STACK_TV(idx) (((typval_T *)ectx.ec_stack.ga_data) + idx)
@@ -1152,8 +1158,8 @@ call_def_function(
11521158
#define STACK_TV_VAR(idx) (((typval_T *)ectx.ec_stack.ga_data) + ectx.ec_frame_idx + STACK_FRAME_SIZE + idx)
11531159

11541160
if (ufunc->uf_def_status == UF_NOT_COMPILED
1155-
|| (func_needs_compiling(ufunc, profiling)
1156-
&& compile_def_function(ufunc, FALSE, profiling, NULL)
1161+
|| (func_needs_compiling(ufunc, PROFILING(ufunc))
1162+
&& compile_def_function(ufunc, FALSE, PROFILING(ufunc), NULL)
11571163
== FAIL))
11581164
{
11591165
if (did_emsg_cumul + did_emsg == did_emsg_before)
@@ -1166,11 +1172,7 @@ call_def_function(
11661172
// Check the function was really compiled.
11671173
dfunc_T *dfunc = ((dfunc_T *)def_functions.ga_data)
11681174
+ ufunc->uf_dfunc_idx;
1169-
if ((
1170-
#ifdef FEAT_PROFILE
1171-
profiling ? dfunc->df_instr_prof :
1172-
#endif
1173-
dfunc->df_instr) == NULL)
1175+
if (INSTRUCTIONS(dfunc) == NULL)
11741176
{
11751177
iemsg("using call_def_function() on not compiled function");
11761178
return FAIL;
@@ -1309,11 +1311,7 @@ call_def_function(
13091311
++ectx.ec_stack.ga_len;
13101312
}
13111313

1312-
#ifdef FEAT_PROFILE
1313-
ectx.ec_instr = profiling ? dfunc->df_instr_prof : dfunc->df_instr;
1314-
#else
1315-
ectx.ec_instr = dfunc->df_instr;
1316-
#endif
1314+
ectx.ec_instr = INSTRUCTIONS(dfunc);
13171315
}
13181316

13191317
// Following errors are in the function, not the caller.

0 commit comments

Comments
 (0)