[Mesa-dev] [PATCH 2/2] glcpp: Don't strlen() the output for every token being printed.

Kenneth Graunke kenneth at whitecape.org
Tue Feb 21 13:38:50 PST 2012


The ralloc string appending functions were originally intended for
simple, non-hot-path uses like printing to an info log.

Cuts Unigine Tropics load time by around 20% (6 seconds).

Signed-off-by: Kenneth Graunke <kenneth at whitecape.org>
---
 src/glsl/glcpp/glcpp-parse.y |   48 ++++++++++++++++++++++-------------------
 src/glsl/glcpp/glcpp.h       |    2 +
 2 files changed, 28 insertions(+), 22 deletions(-)

It would be far nicer if we had a string class that stored the length and
had asprintf_append-style methods.  Like csString in Crystal Space.  But
that's a more invasive change, I think.  STL has the ostringstream class
for this exact purpose, but that would require rewriting everything to use
C++ style IO, and I'm loathe to do that (mostly because we don't use it
anywhere else).

diff --git a/src/glsl/glcpp/glcpp-parse.y b/src/glsl/glcpp/glcpp-parse.y
index efcc205..137e97b 100644
--- a/src/glsl/glcpp/glcpp-parse.y
+++ b/src/glsl/glcpp/glcpp-parse.y
@@ -185,10 +185,12 @@ input:
 line:
 	control_line {
 		ralloc_strcat (&parser->output, "\n");
+		++parser->output_length;
 	}
 |	text_line {
 		_glcpp_parser_print_expanded_token_list (parser, $1);
 		ralloc_strcat (&parser->output, "\n");
+		++parser->output_length;
 		ralloc_free ($1);
 	}
 |	expanded_line
@@ -320,7 +322,7 @@ control_line:
 		if ($2 >= 130 || $2 == 100)
 			add_builtin_define (parser, "GL_FRAGMENT_PRECISION_HIGH", 1);
 
-		ralloc_asprintf_append (&parser->output, "#version %" PRIiMAX, $2);
+		ralloc_asprintf_rewrite_tail (&parser->output, &parser->output_length, "#version %" PRIiMAX, $2);
 	}
 |	HASH NEWLINE
 ;
@@ -903,54 +905,54 @@ _token_list_equal_ignoring_space (token_list_t *a, token_list_t *b)
 }
 
 static void
-_token_print (char **out, token_t *token)
+_token_print (char **out, size_t *len, token_t *token)
 {
 	if (token->type < 256) {
-		ralloc_asprintf_append (out, "%c", token->type);
+		ralloc_asprintf_rewrite_tail (out, len, "%c", token->type);
 		return;
 	}
 
 	switch (token->type) {
 	case INTEGER:
-		ralloc_asprintf_append (out, "%" PRIiMAX, token->value.ival);
+		ralloc_asprintf_rewrite_tail (out, len, "%" PRIiMAX, token->value.ival);
 		break;
 	case IDENTIFIER:
 	case INTEGER_STRING:
 	case OTHER:
-		ralloc_strcat (out, token->value.str);
+		ralloc_asprintf_rewrite_tail (out, len, "%s", token->value.str);
 		break;
 	case SPACE:
-		ralloc_strcat (out, " ");
+		ralloc_asprintf_rewrite_tail (out, len, " ");
 		break;
 	case LEFT_SHIFT:
-		ralloc_strcat (out, "<<");
+		ralloc_asprintf_rewrite_tail (out, len, "<<");
 		break;
 	case RIGHT_SHIFT:
-		ralloc_strcat (out, ">>");
+		ralloc_asprintf_rewrite_tail (out, len, ">>");
 		break;
 	case LESS_OR_EQUAL:
-		ralloc_strcat (out, "<=");
+		ralloc_asprintf_rewrite_tail (out, len, "<=");
 		break;
 	case GREATER_OR_EQUAL:
-		ralloc_strcat (out, ">=");
+		ralloc_asprintf_rewrite_tail (out, len, ">=");
 		break;
 	case EQUAL:
-		ralloc_strcat (out, "==");
+		ralloc_asprintf_rewrite_tail (out, len, "==");
 		break;
 	case NOT_EQUAL:
-		ralloc_strcat (out, "!=");
+		ralloc_asprintf_rewrite_tail (out, len, "!=");
 		break;
 	case AND:
-		ralloc_strcat (out, "&&");
+		ralloc_asprintf_rewrite_tail (out, len, "&&");
 		break;
 	case OR:
-		ralloc_strcat (out, "||");
+		ralloc_asprintf_rewrite_tail (out, len, "||");
 		break;
 	case PASTE:
-		ralloc_strcat (out, "##");
+		ralloc_asprintf_rewrite_tail (out, len, "##");
 		break;
 	case COMMA_FINAL:
-		ralloc_strcat (out, ",");
+		ralloc_asprintf_rewrite_tail (out, len, ",");
 		break;
 	case PLACEHOLDER:
 		/* Nothing to print. */
@@ -1040,11 +1042,11 @@ _token_paste (glcpp_parser_t *parser, token_t *token, token_t *other)
 	}
 
 	glcpp_error (&token->location, parser, "");
-	ralloc_strcat (&parser->info_log, "Pasting \"");
-	_token_print (&parser->info_log, token);
-	ralloc_strcat (&parser->info_log, "\" and \"");
-	_token_print (&parser->info_log, other);
-	ralloc_strcat (&parser->info_log, "\" does not give a valid preprocessing token.\n");
+	ralloc_asprintf_rewrite_tail (&parser->info_log, &parser->info_log_length, "Pasting \"");
+	_token_print (&parser->info_log, &parser->info_log_length, token);
+	ralloc_asprintf_rewrite_tail (&parser->info_log, &parser->info_log_length, "\" and \"");
+	_token_print (&parser->info_log, &parser->info_log_length, other);
+	ralloc_asprintf_rewrite_tail (&parser->info_log, &parser->info_log_length, "\" does not give a valid preprocessing token.\n");
 
 	return token;
 }
@@ -1058,7 +1060,7 @@ _token_list_print (glcpp_parser_t *parser, token_list_t *list)
 		return;
 
 	for (node = list->head; node; node = node->next)
-		_token_print (&parser->output, node->token);
+		_token_print (&parser->output, &parser->output_length, node->token);
 }
 
 void
@@ -1104,7 +1106,9 @@ glcpp_parser_create (const struct gl_extensions *extensions, int api)
 	parser->lex_from_node = NULL;
 
 	parser->output = ralloc_strdup(parser, "");
+	parser->output_length = 0;
 	parser->info_log = ralloc_strdup(parser, "");
+	parser->info_log_length = 0;
 	parser->error = 0;
 
 	/* Add pre-defined macros. */
diff --git a/src/glsl/glcpp/glcpp.h b/src/glsl/glcpp/glcpp.h
index dc816e9..2d7cad2 100644
--- a/src/glsl/glcpp/glcpp.h
+++ b/src/glsl/glcpp/glcpp.h
@@ -174,6 +174,8 @@ struct glcpp_parser {
 	token_node_t *lex_from_node;
 	char *output;
 	char *info_log;
+	size_t output_length;
+	size_t info_log_length;
 	int error;
 };
 
-- 
1.7.7.6



More information about the mesa-dev mailing list