Module Name: src Committed By: rillig Date: Sun Apr 11 19:05:06 UTC 2021
Modified Files: src/usr.bin/make: str.c str.h var.c Log Message: make: avoid unnecessary calls to strlen when evaluating modifiers No functional change. To generate a diff of this commit: cvs rdiff -u -r1.83 -r1.84 src/usr.bin/make/str.c cvs rdiff -u -r1.2 -r1.3 src/usr.bin/make/str.h cvs rdiff -u -r1.919 -r1.920 src/usr.bin/make/var.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/usr.bin/make/str.c diff -u src/usr.bin/make/str.c:1.83 src/usr.bin/make/str.c:1.84 --- src/usr.bin/make/str.c:1.83 Sat Apr 3 14:39:02 2021 +++ src/usr.bin/make/str.c Sun Apr 11 19:05:06 2021 @@ -1,4 +1,4 @@ -/* $NetBSD: str.c,v 1.83 2021/04/03 14:39:02 rillig Exp $ */ +/* $NetBSD: str.c,v 1.84 2021/04/11 19:05:06 rillig Exp $ */ /* * Copyright (c) 1988, 1989, 1990, 1993 @@ -71,7 +71,7 @@ #include "make.h" /* "@(#)str.c 5.8 (Berkeley) 6/1/90" */ -MAKE_RCSID("$NetBSD: str.c,v 1.83 2021/04/03 14:39:02 rillig Exp $"); +MAKE_RCSID("$NetBSD: str.c,v 1.84 2021/04/11 19:05:06 rillig Exp $"); /* Return the concatenation of s1 and s2, freshly allocated. */ char * @@ -125,13 +125,13 @@ str_concat4(const char *s1, const char * * Returns the fractured words, which must be freed later using Words_Free, * unless the returned Words.words was NULL. */ -Words -Str_Words(const char *str, bool expand) +SubstringWords +Substring_Words(const char *str, bool expand) { size_t str_len; char *words_buf; size_t words_cap; - char **words; + Substring *words; size_t words_len; char inquote; char *word_start; @@ -146,7 +146,7 @@ Str_Words(const char *str, bool expand) words_buf = bmake_malloc(str_len + 1); words_cap = str_len / 5 > 50 ? str_len / 5 : 50; - words = bmake_malloc((words_cap + 1) * sizeof(char *)); + words = bmake_malloc((words_cap + 1) * sizeof(words[0])); /* * copy the string; at the same time, parse backslashes, @@ -205,15 +205,16 @@ Str_Words(const char *str, bool expand) *word_end++ = '\0'; if (words_len == words_cap) { size_t new_size; - words_cap *= 2; /* ramp up fast */ - new_size = (words_cap + 1) * sizeof(char *); + words_cap *= 2; + new_size = (words_cap + 1) * sizeof(words[0]); words = bmake_realloc(words, new_size); } - words[words_len++] = word_start; + words[words_len++] = + Substring_Init(word_start, word_end - 1); word_start = NULL; if (ch == '\n' || ch == '\0') { if (expand && inquote != '\0') { - Words res; + SubstringWords res; free(words); free(words_buf); @@ -268,10 +269,10 @@ Str_Words(const char *str, bool expand) *word_end++ = ch; } done: - words[words_len] = NULL; /* useful for argv */ + words[words_len] = Substring_Init(NULL, NULL); /* useful for argv */ { - Words result; + SubstringWords result; result.words = words; result.len = words_len; @@ -280,6 +281,30 @@ done: } } +Words +Str_Words(const char *str, bool expand) +{ + SubstringWords swords; + Words words; + size_t i; + + swords = Substring_Words(str, expand); + if (swords.words == NULL) { + words.words = NULL; + words.len = 0; + words.freeIt = NULL; + return words; + } + + words.words = bmake_malloc((swords.len + 1) * sizeof(words.words[0])); + words.len = swords.len; + words.freeIt = swords.freeIt; + for (i = 0; i < swords.len + 1; i++) + words.words[i] = UNCONST(swords.words[i].start); + free(swords.words); + return words; +} + /* * Str_Match -- Test if a string matches a pattern like "*.[ch]". * The following special characters are known *?\[] (as in fnmatch(3)). Index: src/usr.bin/make/str.h diff -u src/usr.bin/make/str.h:1.2 src/usr.bin/make/str.h:1.3 --- src/usr.bin/make/str.h:1.2 Sun Apr 11 18:44:57 2021 +++ src/usr.bin/make/str.h Sun Apr 11 19:05:06 2021 @@ -1,4 +1,4 @@ -/* $NetBSD: str.h,v 1.2 2021/04/11 18:44:57 rillig Exp $ */ +/* $NetBSD: str.h,v 1.3 2021/04/11 19:05:06 rillig Exp $ */ /* Copyright (c) 2021 Roland Illig <ril...@netbsd.org> @@ -70,6 +70,13 @@ typedef struct Words { void *freeIt; } Words; +/* The result of splitting a string into words. */ +typedef struct SubstringWords { + Substring *words; + size_t len; + void *freeIt; +} SubstringWords; + MAKE_INLINE FStr FStr_Init(const char *str, void *freeIt) @@ -301,6 +308,16 @@ Words_Free(Words w) } +SubstringWords Substring_Words(const char *, bool); + +MAKE_INLINE void +SubstringWords_Free(SubstringWords w) +{ + free(w.words); + free(w.freeIt); +} + + char *str_concat2(const char *, const char *); char *str_concat3(const char *, const char *, const char *); char *str_concat4(const char *, const char *, const char *, const char *); Index: src/usr.bin/make/var.c diff -u src/usr.bin/make/var.c:1.919 src/usr.bin/make/var.c:1.920 --- src/usr.bin/make/var.c:1.919 Sun Apr 11 18:44:57 2021 +++ src/usr.bin/make/var.c Sun Apr 11 19:05:06 2021 @@ -1,4 +1,4 @@ -/* $NetBSD: var.c,v 1.919 2021/04/11 18:44:57 rillig Exp $ */ +/* $NetBSD: var.c,v 1.920 2021/04/11 19:05:06 rillig Exp $ */ /* * Copyright (c) 1988, 1989, 1990, 1993 @@ -140,7 +140,7 @@ #include "metachar.h" /* "@(#)var.c 8.3 (Berkeley) 3/19/94" */ -MAKE_RCSID("$NetBSD: var.c,v 1.919 2021/04/11 18:44:57 rillig Exp $"); +MAKE_RCSID("$NetBSD: var.c,v 1.920 2021/04/11 19:05:06 rillig Exp $"); /* * Variables are defined using one of the VAR=value assignments. Their @@ -2461,7 +2461,7 @@ ModifyWords(ModChain *ch, Expr *expr = ch->expr; const char *val = expr->value.str; SepBuf result; - Words words; + SubstringWords words; size_t i; Substring word; @@ -2473,21 +2473,19 @@ ModifyWords(ModChain *ch, goto done; } - words = Str_Words(val, false); + words = Substring_Words(val, false); DEBUG2(VAR, "ModifyWords: split \"%s\" into %u words\n", val, (unsigned)words.len); SepBuf_Init(&result, ch->sep); for (i = 0; i < words.len; i++) { - /* XXX: performance: Substring_InitStr calls strlen */ - word = Substring_InitStr(words.words[i]); - modifyWord(word, &result, modifyWord_args); + modifyWord(words.words[i], &result, modifyWord_args); if (result.buf.len > 0) SepBuf_Sep(&result); } - Words_Free(words); + SubstringWords_Free(words); done: Expr_SetValueOwn(expr, SepBuf_DoneData(&result));