Skip to content

Commit a7e671f

Browse files
John Marriottchrisbra
authored andcommitted
patch 9.1.2044: Inefficient use of ga_concat()
Problem: Inefficient use of ga_concat() Solution: Use ga_concat_len() when the length is already known to avoid use of strlen() (John Marriott). Additionally the following changes are done: os_unix.c: - in function `socket_server_list_sockets()` use a `string_T` for the strings `buf` and `path` for use in `ga_concat_len()` and drop un-needed variable `dir`. quickfix.c: - in function `qf_jump_print_msg()` use a `string_T` for the string `IObuff` for use in `ga_concat_len()`. - in function `qf_range_text()` use a `string_T` for the string `buf` for use in `ga_concat_len()`. register.c: - simplify function `execreg_line_continuation()`. terminal.c: - in function `read_dump_file()` use a `string_T` for the string `prev_char` for use in `ga_concat_len()`. tuple.c: - in function `tuple_join_inner()` use a `string_T` for the string `s` for use in `ga_concat_len()`. Also, change local struct `join_T` to use `string_T`. vim9type.c: - in functions `type_name_tuple()` and `type_name_func()` use a `string_T` for the string `arg_type` for use in `ga_concat_len()`. closes: #19038 Signed-off-by: John Marriott <basilisk@internode.on.net> Signed-off-by: Christian Brabandt <cb@256bit.org>
1 parent 96a1caa commit a7e671f

11 files changed

Lines changed: 136 additions & 112 deletions

File tree

src/blob.c

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -276,13 +276,16 @@ blob2string(blob_T *blob, char_u **tofree, char_u *numbuf)
276276

277277
// Store bytes in the growarray.
278278
ga_init2(&ga, 1, 4000);
279-
ga_concat(&ga, (char_u *)"0z");
279+
ga_concat_len(&ga, (char_u *)"0z", 2);
280280
for (i = 0; i < blob_len(blob); i++)
281281
{
282+
size_t numbuflen;
283+
282284
if (i > 0 && (i & 3) == 0)
283-
ga_concat(&ga, (char_u *)".");
284-
vim_snprintf((char *)numbuf, NUMBUFLEN, "%02X", blob_get(blob, i));
285-
ga_concat(&ga, numbuf);
285+
ga_concat_len(&ga, (char_u *)".", 1);
286+
numbuflen = vim_snprintf_safelen((char *)numbuf, NUMBUFLEN,
287+
"%02X", blob_get(blob, i));
288+
ga_concat_len(&ga, numbuf, numbuflen);
286289
}
287290
ga_append(&ga, NUL); // append a NUL at the end
288291
*tofree = ga.ga_data;

