]> git.ipfire.org Git - thirdparty/vim.git/commitdiff
patch 8.2.0154: reallocating the list of scripts is inefficient v8.2.0154
authorBram Moolenaar <Bram@vim.org>
Sun, 26 Jan 2020 18:26:46 +0000 (19:26 +0100)
committerBram Moolenaar <Bram@vim.org>
Sun, 26 Jan 2020 18:26:46 +0000 (19:26 +0100)
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.

src/eval.c
src/evalvars.c
src/ex_docmd.c
src/globals.h
src/profiler.c
src/scriptfile.c
src/version.c
src/vim9compile.c
src/vim9execute.c
src/vim9script.c

index 72f932498bd69d791370eccc2aa8901971fefd9e..a9d0c7d4c4439a4e8d50dc5a16e8f62456bdcd1a 100644 (file)
@@ -692,7 +692,7 @@ get_lval(
 
        if (current_sctx.sc_version == SCRIPT_VERSION_VIM9 && *p == ':')
        {
-           scriptitem_T *si = &SCRIPT_ITEM(current_sctx.sc_sid);
+           scriptitem_T *si = SCRIPT_ITEM(current_sctx.sc_sid);
            char_u       *tp = skipwhite(p + 1);
 
            // parse the type after the name
index ebb30dd22e2677cfe3c15f2be52fe1bf3d5f4da6..866682b977c8eb742cbe171160c51dbb5c58312a 100644 (file)
@@ -2289,7 +2289,7 @@ get_var_tv(
        // imported variable from another script
        if (import != NULL)
        {
-           scriptitem_T    *si = &SCRIPT_ITEM(import->imp_sid);
+           scriptitem_T    *si = SCRIPT_ITEM(import->imp_sid);
            svar_T          *sv = ((svar_T *)si->sn_var_vals.ga_data)
                                                    + import->imp_var_vals_idx;
            tv = sv->sv_tv;
@@ -2571,7 +2571,7 @@ new_script_vars(scid_T id)
     if (sv == NULL)
        return;
     init_var_dict(&sv->sv_dict, &sv->sv_var, VAR_SCOPE);
-    SCRIPT_ITEM(id).sn_vars = sv;
+    SCRIPT_ITEM(id)->sn_vars = sv;
 }
 
 /*
@@ -2876,7 +2876,7 @@ set_var_const(
 
        if (is_script_local && current_sctx.sc_version == SCRIPT_VERSION_VIM9)
        {
-           scriptitem_T *si = &SCRIPT_ITEM(current_sctx.sc_sid);
+           scriptitem_T *si = SCRIPT_ITEM(current_sctx.sc_sid);
 
            // Store a pointer to the typval_T, so that it can be found by
            // index instead of using a hastab lookup.
index 0e6b8dc89b87c8bbbb817219e8d0d03fd8ba213e..c0ed1c88c686d39bb509d5d410fc013a997ca7d4 100644 (file)
@@ -2496,7 +2496,7 @@ do_one_cmd(
 #ifdef FEAT_EVAL
     // Set flag that any command was executed, used by ex_vim9script().
     if (getline_equal(ea.getline, ea.cookie, getsourceline))
-       SCRIPT_ITEM(current_sctx.sc_sid).sn_had_command = TRUE;
+       SCRIPT_ITEM(current_sctx.sc_sid)->sn_had_command = TRUE;
 
     /*
      * If the command just executed called do_cmdline(), any throw or ":return"
index 6a73bc135f6a115c83bb93acd1da34c7461ff7b8..b40eb2a85f5f8235c9bf2223c6668aad9620a982 100644 (file)
@@ -285,9 +285,9 @@ EXTERN int  debug_backtrace_level INIT(= 0); // breakpoint backtrace level
 # ifdef FEAT_PROFILE
 EXTERN int     do_profiling INIT(= PROF_NONE); // PROF_ values
 # endif
-EXTERN garray_T script_items INIT5(0, 0, sizeof(scriptitem_T), 4, NULL);
-# define SCRIPT_ITEM(id)    (((scriptitem_T *)script_items.ga_data)[(id) - 1])
-# define SCRIPT_SV(id)     (SCRIPT_ITEM(id).sn_vars)
+EXTERN garray_T script_items INIT5(0, 0, sizeof(scriptitem_T *), 20, NULL);
+# define SCRIPT_ITEM(id)    (((scriptitem_T **)script_items.ga_data)[(id) - 1])
+# define SCRIPT_SV(id)     (SCRIPT_ITEM(id)->sn_vars)
 # define SCRIPT_VARS(id)    (SCRIPT_SV(id)->sv_dict.dv_hashtab)
 
 # define FUNCLINE(fp, j)       ((char_u **)(fp->uf_lines.ga_data))[j]
index cd962cabd4cbd5ef24c36b4b9efece5961d07aca..647934d522cb1ea97335270431573c43fad36f3d 100644 (file)
@@ -440,7 +440,7 @@ prof_inchar_exit(void)
 prof_def_func(void)
 {
     if (current_sctx.sc_sid > 0)
-       return SCRIPT_ITEM(current_sctx.sc_sid).sn_pr_force;
+       return SCRIPT_ITEM(current_sctx.sc_sid)->sn_pr_force;
     return FALSE;
 }
 
@@ -763,7 +763,7 @@ script_prof_save(
 
     if (current_sctx.sc_sid > 0 && current_sctx.sc_sid <= script_items.ga_len)
     {
-       si = &SCRIPT_ITEM(current_sctx.sc_sid);
+       si = SCRIPT_ITEM(current_sctx.sc_sid);
        if (si->sn_prof_on && si->sn_pr_nest++ == 0)
            profile_start(&si->sn_pr_child);
     }
@@ -780,7 +780,7 @@ script_prof_restore(proftime_T *tm)
 
     if (current_sctx.sc_sid > 0 && current_sctx.sc_sid <= script_items.ga_len)
     {
-       si = &SCRIPT_ITEM(current_sctx.sc_sid);
+       si = SCRIPT_ITEM(current_sctx.sc_sid);
        if (si->sn_prof_on && --si->sn_pr_nest == 0)
        {
            profile_end(&si->sn_pr_child);
@@ -805,7 +805,7 @@ script_dump_profile(FILE *fd)
 
     for (id = 1; id <= script_items.ga_len; ++id)
     {
-       si = &SCRIPT_ITEM(id);
+       si = SCRIPT_ITEM(id);
        if (si->sn_prof_on)
        {
            fprintf(fd, "SCRIPT  %s\n", si->sn_name);
@@ -905,7 +905,7 @@ script_line_start(void)
 
     if (current_sctx.sc_sid <= 0 || current_sctx.sc_sid > script_items.ga_len)
        return;
-    si = &SCRIPT_ITEM(current_sctx.sc_sid);
+    si = SCRIPT_ITEM(current_sctx.sc_sid);
     if (si->sn_prof_on && SOURCING_LNUM >= 1)
     {
        // Grow the array before starting the timer, so that the time spent
@@ -940,7 +940,7 @@ script_line_exec(void)
 
     if (current_sctx.sc_sid <= 0 || current_sctx.sc_sid > script_items.ga_len)
        return;
-    si = &SCRIPT_ITEM(current_sctx.sc_sid);
+    si = SCRIPT_ITEM(current_sctx.sc_sid);
     if (si->sn_prof_on && si->sn_prl_idx >= 0)
        si->sn_prl_execed = TRUE;
 }
@@ -956,7 +956,7 @@ script_line_end(void)
 
     if (current_sctx.sc_sid <= 0 || current_sctx.sc_sid > script_items.ga_len)
        return;
-    si = &SCRIPT_ITEM(current_sctx.sc_sid);
+    si = SCRIPT_ITEM(current_sctx.sc_sid);
     if (si->sn_prof_on && si->sn_prl_idx >= 0
                                     && si->sn_prl_idx < si->sn_prl_ga.ga_len)
     {
index 376e0c3e6113ccf1d381d0a6a5e5aa215a9f7011..09548d89bcdca19a134ec6a2c3bfc6bb39737afe 100644 (file)
@@ -1124,7 +1124,7 @@ do_source(
        //   inode number, even though to the user it is the same script.
        // - If a script is deleted and another script is written, with a
        //   different name, the inode may be re-used.
-       si = &SCRIPT_ITEM(sid);
+       si = SCRIPT_ITEM(sid);
        if (si->sn_name != NULL && fnamecmp(si->sn_name, fname_exp) == 0)
                // Found it!
                break;
@@ -1294,8 +1294,11 @@ do_source(
            goto almosttheend;
        while (script_items.ga_len < current_sctx.sc_sid)
        {
+           si = ALLOC_CLEAR_ONE(scriptitem_T);
+           if (si == NULL)
+               goto almosttheend;
            ++script_items.ga_len;
-           si = &SCRIPT_ITEM(script_items.ga_len);
+           SCRIPT_ITEM(script_items.ga_len) = si;
            si->sn_name = NULL;
            si->sn_version = 1;
 
@@ -1308,7 +1311,7 @@ do_source(
            si->sn_prof_on = FALSE;
 # endif
        }
-       si = &SCRIPT_ITEM(current_sctx.sc_sid);
+       si = SCRIPT_ITEM(current_sctx.sc_sid);
        si->sn_name = fname_exp;
        fname_exp = vim_strsave(si->sn_name);  // used for autocmd
        if (ret_sid != NULL)
@@ -1364,7 +1367,7 @@ do_source(
     if (do_profiling == PROF_YES)
     {
        // Get "si" again, "script_items" may have been reallocated.
-       si = &SCRIPT_ITEM(current_sctx.sc_sid);
+       si = SCRIPT_ITEM(current_sctx.sc_sid);
        if (si->sn_prof_on)
        {
            profile_end(&si->sn_pr_start);
@@ -1411,7 +1414,7 @@ do_source(
 #ifdef FEAT_EVAL
 almosttheend:
     // Get "si" again, "script_items" may have been reallocated.
-    si = &SCRIPT_ITEM(current_sctx.sc_sid);
+    si = SCRIPT_ITEM(current_sctx.sc_sid);
     if (si->sn_save_cpo != NULL)
     {
        free_string_option(p_cpo);
@@ -1456,16 +1459,16 @@ ex_scriptnames(exarg_T *eap)
            emsg(_(e_invarg));
        else
        {
-           eap->arg = SCRIPT_ITEM(eap->line2).sn_name;
+           eap->arg = SCRIPT_ITEM(eap->line2)->sn_name;
            do_exedit(eap, NULL);
        }
        return;
     }
 
     for (i = 1; i <= script_items.ga_len && !got_int; ++i)
-       if (SCRIPT_ITEM(i).sn_name != NULL)
+       if (SCRIPT_ITEM(i)->sn_name != NULL)
        {
-           home_replace(NULL, SCRIPT_ITEM(i).sn_name,
+           home_replace(NULL, SCRIPT_ITEM(i)->sn_name,
                                                    NameBuff, MAXPATHL, TRUE);
            smsg("%3d: %s", i, NameBuff);
        }
@@ -1481,8 +1484,8 @@ scriptnames_slash_adjust(void)
     int i;
 
     for (i = 1; i <= script_items.ga_len; ++i)
-       if (SCRIPT_ITEM(i).sn_name != NULL)
-           slash_adjust(SCRIPT_ITEM(i).sn_name);
+       if (SCRIPT_ITEM(i)->sn_name != NULL)
+           slash_adjust(SCRIPT_ITEM(i)->sn_name);
 }
 # endif
 
@@ -1502,7 +1505,7 @@ get_scriptname(scid_T id)
        return (char_u *)_("environment variable");
     if (id == SID_ERROR)
        return (char_u *)_("error handler");
-    return SCRIPT_ITEM(id).sn_name;
+    return SCRIPT_ITEM(id)->sn_name;
 }
 
 # if defined(EXITFREE) || defined(PROTO)
@@ -1513,14 +1516,17 @@ free_scriptnames(void)
 
     for (i = script_items.ga_len; i > 0; --i)
     {
+       scriptitem_T *si = SCRIPT_ITEM(i);
+
        // the variables themselves are cleared in evalvars_clear()
-       vim_free(SCRIPT_ITEM(i).sn_vars);
+       vim_free(si->sn_vars);
 
-       vim_free(SCRIPT_ITEM(i).sn_name);
-       free_string_option(SCRIPT_ITEM(i).sn_save_cpo);
+       vim_free(si->sn_name);
+       free_string_option(si->sn_save_cpo);
 #  ifdef FEAT_PROFILE
-       ga_clear(&SCRIPT_ITEM(i).sn_prl_ga);
+       ga_clear(&si->sn_prl_ga);
 #  endif
+       vim_free(si);
     }
     ga_clear(&script_items);
 }
@@ -1832,7 +1838,7 @@ ex_scriptversion(exarg_T *eap UNUSED)
     else
     {
        current_sctx.sc_version = nr;
-       SCRIPT_ITEM(current_sctx.sc_sid).sn_version = nr;
+       SCRIPT_ITEM(current_sctx.sc_sid)->sn_version = nr;
     }
 #endif
 }
index c7ecb0e4a50fa89594076f8d46105d31e70d9375..19a5c0d10ac9be9fc637d76f8ef286650a381887 100644 (file)
@@ -742,6 +742,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    154,
 /**/
     153,
 /**/
index 9f273c579a1b4d37eb7a69115d7dbcd1c758d8d6..66906221c43f740d361c685723a7c9c6f4a93686 100644 (file)
@@ -1401,7 +1401,7 @@ get_script_item_idx(int sid, char_u *name, int check_writable)
 {
     hashtab_T      *ht;
     dictitem_T     *di;
-    scriptitem_T    *si = &SCRIPT_ITEM(sid);
+    scriptitem_T    *si = SCRIPT_ITEM(sid);
     int                    idx;
 
     // First look the name up in the hashtable.
@@ -1433,7 +1433,7 @@ get_script_item_idx(int sid, char_u *name, int check_writable)
     imported_T *
 find_imported(char_u *name, cctx_T *cctx)
 {
-    scriptitem_T    *si = &SCRIPT_ITEM(current_sctx.sc_sid);
+    scriptitem_T    *si = SCRIPT_ITEM(current_sctx.sc_sid);
     int                    idx;
 
     if (cctx != NULL)
@@ -1462,7 +1462,7 @@ find_imported(char_u *name, cctx_T *cctx)
     static int
 compile_load_scriptvar(cctx_T *cctx, char_u *name)
 {
-    scriptitem_T    *si = &SCRIPT_ITEM(current_sctx.sc_sid);
+    scriptitem_T    *si = SCRIPT_ITEM(current_sctx.sc_sid);
     int                    idx = get_script_item_idx(current_sctx.sc_sid, name, FALSE);
     imported_T     *import;
 
index 10da178eb53517bffa27359c91a65c9855d181e3..a738aa1e52edea99471ff15cf70a3fce6b8e0bf9 100644 (file)
@@ -492,7 +492,7 @@ call_def_function(
            case ISN_LOADSCRIPT:
                {
                    scriptitem_T *si =
-                                &SCRIPT_ITEM(iptr->isn_arg.script.script_sid);
+                                 SCRIPT_ITEM(iptr->isn_arg.script.script_sid);
                    svar_T       *sv;
 
                    sv = ((svar_T *)si->sn_var_vals.ga_data)
@@ -598,7 +598,7 @@ call_def_function(
            // store script-local variable
            case ISN_STORESCRIPT:
                {
-                   scriptitem_T *si = &SCRIPT_ITEM(
+                   scriptitem_T *si = SCRIPT_ITEM(
                                              iptr->isn_arg.script.script_sid);
                    svar_T       *sv = ((svar_T *)si->sn_var_vals.ga_data)
                                             + iptr->isn_arg.script.script_idx;
@@ -1551,7 +1551,7 @@ ex_disassemble(exarg_T *eap)
            case ISN_LOADSCRIPT:
                {
                    scriptitem_T *si =
-                                &SCRIPT_ITEM(iptr->isn_arg.script.script_sid);
+                                 SCRIPT_ITEM(iptr->isn_arg.script.script_sid);
                    svar_T *sv = ((svar_T *)si->sn_var_vals.ga_data)
                                             + iptr->isn_arg.script.script_idx;
 
@@ -1561,7 +1561,7 @@ ex_disassemble(exarg_T *eap)
                break;
            case ISN_LOADS:
                {
-                   scriptitem_T *si = &SCRIPT_ITEM(iptr->isn_arg.loads.ls_sid);
+                   scriptitem_T *si = SCRIPT_ITEM(iptr->isn_arg.loads.ls_sid);
 
                    smsg("%4d LOADS s:%s from %s", current,
                                            iptr->isn_arg.string, si->sn_name);
@@ -1589,7 +1589,7 @@ ex_disassemble(exarg_T *eap)
            case ISN_STORESCRIPT:
                {
                    scriptitem_T *si =
-                                &SCRIPT_ITEM(iptr->isn_arg.script.script_sid);
+                                 SCRIPT_ITEM(iptr->isn_arg.script.script_sid);
                    svar_T *sv = ((svar_T *)si->sn_var_vals.ga_data)
                                             + iptr->isn_arg.script.script_idx;
 
index 4596ce35aba46f47bd7f2229f6263cd305d69759..fb1925835a69788f9153dac8c0e42297f152f850 100644 (file)
@@ -32,7 +32,7 @@ in_vim9script(void)
     void
 ex_vim9script(exarg_T *eap)
 {
-    scriptitem_T *si = &SCRIPT_ITEM(current_sctx.sc_sid);
+    scriptitem_T *si = SCRIPT_ITEM(current_sctx.sc_sid);
 
     if (!getline_equal(eap->getline, eap->cookie, getsourceline))
     {
@@ -114,7 +114,7 @@ new_imported(garray_T *gap)
     void
 free_imports(int sid)
 {
-    scriptitem_T    *si = &SCRIPT_ITEM(sid);
+    scriptitem_T    *si = SCRIPT_ITEM(sid);
     int                    idx;
 
     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)
     if (*tv.vval.v_string == '.')
     {
        size_t          len;
-       scriptitem_T    *si = &SCRIPT_ITEM(current_sctx.sc_sid);
+       scriptitem_T    *si = SCRIPT_ITEM(current_sctx.sc_sid);
        char_u          *tail = gettail(si->sn_name);
        char_u          *from_name;
 
@@ -279,7 +279,7 @@ handle_import(char_u *arg_start, garray_T *gap, int import_sid)
     if (*arg_start == '*')
     {
        imported_T *imported = new_imported(gap != NULL ? gap
-                                       : &SCRIPT_ITEM(import_sid).sn_imports);
+                                       : &SCRIPT_ITEM(import_sid)->sn_imports);
 
        if (imported == NULL)
            return NULL;
@@ -289,7 +289,7 @@ handle_import(char_u *arg_start, garray_T *gap, int import_sid)
     }
     else
     {
-       scriptitem_T *script = &SCRIPT_ITEM(sid);
+       scriptitem_T *script = SCRIPT_ITEM(sid);
 
        arg = arg_start;
        if (*arg == '{')
@@ -358,7 +358,7 @@ handle_import(char_u *arg_start, garray_T *gap, int import_sid)
            }
 
            imported = new_imported(gap != NULL ? gap
-                                       : &SCRIPT_ITEM(import_sid).sn_imports);
+                                      : &SCRIPT_ITEM(import_sid)->sn_imports);
            if (imported == NULL)
                return NULL;