Skip to content

Commit 21b9e97

Browse files
committed
patch 8.2.0154: reallocating the list of scripts is inefficient
Problem: Reallocating the list of scripts is inefficient. Solution: Instead of using a growarray of scriptitem_T, store pointers and allocate each scriptitem_T separately. Also avoids that the growarray pointers change when sourcing a new script.
1 parent b3de511 commit 21b9e97

10 files changed

Lines changed: 53 additions & 45 deletions

File tree

src/eval.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -692,7 +692,7 @@ get_lval(
692692

693693
if (current_sctx.sc_version == SCRIPT_VERSION_VIM9 && *p == ':')
694694
{
695-
scriptitem_T *si = &SCRIPT_ITEM(current_sctx.sc_sid);
695+
scriptitem_T *si = SCRIPT_ITEM(current_sctx.sc_sid);
696696
char_u *tp = skipwhite(p + 1);
697697

698698
// parse the type after the name

src/evalvars.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2289,7 +2289,7 @@ get_var_tv(
22892289
// imported variable from another script
22902290
if (import != NULL)
22912291
{
2292-
scriptitem_T *si = &SCRIPT_ITEM(import->imp_sid);
2292+
scriptitem_T *si = SCRIPT_ITEM(import->imp_sid);
22932293
svar_T *sv = ((svar_T *)si->sn_var_vals.ga_data)
22942294
+ import->imp_var_vals_idx;
22952295
tv = sv->sv_tv;
@@ -2571,7 +2571,7 @@ new_script_vars(scid_T id)
25712571
if (sv == NULL)
25722572
return;
25732573
init_var_dict(&sv->sv_dict, &sv->sv_var, VAR_SCOPE);
2574-
SCRIPT_ITEM(id).sn_vars = sv;
2574+
SCRIPT_ITEM(id)->sn_vars = sv;
25752575
}
25762576

25772577
/*
@@ -2876,7 +2876,7 @@ set_var_const(
28762876

28772877
if (is_script_local && current_sctx.sc_version == SCRIPT_VERSION_VIM9)
28782878
{
2879-
scriptitem_T *si = &SCRIPT_ITEM(current_sctx.sc_sid);
2879+
scriptitem_T *si = SCRIPT_ITEM(current_sctx.sc_sid);
28802880

28812881
// Store a pointer to the typval_T, so that it can be found by
28822882
// index instead of using a hastab lookup.

src/ex_docmd.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2496,7 +2496,7 @@ do_one_cmd(
24962496
#ifdef FEAT_EVAL
24972497
// Set flag that any command was executed, used by ex_vim9script().
24982498
if (getline_equal(ea.getline, ea.cookie, getsourceline))
2499-
SCRIPT_ITEM(current_sctx.sc_sid).sn_had_command = TRUE;
2499+
SCRIPT_ITEM(current_sctx.sc_sid)->sn_had_command = TRUE;
25002500

25012501
/*
25022502
* If the command just executed called do_cmdline(), any throw or ":return"

src/globals.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -285,9 +285,9 @@ EXTERN int debug_backtrace_level INIT(= 0); // breakpoint backtrace level
285285
# ifdef FEAT_PROFILE
286286
EXTERN int do_profiling INIT(= PROF_NONE); // PROF_ values
287287
# endif
288-
EXTERN garray_T script_items INIT5(0, 0, sizeof(scriptitem_T), 4, NULL);
289-
# define SCRIPT_ITEM(id) (((scriptitem_T *)script_items.ga_data)[(id) - 1])
290-
# define SCRIPT_SV(id) (SCRIPT_ITEM(id).sn_vars)
288+
EXTERN garray_T script_items INIT5(0, 0, sizeof(scriptitem_T *), 20, NULL);
289+
# define SCRIPT_ITEM(id) (((scriptitem_T **)script_items.ga_data)[(id) - 1])
290+
# define SCRIPT_SV(id) (SCRIPT_ITEM(id)->sn_vars)
291291
# define SCRIPT_VARS(id) (SCRIPT_SV(id)->sv_dict.dv_hashtab)
292292

293293
# define FUNCLINE(fp, j) ((char_u **)(fp->uf_lines.ga_data))[j]

src/profiler.c

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -440,7 +440,7 @@ prof_inchar_exit(void)
440440
prof_def_func(void)
441441
{
442442
if (current_sctx.sc_sid > 0)
443-
return SCRIPT_ITEM(current_sctx.sc_sid).sn_pr_force;
443+
return SCRIPT_ITEM(current_sctx.sc_sid)->sn_pr_force;
444444
return FALSE;
445445
}
446446

@@ -763,7 +763,7 @@ script_prof_save(
763763

764764
if (current_sctx.sc_sid > 0 && current_sctx.sc_sid <= script_items.ga_len)
765765
{
766-
si = &SCRIPT_ITEM(current_sctx.sc_sid);
766+
si = SCRIPT_ITEM(current_sctx.sc_sid);
767767
if (si->sn_prof_on && si->sn_pr_nest++ == 0)
768768
profile_start(&si->sn_pr_child);
769769
}
@@ -780,7 +780,7 @@ script_prof_restore(proftime_T *tm)
780780

781781
if (current_sctx.sc_sid > 0 && current_sctx.sc_sid <= script_items.ga_len)
782782
{
783-
si = &SCRIPT_ITEM(current_sctx.sc_sid);
783+
si = SCRIPT_ITEM(current_sctx.sc_sid);
784784
if (si->sn_prof_on && --si->sn_pr_nest == 0)
785785
{
786786
profile_end(&si->sn_pr_child);
@@ -805,7 +805,7 @@ script_dump_profile(FILE *fd)
805805

806806
for (id = 1; id <= script_items.ga_len; ++id)
807807
{
808-
si = &SCRIPT_ITEM(id);
808+
si = SCRIPT_ITEM(id);
809809
if (si->sn_prof_on)
810810
{
811811
fprintf(fd, "SCRIPT %s\n", si->sn_name);
@@ -905,7 +905,7 @@ script_line_start(void)
905905

906906
if (current_sctx.sc_sid <= 0 || current_sctx.sc_sid > script_items.ga_len)
907907
return;
908-
si = &SCRIPT_ITEM(current_sctx.sc_sid);
908+
si = SCRIPT_ITEM(current_sctx.sc_sid);
909909
if (si->sn_prof_on && SOURCING_LNUM >= 1)
910910
{
911911
// Grow the array before starting the timer, so that the time spent
@@ -940,7 +940,7 @@ script_line_exec(void)
940940

941941
if (current_sctx.sc_sid <= 0 || current_sctx.sc_sid > script_items.ga_len)
942942
return;
943-
si = &SCRIPT_ITEM(current_sctx.sc_sid);
943+
si = SCRIPT_ITEM(current_sctx.sc_sid);
944944
if (si->sn_prof_on && si->sn_prl_idx >= 0)
945945
si->sn_prl_execed = TRUE;
946946
}
@@ -956,7 +956,7 @@ script_line_end(void)
956956

957957
if (current_sctx.sc_sid <= 0 || current_sctx.sc_sid > script_items.ga_len)
958958
return;
959-
si = &SCRIPT_ITEM(current_sctx.sc_sid);
959+
si = SCRIPT_ITEM(current_sctx.sc_sid);
960960
if (si->sn_prof_on && si->sn_prl_idx >= 0
961961
&& si->sn_prl_idx < si->sn_prl_ga.ga_len)
962962
{

src/scriptfile.c

Lines changed: 22 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1124,7 +1124,7 @@ do_source(
11241124
// inode number, even though to the user it is the same script.
11251125
// - If a script is deleted and another script is written, with a
11261126
// different name, the inode may be re-used.
1127-
si = &SCRIPT_ITEM(sid);
1127+
si = SCRIPT_ITEM(sid);
11281128
if (si->sn_name != NULL && fnamecmp(si->sn_name, fname_exp) == 0)
11291129
// Found it!
11301130
break;
@@ -1294,8 +1294,11 @@ do_source(
12941294
goto almosttheend;
12951295
while (script_items.ga_len < current_sctx.sc_sid)
12961296
{
1297+
si = ALLOC_CLEAR_ONE(scriptitem_T);
1298+
if (si == NULL)
1299+
goto almosttheend;
12971300
++script_items.ga_len;
1298-
si = &SCRIPT_ITEM(script_items.ga_len);
1301+
SCRIPT_ITEM(script_items.ga_len) = si;
12991302
si->sn_name = NULL;
13001303
si->sn_version = 1;
13011304

@@ -1308,7 +1311,7 @@ do_source(
13081311
si->sn_prof_on = FALSE;
13091312
# endif
13101313
}
1311-
si = &SCRIPT_ITEM(current_sctx.sc_sid);
1314+
si = SCRIPT_ITEM(current_sctx.sc_sid);
13121315
si->sn_name = fname_exp;
13131316
fname_exp = vim_strsave(si->sn_name); // used for autocmd
13141317
if (ret_sid != NULL)
@@ -1364,7 +1367,7 @@ do_source(
13641367
if (do_profiling == PROF_YES)
13651368
{
13661369
// Get "si" again, "script_items" may have been reallocated.
1367-
si = &SCRIPT_ITEM(current_sctx.sc_sid);
1370+
si = SCRIPT_ITEM(current_sctx.sc_sid);
13681371
if (si->sn_prof_on)
13691372
{
13701373
profile_end(&si->sn_pr_start);
@@ -1411,7 +1414,7 @@ do_source(
14111414
#ifdef FEAT_EVAL
14121415
almosttheend:
14131416
// Get "si" again, "script_items" may have been reallocated.
1414-
si = &SCRIPT_ITEM(current_sctx.sc_sid);
1417+
si = SCRIPT_ITEM(current_sctx.sc_sid);
14151418
if (si->sn_save_cpo != NULL)
14161419
{
14171420
free_string_option(p_cpo);
@@ -1456,16 +1459,16 @@ ex_scriptnames(exarg_T *eap)
14561459
emsg(_(e_invarg));
14571460
else
14581461
{
1459-
eap->arg = SCRIPT_ITEM(eap->line2).sn_name;
1462+
eap->arg = SCRIPT_ITEM(eap->line2)->sn_name;
14601463
do_exedit(eap, NULL);
14611464
}
14621465
return;
14631466
}
14641467

14651468
for (i = 1; i <= script_items.ga_len && !got_int; ++i)
1466-
if (SCRIPT_ITEM(i).sn_name != NULL)
1469+
if (SCRIPT_ITEM(i)->sn_name != NULL)
14671470
{
1468-
home_replace(NULL, SCRIPT_ITEM(i).sn_name,
1471+
home_replace(NULL, SCRIPT_ITEM(i)->sn_name,
14691472
NameBuff, MAXPATHL, TRUE);
14701473
smsg("%3d: %s", i, NameBuff);
14711474
}
@@ -1481,8 +1484,8 @@ scriptnames_slash_adjust(void)
14811484
int i;
14821485

14831486
for (i = 1; i <= script_items.ga_len; ++i)
1484-
if (SCRIPT_ITEM(i).sn_name != NULL)
1485-
slash_adjust(SCRIPT_ITEM(i).sn_name);
1487+
if (SCRIPT_ITEM(i)->sn_name != NULL)
1488+
slash_adjust(SCRIPT_ITEM(i)->sn_name);
14861489
}
14871490
# endif
14881491

@@ -1502,7 +1505,7 @@ get_scriptname(scid_T id)
15021505
return (char_u *)_("environment variable");
15031506
if (id == SID_ERROR)
15041507
return (char_u *)_("error handler");
1505-
return SCRIPT_ITEM(id).sn_name;
1508+
return SCRIPT_ITEM(id)->sn_name;
15061509
}
15071510

15081511
# if defined(EXITFREE) || defined(PROTO)
@@ -1513,14 +1516,17 @@ free_scriptnames(void)
15131516

15141517
for (i = script_items.ga_len; i > 0; --i)
15151518
{
1519+
scriptitem_T *si = SCRIPT_ITEM(i);
1520+
15161521
// the variables themselves are cleared in evalvars_clear()
1517-
vim_free(SCRIPT_ITEM(i).sn_vars);
1522+
vim_free(si->sn_vars);
15181523

1519-
vim_free(SCRIPT_ITEM(i).sn_name);
1520-
free_string_option(SCRIPT_ITEM(i).sn_save_cpo);
1524+
vim_free(si->sn_name);
1525+
free_string_option(si->sn_save_cpo);
15211526
# ifdef FEAT_PROFILE
1522-
ga_clear(&SCRIPT_ITEM(i).sn_prl_ga);
1527+
ga_clear(&si->sn_prl_ga);
15231528
# endif
1529+
vim_free(si);
15241530
}
15251531
ga_clear(&script_items);
15261532
}
@@ -1832,7 +1838,7 @@ ex_scriptversion(exarg_T *eap UNUSED)
18321838
else
18331839
{
18341840
current_sctx.sc_version = nr;
1835-
SCRIPT_ITEM(current_sctx.sc_sid).sn_version = nr;
1841+
SCRIPT_ITEM(current_sctx.sc_sid)->sn_version = nr;
18361842
}
18371843
#endif
18381844
}

src/version.c

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

743743
static int included_patches[] =
744744
{ /* Add new patch number below this line */
745+
/**/
746+
154,
745747
/**/
746748
153,
747749
/**/

src/vim9compile.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1401,7 +1401,7 @@ get_script_item_idx(int sid, char_u *name, int check_writable)
14011401
{
14021402
hashtab_T *ht;
14031403
dictitem_T *di;
1404-
scriptitem_T *si = &SCRIPT_ITEM(sid);
1404+
scriptitem_T *si = SCRIPT_ITEM(sid);
14051405
int idx;
14061406

14071407
// First look the name up in the hashtable.
@@ -1433,7 +1433,7 @@ get_script_item_idx(int sid, char_u *name, int check_writable)
14331433
imported_T *
14341434
find_imported(char_u *name, cctx_T *cctx)
14351435
{
1436-
scriptitem_T *si = &SCRIPT_ITEM(current_sctx.sc_sid);
1436+
scriptitem_T *si = SCRIPT_ITEM(current_sctx.sc_sid);
14371437
int idx;
14381438

14391439
if (cctx != NULL)
@@ -1462,7 +1462,7 @@ find_imported(char_u *name, cctx_T *cctx)
14621462
static int
14631463
compile_load_scriptvar(cctx_T *cctx, char_u *name)
14641464
{
1465-
scriptitem_T *si = &SCRIPT_ITEM(current_sctx.sc_sid);
1465+
scriptitem_T *si = SCRIPT_ITEM(current_sctx.sc_sid);
14661466
int idx = get_script_item_idx(current_sctx.sc_sid, name, FALSE);
14671467
imported_T *import;
14681468

src/vim9execute.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -492,7 +492,7 @@ call_def_function(
492492
case ISN_LOADSCRIPT:
493493
{
494494
scriptitem_T *si =
495-
&SCRIPT_ITEM(iptr->isn_arg.script.script_sid);
495+
SCRIPT_ITEM(iptr->isn_arg.script.script_sid);
496496
svar_T *sv;
497497

498498
sv = ((svar_T *)si->sn_var_vals.ga_data)
@@ -598,7 +598,7 @@ call_def_function(
598598
// store script-local variable
599599
case ISN_STORESCRIPT:
600600
{
601-
scriptitem_T *si = &SCRIPT_ITEM(
601+
scriptitem_T *si = SCRIPT_ITEM(
602602
iptr->isn_arg.script.script_sid);
603603
svar_T *sv = ((svar_T *)si->sn_var_vals.ga_data)
604604
+ iptr->isn_arg.script.script_idx;
@@ -1551,7 +1551,7 @@ ex_disassemble(exarg_T *eap)
15511551
case ISN_LOADSCRIPT:
15521552
{
15531553
scriptitem_T *si =
1554-
&SCRIPT_ITEM(iptr->isn_arg.script.script_sid);
1554+
SCRIPT_ITEM(iptr->isn_arg.script.script_sid);
15551555
svar_T *sv = ((svar_T *)si->sn_var_vals.ga_data)
15561556
+ iptr->isn_arg.script.script_idx;
15571557

@@ -1561,7 +1561,7 @@ ex_disassemble(exarg_T *eap)
15611561
break;
15621562
case ISN_LOADS:
15631563
{
1564-
scriptitem_T *si = &SCRIPT_ITEM(iptr->isn_arg.loads.ls_sid);
1564+
scriptitem_T *si = SCRIPT_ITEM(iptr->isn_arg.loads.ls_sid);
15651565

15661566
smsg("%4d LOADS s:%s from %s", current,
15671567
iptr->isn_arg.string, si->sn_name);
@@ -1589,7 +1589,7 @@ ex_disassemble(exarg_T *eap)
15891589
case ISN_STORESCRIPT:
15901590
{
15911591
scriptitem_T *si =
1592-
&SCRIPT_ITEM(iptr->isn_arg.script.script_sid);
1592+
SCRIPT_ITEM(iptr->isn_arg.script.script_sid);
15931593
svar_T *sv = ((svar_T *)si->sn_var_vals.ga_data)
15941594
+ iptr->isn_arg.script.script_idx;
15951595

src/vim9script.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ in_vim9script(void)
3232
void
3333
ex_vim9script(exarg_T *eap)
3434
{
35-
scriptitem_T *si = &SCRIPT_ITEM(current_sctx.sc_sid);
35+
scriptitem_T *si = SCRIPT_ITEM(current_sctx.sc_sid);
3636

3737
if (!getline_equal(eap->getline, eap->cookie, getsourceline))
3838
{
@@ -114,7 +114,7 @@ new_imported(garray_T *gap)
114114
void
115115
free_imports(int sid)
116116
{
117-
scriptitem_T *si = &SCRIPT_ITEM(sid);
117+
scriptitem_T *si = SCRIPT_ITEM(sid);
118118
int idx;
119119

120120
for (idx = 0; idx < si->sn_imports.ga_len; ++idx)
@@ -226,7 +226,7 @@ handle_import(char_u *arg_start, garray_T *gap, int import_sid)
226226
if (*tv.vval.v_string == '.')
227227
{
228228
size_t len;
229-
scriptitem_T *si = &SCRIPT_ITEM(current_sctx.sc_sid);
229+
scriptitem_T *si = SCRIPT_ITEM(current_sctx.sc_sid);
230230
char_u *tail = gettail(si->sn_name);
231231
char_u *from_name;
232232

@@ -279,7 +279,7 @@ handle_import(char_u *arg_start, garray_T *gap, int import_sid)
279279
if (*arg_start == '*')
280280
{
281281
imported_T *imported = new_imported(gap != NULL ? gap
282-
: &SCRIPT_ITEM(import_sid).sn_imports);
282+
: &SCRIPT_ITEM(import_sid)->sn_imports);
283283

284284
if (imported == NULL)
285285
return NULL;
@@ -289,7 +289,7 @@ handle_import(char_u *arg_start, garray_T *gap, int import_sid)
289289
}
290290
else
291291
{
292-
scriptitem_T *script = &SCRIPT_ITEM(sid);
292+
scriptitem_T *script = SCRIPT_ITEM(sid);
293293

294294
arg = arg_start;
295295
if (*arg == '{')
@@ -358,7 +358,7 @@ handle_import(char_u *arg_start, garray_T *gap, int import_sid)
358358
}
359359

360360
imported = new_imported(gap != NULL ? gap
361-
: &SCRIPT_ITEM(import_sid).sn_imports);
361+
: &SCRIPT_ITEM(import_sid)->sn_imports);
362362
if (imported == NULL)
363363
return NULL;
364364

0 commit comments

Comments
 (0)