@@ -72,6 +72,11 @@ struct ectx_S {
7272 garray_T ec_funcrefs ; // partials that might be a closure
7373};
7474
75+ #ifdef FEAT_PROFILE
76+ // stack of profinfo_T used when profiling.
77+ static garray_T profile_info_ga = {0 , 0 , sizeof (profinfo_T ), 20 , NULL };
78+ #endif
79+
7580// Get pointer to item relative to the bottom of the stack, -1 is the last one.
7681#define STACK_TV_BOT (idx ) (((typval_T *)ectx->ec_stack.ga_data) + ectx->ec_stack.ga_len + (idx))
7782
@@ -184,13 +189,27 @@ call_dfunc(int cdf_idx, partial_T *pt, int argcount_arg, ectx_T *ectx)
184189 }
185190
186191#ifdef FEAT_PROFILE
187- // Profiling might be enabled/disabled along the way. This should not
188- // fail, since the function was compiled before and toggling profiling
189- // doesn't change any errors.
190- if (func_needs_compiling (ufunc , PROFILING (ufunc ))
191- && compile_def_function (ufunc , FALSE, PROFILING (ufunc ), NULL )
192+ if (do_profiling == PROF_YES )
193+ {
194+ if (ga_grow (& profile_info_ga , 1 ) == OK )
195+ {
196+ profinfo_T * info = ((profinfo_T * )profile_info_ga .ga_data )
197+ + profile_info_ga .ga_len ;
198+ ++ profile_info_ga .ga_len ;
199+ CLEAR_POINTER (info );
200+ profile_may_start_func (info , ufunc ,
201+ (((dfunc_T * )def_functions .ga_data )
202+ + ectx -> ec_dfunc_idx )-> df_ufunc );
203+ }
204+
205+ // Profiling might be enabled/disabled along the way. This should not
206+ // fail, since the function was compiled before and toggling profiling
207+ // doesn't change any errors.
208+ if (func_needs_compiling (ufunc , PROFILING (ufunc ))
209+ && compile_def_function (ufunc , FALSE, PROFILING (ufunc ), NULL )
192210 == FAIL )
193- return FAIL ;
211+ return FAIL ;
212+ }
194213#endif
195214
196215 if (ufunc -> uf_va_name != NULL )
@@ -517,7 +536,25 @@ func_return(ectx_T *ectx)
517536 int argcount = ufunc_argcount (dfunc -> df_ufunc );
518537 int top = ectx -> ec_frame_idx - argcount ;
519538 estack_T * entry ;
539+ int prev_dfunc_idx = STACK_TV (ectx -> ec_frame_idx
540+ + STACK_FRAME_FUNC_OFF )-> vval .v_number ;
541+ dfunc_T * prev_dfunc = ((dfunc_T * )def_functions .ga_data )
542+ + prev_dfunc_idx ;
520543
544+ #ifdef FEAT_PROFILE
545+ if (do_profiling == PROF_YES )
546+ {
547+ ufunc_T * caller = prev_dfunc -> df_ufunc ;
548+
549+ if (dfunc -> df_ufunc -> uf_profiling
550+ || (caller != NULL && caller -> uf_profiling ))
551+ {
552+ profile_may_end_func (((profinfo_T * )profile_info_ga .ga_data )
553+ + profile_info_ga .ga_len - 1 , dfunc -> df_ufunc , caller );
554+ -- profile_info_ga .ga_len ;
555+ }
556+ }
557+ #endif
521558 // execution context goes one level up
522559 entry = estack_pop ();
523560 if (entry != NULL )
@@ -544,17 +581,15 @@ func_return(ectx_T *ectx)
544581 vim_free (ectx -> ec_outer );
545582
546583 // Restore the previous frame.
547- ectx -> ec_dfunc_idx = STACK_TV (ectx -> ec_frame_idx
548- + STACK_FRAME_FUNC_OFF )-> vval .v_number ;
584+ ectx -> ec_dfunc_idx = prev_dfunc_idx ;
549585 ectx -> ec_iidx = STACK_TV (ectx -> ec_frame_idx
550586 + STACK_FRAME_IIDX_OFF )-> vval .v_number ;
551587 ectx -> ec_outer = (void * )STACK_TV (ectx -> ec_frame_idx
552588 + STACK_FRAME_OUTER_OFF )-> vval .v_string ;
553589 // restoring ec_frame_idx must be last
554590 ectx -> ec_frame_idx = STACK_TV (ectx -> ec_frame_idx
555591 + STACK_FRAME_IDX_OFF )-> vval .v_number ;
556- dfunc = ((dfunc_T * )def_functions .ga_data ) + ectx -> ec_dfunc_idx ;
557- ectx -> ec_instr = INSTRUCTIONS (dfunc );
592+ ectx -> ec_instr = INSTRUCTIONS (prev_dfunc );
558593
559594 if (ret_idx > 0 )
560595 {
0 commit comments