patch 9.1.0138: too many STRLEN calls when getting a memline

Commit: 
https://github.com/vim/vim/commit/02d7a6c6cfceb3faf9c98fcb7c458760cd50d269
Author: John Marriott <[email protected]>
Date:   Mon Feb 26 21:21:17 2024 +0100

    patch 9.1.0138: too many STRLEN calls when getting a memline
    
    Problem:  too many STRLEN calls when getting a memline
    Solution: Optimize calls to STRLEN(), add a few functions in memline.c
              that return the byte length instead of relying on STRLEN()
              (John Marriott)
    
    closes: #14052
    
    Signed-off-by: John Marriott <[email protected]>
    Signed-off-by: Christian Brabandt <[email protected]>

diff --git a/src/memline.c b/src/memline.c
index cf2dc8c31..bbc13d7ed 100644
--- a/src/memline.c
+++ b/src/memline.c
@@ -1754,7 +1754,7 @@ ml_recover(int checkext)
        for (idx = 1; idx <= lnum; ++idx)
        {
            // Need to copy one line, fetching the other one may flush it.
-           p = vim_strsave(ml_get(idx));
+           p = vim_strnsave(ml_get(idx), ml_get_len(idx));
            i = STRCMP(p, ml_get(idx + lnum));
            vim_free(p);
            if (i != 0)
@@ -2675,6 +2675,37 @@ ml_get_cursor(void)
                                                        curwin->w_cursor.col);
 }
 
