Mercurial > vim
comparison src/vim9execute.c @ 23735:7caffd835aa1 v8.2.2409
patch 8.2.2409: Vim9: profiling only works for one function
Commit: https://github.com/vim/vim/commit/e5ea346a07a7750c02a89996b67716b43c767d06
Author: Bram Moolenaar <Bram@vim.org>
Date: Mon Jan 25 21:01:48 2021 +0100
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)
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Mon, 25 Jan 2021 21:15:06 +0100 |
parents | f98692ae09a0 |
children | d12ef361d9de |
comparison
equal
deleted
inserted
replaced
23734:f4946b73ba39 | 23735:7caffd835aa1 |
---|---|
179 emsg_funcname(e_func_deleted, | 179 emsg_funcname(e_func_deleted, |
180 dfunc->df_name == NULL ? (char_u *)"unknown" : dfunc->df_name); | 180 dfunc->df_name == NULL ? (char_u *)"unknown" : dfunc->df_name); |
181 return FAIL; | 181 return FAIL; |
182 } | 182 } |
183 | 183 |
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 | |
184 if (ufunc->uf_va_name != NULL) | 194 if (ufunc->uf_va_name != NULL) |
185 { | 195 { |
186 // Need to make a list out of the vararg arguments. | 196 // Need to make a list out of the vararg arguments. |
187 // Stack at time of call with 2 varargs: | 197 // Stack at time of call with 2 varargs: |
188 // normal_arg | 198 // normal_arg |
291 else | 301 else |
292 ectx->ec_outer = NULL; | 302 ectx->ec_outer = NULL; |
293 | 303 |
294 // Set execution state to the start of the called function. | 304 // Set execution state to the start of the called function. |
295 ectx->ec_dfunc_idx = cdf_idx; | 305 ectx->ec_dfunc_idx = cdf_idx; |
296 ectx->ec_instr = dfunc->df_instr; | 306 ectx->ec_instr = INSTRUCTIONS(dfunc); |
297 entry = estack_push_ufunc(ufunc, 1); | 307 entry = estack_push_ufunc(ufunc, 1); |
298 if (entry != NULL) | 308 if (entry != NULL) |
299 { | 309 { |
300 // Set the script context to the script where the function was defined. | 310 // Set the script context to the script where the function was defined. |
301 // TODO: save more than the SID? | 311 // TODO: save more than the SID? |
540 + STACK_FRAME_OUTER_OFF)->vval.v_string; | 550 + STACK_FRAME_OUTER_OFF)->vval.v_string; |
541 // restoring ec_frame_idx must be last | 551 // restoring ec_frame_idx must be last |
542 ectx->ec_frame_idx = STACK_TV(ectx->ec_frame_idx | 552 ectx->ec_frame_idx = STACK_TV(ectx->ec_frame_idx |
543 + STACK_FRAME_IDX_OFF)->vval.v_number; | 553 + STACK_FRAME_IDX_OFF)->vval.v_number; |
544 dfunc = ((dfunc_T *)def_functions.ga_data) + ectx->ec_dfunc_idx; | 554 dfunc = ((dfunc_T *)def_functions.ga_data) + ectx->ec_dfunc_idx; |
545 ectx->ec_instr = dfunc->df_instr; | 555 ectx->ec_instr = INSTRUCTIONS(dfunc); |
546 | 556 |
547 if (ret_idx > 0) | 557 if (ret_idx > 0) |
548 { | 558 { |
549 // Reset the stack to the position before the call, with a spot for the | 559 // Reset the stack to the position before the call, with a spot for the |
550 // return value, moved there from above the frame. | 560 // return value, moved there from above the frame. |
1100 ++ectx->ec_funcrefs.ga_len; | 1110 ++ectx->ec_funcrefs.ga_len; |
1101 } | 1111 } |
1102 ++ufunc->uf_refcount; | 1112 ++ufunc->uf_refcount; |
1103 return OK; | 1113 return OK; |
1104 } | 1114 } |
1115 | |
1105 | 1116 |
1106 /* | 1117 /* |
1107 * Call a "def" function from old Vim script. | 1118 * Call a "def" function from old Vim script. |
1108 * Return OK or FAIL. | 1119 * Return OK or FAIL. |
1109 */ | 1120 */ |
1133 int restore_cmdmod_stacklen = 0; | 1144 int restore_cmdmod_stacklen = 0; |
1134 int save_emsg_silent_def = emsg_silent_def; | 1145 int save_emsg_silent_def = emsg_silent_def; |
1135 int save_did_emsg_def = did_emsg_def; | 1146 int save_did_emsg_def = did_emsg_def; |
1136 int trylevel_at_start = trylevel; | 1147 int trylevel_at_start = trylevel; |
1137 int orig_funcdepth; | 1148 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 | |
1143 | 1149 |
1144 // Get pointer to item in the stack. | 1150 // Get pointer to item in the stack. |
1145 #define STACK_TV(idx) (((typval_T *)ectx.ec_stack.ga_data) + idx) | 1151 #define STACK_TV(idx) (((typval_T *)ectx.ec_stack.ga_data) + idx) |
1146 | 1152 |
1147 // Get pointer to item at the bottom of the stack, -1 is the bottom. | 1153 // Get pointer to item at the bottom of the stack, -1 is the bottom. |
1150 | 1156 |
1151 // Get pointer to a local variable on the stack. Negative for arguments. | 1157 // Get pointer to a local variable on the stack. Negative for arguments. |
1152 #define STACK_TV_VAR(idx) (((typval_T *)ectx.ec_stack.ga_data) + ectx.ec_frame_idx + STACK_FRAME_SIZE + idx) | 1158 #define STACK_TV_VAR(idx) (((typval_T *)ectx.ec_stack.ga_data) + ectx.ec_frame_idx + STACK_FRAME_SIZE + idx) |
1153 | 1159 |
1154 if (ufunc->uf_def_status == UF_NOT_COMPILED | 1160 if (ufunc->uf_def_status == UF_NOT_COMPILED |
1155 || (func_needs_compiling(ufunc, profiling) | 1161 || (func_needs_compiling(ufunc, PROFILING(ufunc)) |
1156 && compile_def_function(ufunc, FALSE, profiling, NULL) | 1162 && compile_def_function(ufunc, FALSE, PROFILING(ufunc), NULL) |
1157 == FAIL)) | 1163 == FAIL)) |
1158 { | 1164 { |
1159 if (did_emsg_cumul + did_emsg == did_emsg_before) | 1165 if (did_emsg_cumul + did_emsg == did_emsg_before) |
1160 semsg(_(e_function_is_not_compiled_str), | 1166 semsg(_(e_function_is_not_compiled_str), |
1161 printable_func_name(ufunc)); | 1167 printable_func_name(ufunc)); |
1164 | 1170 |
1165 { | 1171 { |
1166 // Check the function was really compiled. | 1172 // Check the function was really compiled. |
1167 dfunc_T *dfunc = ((dfunc_T *)def_functions.ga_data) | 1173 dfunc_T *dfunc = ((dfunc_T *)def_functions.ga_data) |
1168 + ufunc->uf_dfunc_idx; | 1174 + ufunc->uf_dfunc_idx; |
1169 if (( | 1175 if (INSTRUCTIONS(dfunc) == NULL) |
1170 #ifdef FEAT_PROFILE | |
1171 profiling ? dfunc->df_instr_prof : | |
1172 #endif | |
1173 dfunc->df_instr) == NULL) | |
1174 { | 1176 { |
1175 iemsg("using call_def_function() on not compiled function"); | 1177 iemsg("using call_def_function() on not compiled function"); |
1176 return FAIL; | 1178 return FAIL; |
1177 } | 1179 } |
1178 } | 1180 } |
1307 STACK_TV_VAR(idx)->v_type = VAR_NUMBER; | 1309 STACK_TV_VAR(idx)->v_type = VAR_NUMBER; |
1308 STACK_TV_VAR(idx)->vval.v_number = 0; | 1310 STACK_TV_VAR(idx)->vval.v_number = 0; |
1309 ++ectx.ec_stack.ga_len; | 1311 ++ectx.ec_stack.ga_len; |
1310 } | 1312 } |
1311 | 1313 |
1312 #ifdef FEAT_PROFILE | 1314 ectx.ec_instr = INSTRUCTIONS(dfunc); |
1313 ectx.ec_instr = profiling ? dfunc->df_instr_prof : dfunc->df_instr; | |
1314 #else | |
1315 ectx.ec_instr = dfunc->df_instr; | |
1316 #endif | |
1317 } | 1315 } |
1318 | 1316 |
1319 // Following errors are in the function, not the caller. | 1317 // Following errors are in the function, not the caller. |
1320 // Commands behave like vim9script. | 1318 // Commands behave like vim9script. |
1321 estack_push_ufunc(ufunc, 1); | 1319 estack_push_ufunc(ufunc, 1); |