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));

Reply via email to