+// return length (excluding the NUL) of the given line
+    colnr_T
+ml_get_len(linenr_T lnum)
+{
+    return ml_get_buf_len(curbuf, lnum);
+}
+
+// return length (excluding the NUL) of the cursor line
+    colnr_T
+ml_get_curline_len(void)
+{
+    return ml_get_buf_len(curbuf, curwin->w_cursor.lnum);
+}
+
+// return length (excluding the NUL) of the cursor position
+    colnr_T
+ml_get_cursor_len(void)
+{
+    return ml_get_buf_len(curbuf, curwin->w_cursor.lnum) - 
curwin->w_cursor.col;
+}
+
+// return length (excluding the NUL) of the given line in the given buffer
+    colnr_T
+ml_get_buf_len(buf_T *buf, linenr_T lnum)
+{
+    if (*ml_get_buf(buf, lnum, FALSE) == NUL)
+        return 0;
+
+    return buf->b_ml.ml_line_len - 1;
+}
+
 /*
  * Return a pointer to a line in a specific buffer
  *
@@ -2727,7 +2758,6 @@ errorret:
     if (buf->b_ml.ml_line_lnum != lnum || mf_dont_release)
     {
        unsigned    start, end;
-       colnr_T     len;
        int         idx;
 
        ml_flush_line(buf);
@@ -2763,10 +2793,9 @@ errorret:
            end = dp->db_txt_end;
        else
            end = ((dp->db_index[idx - 1]) & DB_INDEX_MASK);
-       len = end - start;
 
        buf->b_ml.ml_line_ptr = (char_u *)dp + start;
-       buf->b_ml.ml_line_len = len;
+       buf->b_ml.ml_line_len = end - start;
        buf->b_ml.ml_line_lnum = lnum;
        buf->b_ml.ml_flags &= ~(ML_LINE_DIRTY | ML_ALLOCATED);
     }
@@ -3400,10 +3429,10 @@ ml_append_int(
 #ifdef FEAT_NETBEANS_INTG
     if (netbeans_active())
     {
-       if (STRLEN(line) > 0)
-           netbeans_inserted(buf, lnum+1, (colnr_T)0, line, (int)STRLEN(line));
-       netbeans_inserted(buf, lnum+1, (colnr_T)STRLEN(line),
-                                                          (char_u *)"
", 1);
+       int line_len = (int)STRLEN(line);
+       if (line_len > 0)
+           netbeans_inserted(buf, lnum+1, (colnr_T)0, line, line_len);
+       netbeans_inserted(buf, lnum+1, (colnr_T)line_len, (char_u *)"
", 1);
     }
 #endif
 #ifdef FEAT_JOB_CHANNEL
@@ -3571,7 +3600,7 @@ ml_replace_len(
 #ifdef FEAT_NETBEANS_INTG
     if (netbeans_active())
     {
-       netbeans_removed(curbuf, lnum, 0, (long)STRLEN(ml_get(lnum)));
+       netbeans_removed(curbuf, lnum, 0, (long)ml_get_len(lnum));
        netbeans_inserted(curbuf, lnum, 0, line, (int)STRLEN(line));
     }
 #endif
@@ -5192,15 +5221,15 @@ findswapname(
                    {
                        char_u  *name;
                        int     dialog_result;
+                       size_t  len = STRLEN(_("Swap file \""));
 
                        name = alloc(STRLEN(fname)
-                               + STRLEN(_("Swap file \""))
+                               + len
                                + STRLEN(_("\" already exists!")) + 5);
                        if (name != NULL)
                        {
                            STRCPY(name, _("Swap file \""));
-                           home_replace(NULL, fname, name + STRLEN(name),
-                                                                 1000, TRUE);
+                           home_replace(NULL, fname, name + len, 1000, TRUE);
                            STRCAT(name, _("\" already exists!"));
                        }
                        dialog_result = do_dialog(VIM_WARNING,
diff --git a/src/normal.c b/src/normal.c
index 8a10b86d7..015a25078 100644
--- a/src/normal.c
+++ b/src/normal.c
@@ -3225,8 +3225,7 @@ nv_colon(cmdarg_T *cap)
        clearop(cap->oap);
     else if (cap->oap->op_type != OP_NOP
            && (cap->oap->start.lnum > curbuf->b_ml.ml_line_count
-               || cap->oap->start.col >
-                                 (colnr_T)STRLEN(ml_get(cap->oap->start.lnum))
+               || cap->oap->start.col > ml_get_len(cap->oap->start.lnum)
                || did_emsg
               ))
        // The start of the operator has become invalid by the Ex command.
@@ -3675,7 +3674,7 @@ get_visual_text(
     if (VIsual_mode == 'V')
     {
        *pp = ml_get_curline();
-       *lenp = (int)STRLEN(*pp);
+       *lenp = (int)ml_get_curline_len();
     }
     else
     {
@@ -4768,7 +4767,6 @@ nv_kundo(cmdarg_T *cap)
     static void
 nv_replace(cmdarg_T *cap)
 {
-    char_u     *ptr;
     int                had_ctrl_v;
     long       n;
 
@@ -4835,9 +4833,8 @@ nv_replace(cmdarg_T *cap)
     }
 
     // Abort if not enough characters to replace.
-    ptr = ml_get_cursor();
-    if (STRLEN(ptr) < (unsigned)cap->count1
-           || (has_mbyte && mb_charlen(ptr) < cap->count1))
+    if ((size_t)ml_get_cursor_len() < (unsigned)cap->count1
+           || (has_mbyte && mb_charlen(ml_get_cursor()) < cap->count1))
     {
        clearopbeep(cap->oap);
        return;
@@ -4917,11 +4914,13 @@ nv_replace(cmdarg_T *cap)
        }
        else
        {
+           char_u *ptr;
+
            // Replace the characters within one line.
            for (n = cap->count1; n > 0; --n)
            {
-               // Get ptr again, because u_save and/or showmatch() will have
-               // released the line.  This may also happen in ins_copychar().
+               // Get ptr again, because ins_copychar() and showmatch()
+               // will have released the line.
                // At the same time we let know that the line will be changed.
                if (cap->nchar == Ctrl_E || cap->nchar == Ctrl_Y)
                {
@@ -4945,6 +4944,7 @@ nv_replace(cmdarg_T *cap)
            if (netbeans_active())
            {
                colnr_T  start = (colnr_T)(curwin->w_cursor.col - cap->count1);
+               ptr = ml_get_curline();
 
                netbeans_removed(curbuf, curwin->w_cursor.lnum, start,
                                                           cap->count1);
@@ -5130,7 +5130,7 @@ n_swapchar(cmdarg_T *cap)
                    if (did_change)
                    {
                        ptr = ml_get(pos.lnum);
-                       count = (int)STRLEN(ptr) - pos.col;
+                       count = (int)ml_get_len(pos.lnum) - pos.col;
                        netbeans_removed(curbuf, pos.lnum, pos.col,
                                                                 (long)count);
                        // line may have been flushed, get it again
@@ -5919,7 +5919,7 @@ nv_gi_cmd(cmdarg_T *cap)
     {
        curwin->w_cursor = curbuf->b_last_insert;
        check_cursor_lnum();
-       i = (int)STRLEN(ml_get_curline());
+       i = (int)ml_get_curline_len();
        if (curwin->w_cursor.col > (colnr_T)i)
        {
            if (virtual_active())
@@ -6717,7 +6717,7 @@ unadjust_for_sel(void)
        else if (pp->lnum > 1)
        {
            --pp->lnum;
-           pp->col = (colnr_T)STRLEN(ml_get(pp->lnum));
+           pp->col = ml_get_len(pp->lnum);
            return TRUE;
        }
     }
diff --git a/src/proto/memline.pro b/src/proto/memline.pro
index 3fa8707d8..eb21a7eec 100644
--- a/src/proto/memline.pro
+++ b/src/proto/memline.pro
@@ -19,6 +19,10 @@ char_u *ml_get(linenr_T lnum);
 char_u *ml_get_pos(pos_T *pos);
 char_u *ml_get_curline(void);
 char_u *ml_get_cursor(void);
+colnr_T ml_get_len(linenr_T lnum);
+colnr_T ml_get_curline_len(void);
+colnr_T ml_get_cursor_len(void);
+colnr_T ml_get_buf_len(buf_T *buf, linenr_T lnum);
 char_u *ml_get_buf(buf_T *buf, linenr_T lnum, int will_change);
 int ml_line_alloced(void);
 int ml_append(linenr_T lnum, char_u *line, colnr_T len, int newfile);
diff --git a/src/version.c b/src/version.c
index 38201599e..8ad03e380 100644
--- a/src/version.c
+++ b/src/version.c
@@ -704,6 +704,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    138,
 /**/
     137,
 /**/

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/vim_dev/E1rehbv-003Eob-H7%40256bit.org.

Raspunde prin e-mail lui