src/eval.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6270,14 +6270,14 @@ partial_tv2string(
62706270
fname = string_quote(pt == NULL ? NULL : partial_name(pt), FALSE);
62716271

62726272
ga_init2(&ga, 1, 100);
6273-
ga_concat(&ga, (char_u *)"function(");
6273+
ga_concat_len(&ga, (char_u *)"function(", 9);
62746274
if (fname != NULL)
62756275
{
62766276
// When using uf_name prepend "g:" for a global function.
62776277
if (pt != NULL && pt->pt_name == NULL && fname[0] == '\''
62786278
&& vim_isupper(fname[1]))
62796279
{
6280-
ga_concat(&ga, (char_u *)"'g:");
6280+
ga_concat_len(&ga, (char_u *)"'g:", 3);
62816281
ga_concat(&ga, fname + 1);
62826282
}
62836283
else
@@ -6286,21 +6286,21 @@ partial_tv2string(
62866286
}
62876287
if (pt != NULL && pt->pt_argc > 0)
62886288
{
6289-
ga_concat(&ga, (char_u *)", [");
6289+
ga_concat_len(&ga, (char_u *)", [", 3);
62906290
for (i = 0; i < pt->pt_argc; ++i)
62916291
{
62926292
if (i > 0)
6293-
ga_concat(&ga, (char_u *)", ");
6293+
ga_concat_len(&ga, (char_u *)", ", 2);
62946294
ga_concat(&ga, tv2string(&pt->pt_argv[i], &tf, numbuf, copyID));
62956295
vim_free(tf);
62966296
}
6297-
ga_concat(&ga, (char_u *)"]");
6297+
ga_concat_len(&ga, (char_u *)"]", 1);
62986298
}
62996299
if (pt != NULL && pt->pt_dict != NULL)
63006300
{
63016301
typval_T dtv;
63026302

6303-
ga_concat(&ga, (char_u *)", ");
6303+
ga_concat_len(&ga, (char_u *)", ", 2);
63046304
dtv.v_type = VAR_DICT;
63056305
dtv.vval.v_dict = pt->pt_dict;
63066306
ga_concat(&ga, tv2string(&dtv, &tf, numbuf, copyID));

src/evalwindow.c

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1200,10 +1200,14 @@ f_winrestcmd(typval_T *argvars UNUSED, typval_T *rettv)
12001200
winnr = 1;
12011201
FOR_ALL_WINDOWS(wp)
12021202
{
1203-
sprintf((char *)buf, ":%dresize %d|", winnr, wp->w_height);
1204-
ga_concat(&ga, buf);
1205-
sprintf((char *)buf, "vert :%dresize %d|", winnr, wp->w_width);
1206-
ga_concat(&ga, buf);
1203+
size_t buflen;
1204+
1205+
buflen = vim_snprintf_safelen((char *)buf, sizeof(buf),
1206+
":%dresize %d|", winnr, wp->w_height);
1207+
ga_concat_len(&ga, buf, buflen);
1208+
buflen = vim_snprintf_safelen((char *)buf, sizeof(buf),
1209+
"vert :%dresize %d|", winnr, wp->w_width);
1210+
ga_concat_len(&ga, buf, buflen);
12071211
++winnr;
12081212
}
12091213
}

src/gui.c

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5308,34 +5308,34 @@ gui_do_findrepl(
53085308

53095309
ga_init2(&ga, 1, 100);
53105310
if (type == FRD_REPLACEALL)
5311-
ga_concat(&ga, (char_u *)"%s/");
5311+
ga_concat_len(&ga, (char_u *)"%s/", 3);
53125312

5313-
ga_concat(&ga, (char_u *)"\\V");
5313+
ga_concat_len(&ga, (char_u *)"\\V", 2);
53145314
if (flags & FRD_MATCH_CASE)
5315-
ga_concat(&ga, (char_u *)"\\C");
5315+
ga_concat_len(&ga, (char_u *)"\\C", 2);
53165316
else
5317-
ga_concat(&ga, (char_u *)"\\c");
5317+
ga_concat_len(&ga, (char_u *)"\\c", 2);
53185318
if (flags & FRD_WHOLE_WORD)
5319-
ga_concat(&ga, (char_u *)"\\<");
5319+
ga_concat_len(&ga, (char_u *)"\\<", 2);
53205320
// escape slash and backslash
53215321
p = vim_strsave_escaped(find_text, (char_u *)"/\\");
53225322
if (p != NULL)
53235323
ga_concat(&ga, p);
53245324
vim_free(p);
53255325
if (flags & FRD_WHOLE_WORD)
5326-
ga_concat(&ga, (char_u *)"\\>");
5326+
ga_concat_len(&ga, (char_u *)"\\>", 2);
53275327

53285328
if (type == FRD_REPLACEALL)
53295329
{
5330-
ga_concat(&ga, (char_u *)"/");
5330+
ga_concat_len(&ga, (char_u *)"/", 1);
53315331
// Escape slash and backslash.
53325332
// Also escape tilde and ampersand if 'magic' is set.
53335333
p = vim_strsave_escaped(repl_text,
53345334
p_magic ? (char_u *)"/\\~&" : (char_u *)"/\\");
53355335
if (p != NULL)
53365336
ga_concat(&ga, p);
53375337
vim_free(p);
5338-
ga_concat(&ga, (char_u *)"/g");
5338+
ga_concat_len(&ga, (char_u *)"/g", 2);
53395339
}
53405340
ga_append(&ga, NUL);
53415341

src/os_unix.c

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -9363,8 +9363,8 @@ socket_server_uninit(void)
93639363
socket_server_list_sockets(void)
93649364
{
93659365
garray_T str;
9366-
char_u *buf;
9367-
char_u *path;
9366+
string_T buf;
9367+
string_T path;
93689368
DIR *dirp;
93699369
struct dirent *dp;
93709370
struct sockaddr_un addr;
@@ -9374,13 +9374,15 @@ socket_server_list_sockets(void)
93749374
(char_u *)"/tmp"
93759375
};
93769376

9377-
if ((buf = alloc(sizeof(addr.sun_path))) == NULL)
9377+
if ((buf.string = alloc(sizeof(addr.sun_path))) == NULL)
93789378
return NULL;
9379-
if ((path = alloc(sizeof(addr.sun_path))) == NULL)
9379+
if ((path.string = alloc(sizeof(addr.sun_path))) == NULL)
93809380
{
9381-
vim_free(buf);
9381+
vim_free(buf.string);
93829382
return NULL;
93839383
}
9384+
buf.length = 0;
9385+
path.length = 0;
93849386

93859387
ga_init2(&str, 1, 100);
93869388

@@ -9393,15 +9395,13 @@ socket_server_list_sockets(void)
93939395

93949396
if (STRCMP(dir, "/tmp") == 0 ||
93959397
(known_dirs[1] != NULL && STRCMP(dir, known_dirs[1]) == 0))
9396-
vim_snprintf((char *)path, sizeof(addr.sun_path), "%s/vim-%lu",
9397-
dir, (unsigned long int)getuid());
9398+
path.length = vim_snprintf_safelen((char *)path.string, sizeof(addr.sun_path),
9399+
"%s/vim-%lu", dir, (unsigned long int)getuid());
93989400
else
9399-
vim_snprintf((char *)path, sizeof(addr.sun_path), "%s/vim", dir);
9400-
9401-
dir = path;
9402-
9403-
dirp = opendir((char *)dir);
9401+
path.length = vim_snprintf_safelen((char *)path.string, sizeof(addr.sun_path),
9402+
"%s/vim", dir);
94049403

9404+
dirp = opendir((char *)path.string);
94059405
if (dirp == NULL)
94069406
continue;
94079407

@@ -9411,15 +9411,15 @@ socket_server_list_sockets(void)
94119411
if (STRCMP(dp->d_name, ".") == 0 || STRCMP(dp->d_name, "..") == 0)
94129412
continue;
94139413

9414-
vim_snprintf((char *)buf, sizeof(addr.sun_path), "%s/%s",
9415-
dir, dp->d_name);
9414+
buf.length = vim_snprintf_safelen((char *)buf.string, sizeof(addr.sun_path),
9415+
"%s/%s", path.string, dp->d_name);
94169416

94179417
// Try sending an ALIVE command. This is more assuring than a
94189418
// simple connect, and *also seems to make tests less flaky*.
9419-
if (!socket_server_check_alive(buf))
9419+
if (!socket_server_check_alive(buf.string))
94209420
continue;
94219421

9422-
ga_concat(&str, (char_u *)dp->d_name);
9422+
ga_concat_len(&str, (char_u *)dp->d_name, buf.length - (path.length + 1));
94239423
ga_append(&str, '\n');
94249424
}
94259425

@@ -9428,8 +9428,8 @@ socket_server_list_sockets(void)
94289428
break;
94299429
}
94309430

9431-
vim_free(path);
9432-
vim_free(buf);
9431+
vim_free(path.string);
9432+
vim_free(buf.string);
94339433

94349434
ga_append(&str, NUL);
94359435

src/quickfix.c

Lines changed: 13 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -3646,19 +3646,21 @@ qf_jump_print_msg(
36463646
{
36473647
linenr_T i;
36483648
garray_T *gap;
3649+
size_t IObufflen;
36493650

36503651
gap = qfga_get();
36513652

36523653
// Update the screen before showing the message, unless the screen
36533654
// scrolled up.
36543655
if (!msg_scrolled)
36553656
update_topline_redraw();
3656-
vim_snprintf((char *)IObuff, IOSIZE, _("(%d of %d)%s%s: "), qf_index,
3657+
IObufflen = vim_snprintf_safelen((char *)IObuff, IOSIZE,
3658+
_("(%d of %d)%s%s: "), qf_index,
36573659
qf_get_curlist(qi)->qf_count,
36583660
qf_ptr->qf_cleared ? _(" (line deleted)") : "",
36593661
(char *)qf_types(qf_ptr->qf_type, qf_ptr->qf_nr));
36603662
// Add the message, skipping leading whitespace and newlines.
3661-
ga_concat(gap, IObuff);
3663+
ga_concat_len(gap, IObuff, IObufflen);
36623664
qf_fmt_text(gap, skipwhite(qf_ptr->qf_text));
36633665
ga_append(gap, NUL);
36643666

@@ -4126,32 +4128,25 @@ qf_fmt_text(garray_T *gap, char_u *text)
41264128
static void
41274129
qf_range_text(garray_T *gap, qfline_T *qfp)
41284130
{
4129-
char_u *buf = IObuff;
4130-
int bufsize = IOSIZE;
4131-
int len;
4131+
string_T buf = {IObuff, 0};
41324132

4133-
vim_snprintf((char *)buf, bufsize, "%ld", qfp->qf_lnum);
4134-
len = (int)STRLEN(buf);
4133+
buf.length = vim_snprintf_safelen((char *)buf.string, IOSIZE, "%ld", qfp->qf_lnum);
41354134

41364135
if (qfp->qf_end_lnum > 0 && qfp->qf_lnum != qfp->qf_end_lnum)
41374136
{
4138-
vim_snprintf((char *)buf + len, bufsize - len, "-%ld",
4139-
qfp->qf_end_lnum);
4140-
len += (int)STRLEN(buf + len);
4137+
buf.length += vim_snprintf_safelen((char *)buf.string + buf.length,
4138+
IOSIZE - buf.length, "-%ld", qfp->qf_end_lnum);
41414139
}
41424140
if (qfp->qf_col > 0)
41434141
{
4144-
vim_snprintf((char *)buf + len, bufsize - len, " col %d", qfp->qf_col);
4145-
len += (int)STRLEN(buf + len);
4142+
buf.length += vim_snprintf_safelen((char *)buf.string + buf.length,
4143+
IOSIZE - buf.length, " col %d", qfp->qf_col);
41464144
if (qfp->qf_end_col > 0 && qfp->qf_col != qfp->qf_end_col)
4147-
{
4148-
vim_snprintf((char *)buf + len, bufsize - len, "-%d",
4149-
qfp->qf_end_col);
4150-
len += (int)STRLEN(buf + len);
4151-
}
4145+
buf.length += vim_snprintf_safelen((char *)buf.string + buf.length,
4146+
IOSIZE - buf.length, "-%d", qfp->qf_end_col);
41524147
}
41534148

4154-
ga_concat_len(gap, buf, len);
4149+
ga_concat_len(gap, buf.string, buf.length);
41554150
}
41564151

41574152
/*

src/register.c

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -565,10 +565,9 @@ set_execreg_lastc(int lastc)
565565
execreg_line_continuation(string_T *lines, long *idx)
566566
{
567567
garray_T ga;
568-
long i = *idx;
569-
char_u *p;
570-
int cmd_start;
571-
int cmd_end = i;
568+
long cmd_start = *idx;
569+
long cmd_end = *idx;
570+
string_T *tmp;
572571
int j;
573572
char_u *str;
574573

@@ -577,19 +576,24 @@ execreg_line_continuation(string_T *lines, long *idx)
577576
// search backwards to find the first line of this command.
578577
// Any line not starting with \ or "\ is the start of the
579578
// command.
580-
while (--i > 0)
579+
while (--cmd_start > 0)
581580
{
582-
p = skipwhite(lines[i].string);
581+
char_u *p;
582+
583+
p = skipwhite(lines[cmd_start].string);
583584
if (*p != '\\' && (p[0] != '"' || p[1] != '\\' || p[2] != ' '))
584585
break;
585586
}
586-
cmd_start = i;
587587

588588
// join all the lines
589-
ga_concat(&ga, lines[cmd_start].string);
589+
tmp = &lines[cmd_start];
590+
ga_concat_len(&ga, tmp->string, tmp->length);
590591
for (j = cmd_start + 1; j <= cmd_end; j++)
591592
{
592-
p = skipwhite(lines[j].string);
593+
char_u *p;
594+
595+
tmp = &lines[j];
596+
p = skipwhite(tmp->string);
593597
if (*p == '\\')
594598
{
595599
// Adjust the growsize to the current length to
@@ -601,14 +605,15 @@ execreg_line_continuation(string_T *lines, long *idx)
601605
else
602606
ga.ga_growsize = ga.ga_len;
603607
}
604-
ga_concat(&ga, p + 1);
608+
p++;
609+
ga_concat_len(&ga, p, (tmp->string + tmp->length) - p);
605610
}
606611
}
607612
ga_append(&ga, NUL);
608613
str = vim_strnsave(ga.ga_data, ga.ga_len);
609614
ga_clear(&ga);
610615

611-
*idx = i;
616+
*idx = cmd_start;
612617
return str;
613618
}
614619

0 commit comments

Comments
 (0)