[Mesa-dev] [PATCH 04/12] glcpp: Use string_buffer for continuations removal

Vladislav Egorov vegorov180 at gmail.com
Sat Jan 7 19:02:05 UTC 2017


Migrate removal of line continuations to string_buffer. Before this
it used ralloc_strncat() to append strings, which internally
each time calculates strlen() of its argument. Its argument is
entire shader, so it multiple time scans the whole shader text.
---
 src/compiler/glsl/glcpp/glcpp.h | 11 +++++++++--
 src/compiler/glsl/glcpp/pp.c    | 28 +++++++++++++++++++++-------
 2 files changed, 30 insertions(+), 9 deletions(-)

diff --git a/src/compiler/glsl/glcpp/glcpp.h b/src/compiler/glsl/glcpp/glcpp.h
index a9c08e6..34f8b66 100644
--- a/src/compiler/glsl/glcpp/glcpp.h
+++ b/src/compiler/glsl/glcpp/glcpp.h
@@ -275,9 +275,9 @@ glcpp_printf(glcpp_parser_t *parser, struct string_buffer *str,
 
 /* Inlining is necessary to resolve length of literal strings statically */
 static inline bool
-glcpp_append(glcpp_parser_t *parser, struct string_buffer *str, const char *s)
+glcpp_append_length(glcpp_parser_t *parser, struct string_buffer *str,
+		    const char *s, size_t len)
 {
-	size_t len = strlen(s);
 	if (likely(glcpp_strbuffer_ensure_capacity(parser, str, len))) {
 		/* Don't copy null-terminator, str->buf is
 		 * not a null-terminating string
@@ -291,6 +291,13 @@ glcpp_append(glcpp_parser_t *parser, struct string_buffer *str, const char *s)
 }
 
 static inline bool
+glcpp_append(glcpp_parser_t *parser, struct string_buffer *str, const char *s)
+{
+	size_t len = strlen(s);
+	return glcpp_append_length(parser, str, s, len);
+}
+
+static inline bool
 glcpp_append_char(glcpp_parser_t *parser, struct string_buffer *str, char ch)
 {
 	assert(str->capacity > 0 && ch != '\0');
diff --git a/src/compiler/glsl/glcpp/pp.c b/src/compiler/glsl/glcpp/pp.c
index 7fbadf9..af4ec93 100644
--- a/src/compiler/glsl/glcpp/pp.c
+++ b/src/compiler/glsl/glcpp/pp.c
@@ -229,11 +229,16 @@ skip_newline (const char *str)
 static char *
 remove_line_continuations(glcpp_parser_t *ctx, const char *shader)
 {
-	char *clean = ralloc_strdup(ctx, "");
+	struct string_buffer sb;
 	const char *backslash, *newline, *search_start;
         const char *cr, *lf;
         char newline_separator[3];
 	int collapsed_newlines = 0;
+	int separator_len;
+
+	sb.capacity = 4096 - RALLOC_OVERHEAD;
+	sb.buf = ralloc_size(ctx, sb.capacity);
+	sb.length = 0;
 
 	search_start = shader;
 
@@ -273,6 +278,7 @@ remove_line_continuations(glcpp_parser_t *ctx, const char *shader)
 		newline_separator[0] = '\n';
 		newline_separator[1] = '\r';
 	}
+	separator_len = strlen(newline_separator);
 
 	while (true) {
 		backslash = strchr(search_start, '\\');
@@ -294,10 +300,12 @@ remove_line_continuations(glcpp_parser_t *ctx, const char *shader)
 			if (newline &&
 			    (backslash == NULL || newline < backslash))
 			{
-				ralloc_strncat(&clean, shader,
-					       newline - shader + 1);
+				glcpp_append_length(ctx, &sb, shader,
+						    newline - shader + 1);
 				while (collapsed_newlines) {
-					ralloc_strcat(&clean, newline_separator);
+					glcpp_append_length(ctx, &sb,
+							    newline_separator,
+							    separator_len);
 					collapsed_newlines--;
 				}
 				shader = skip_newline (newline);
@@ -318,15 +326,21 @@ remove_line_continuations(glcpp_parser_t *ctx, const char *shader)
 		if (backslash[1] == '\r' || backslash[1] == '\n')
 		{
 			collapsed_newlines++;
-			ralloc_strncat(&clean, shader, backslash - shader);
+			glcpp_append_length(ctx, &sb, shader,
+					    backslash - shader);
 			shader = skip_newline (backslash + 1);
 			search_start = shader;
 		}
 	}
 
-	ralloc_strcat(&clean, shader);
+	glcpp_append(ctx, &sb, shader);
+
+	/* string_buffer's string is not null-terminated, but it has enough
+	 * of space for '\0'. Don't forget to put null-terminator.
+	 */
+	sb.buf[sb.length] = '\0';
 
-	return clean;
+	return sb.buf;
 }
 
 int
-- 
2.7.4



More information about the mesa-dev mailing list