[Mesa-dev] [PATCH 07/15] glcpp: use the linear allocator for most objects

Marek Olšák maraeo at gmail.com
Sat Oct 8 10:58:31 UTC 2016


From: Marek Olšák <marek.olsak at amd.com>

---
 src/compiler/glsl/glcpp/glcpp-lex.l   |   2 +-
 src/compiler/glsl/glcpp/glcpp-parse.y | 203 +++++++++++++++-------------------
 src/compiler/glsl/glcpp/glcpp.h       |   1 +
 3 files changed, 94 insertions(+), 112 deletions(-)

diff --git a/src/compiler/glsl/glcpp/glcpp-lex.l b/src/compiler/glsl/glcpp/glcpp-lex.l
index d09441a..f4a6876 100644
--- a/src/compiler/glsl/glcpp/glcpp-lex.l
+++ b/src/compiler/glsl/glcpp/glcpp-lex.l
@@ -94,21 +94,21 @@ void glcpp_set_column (int  column_no , yyscan_t yyscanner);
 #define RETURN_TOKEN(token)						\
 	do {								\
 		if (! parser->skipping) {				\
 			RETURN_TOKEN_NEVER_SKIP(token);			\
 		}							\
 	} while(0)
 
 #define RETURN_STRING_TOKEN(token)					\
 	do {								\
 		if (! parser->skipping) {				\
-			yylval->str = ralloc_strdup (yyextra, yytext);	\
+			yylval->str = linear_strdup(yyextra->linalloc, yytext);	\
 			RETURN_TOKEN_NEVER_SKIP (token);		\
 		}							\
 	} while(0)
 
 
 /* Update all state necessary for each token being returned.
  *
  * Here we'll be tracking newlines and spaces so that the lexer can
  * alter its behavior as necessary, (for example, '#' has special
  * significance if it is the first non-whitespace, non-comment token
diff --git a/src/compiler/glsl/glcpp/glcpp-parse.y b/src/compiler/glsl/glcpp/glcpp-parse.y
index 4fd1448..d2081b3 100644
--- a/src/compiler/glsl/glcpp/glcpp-parse.y
+++ b/src/compiler/glsl/glcpp/glcpp-parse.y
@@ -42,61 +42,62 @@ _define_object_macro(glcpp_parser_t *parser,
                      token_list_t *replacements);
 
 static void
 _define_function_macro(glcpp_parser_t *parser,
                        YYLTYPE *loc,
                        const char *macro,
                        string_list_t *parameters,
                        token_list_t *replacements);
 
 static string_list_t *
-_string_list_create(void *ctx);
+_string_list_create(glcpp_parser_t *parser);
 
 static void
-_string_list_append_item(string_list_t *list, const char *str);
+_string_list_append_item(glcpp_parser_t *parser, string_list_t *list,
+                         const char *str);
 
 static int
 _string_list_contains(string_list_t *list, const char *member, int *index);
 
 static const char *
 _string_list_has_duplicate(string_list_t *list);
 
 static int
 _string_list_length(string_list_t *list);
 
 static int
 _string_list_equal(string_list_t *a, string_list_t *b);
 
 static argument_list_t *
-_argument_list_create(void *ctx);
+_argument_list_create(glcpp_parser_t *parser);
 
 static void
-_argument_list_append(argument_list_t *list, token_list_t *argument);
+_argument_list_append(glcpp_parser_t *parser, argument_list_t *list,
+                      token_list_t *argument);
 
 static int
 _argument_list_length(argument_list_t *list);
 
 static token_list_t *
 _argument_list_member_at(argument_list_t *list, int index);
 
-/* Note: This function ralloc_steal()s the str pointer. */
 static token_t *
-_token_create_str(void *ctx, int type, char *str);
+_token_create_str(glcpp_parser_t *parser, int type, char *str);
 
 static token_t *
-_token_create_ival(void *ctx, int type, int ival);
+_token_create_ival(glcpp_parser_t *parser, int type, int ival);
 
 static token_list_t *
-_token_list_create(void *ctx);
+_token_list_create(glcpp_parser_t *parser);
 
 static void
-_token_list_append(token_list_t *list, token_t *token);
+_token_list_append(glcpp_parser_t *parser, token_list_t *list, token_t *token);
 
 static void
 _token_list_append_list(token_list_t *list, token_list_t *tail);
 
 static int
 _token_list_equal_ignoring_space(token_list_t *a, token_list_t *b);
 
 static void
 _parser_active_list_push(glcpp_parser_t *parser, const char *identifier,
                          token_node_t *marker);
@@ -202,21 +203,20 @@ input:
 	/* empty */
 |	input line
 ;
 
 line:
 	control_line
 |	SPACE control_line
 |	text_line {
 		_glcpp_parser_print_expanded_token_list (parser, $1);
 		ralloc_asprintf_rewrite_tail (&parser->output, &parser->output_length, "\n");
-		ralloc_free ($1);
 	}
 |	expanded_line
 ;
 
 expanded_line:
 	IF_EXPANDED expression NEWLINE {
 		if (parser->is_gles && $2.undefined_macro)
 			glcpp_error(& @1, parser, "undefined macro %s in expression (illegal in GLES)", $2.undefined_macro);
 		_glcpp_parser_skip_stack_push_if (parser, & @1, $2.value);
 	}
@@ -270,21 +270,20 @@ control_line:
 			_glcpp_parser_expand_and_lex_from (parser,
 							   LINE_EXPANDED, $3,
 							   EXPANSION_MODE_IGNORE_DEFINED);
 		}
 	}
 ;
 
 control_line_success:
 	HASH_TOKEN DEFINE_TOKEN define
 |	HASH_TOKEN UNDEF IDENTIFIER NEWLINE {
-		macro_t *macro;
 		struct hash_entry *entry;
 
                 /* Section 3.4 (Preprocessor) of the GLSL ES 3.00 spec says:
                  *
                  *    It is an error to undefine or to redefine a built-in
                  *    (pre-defined) macro name.
                  *
                  * The GLSL ES 1.00 spec does not contain this text.
                  *
                  * Section 3.3 (Preprocessor) of the GLSL 1.30 spec says:
@@ -305,25 +304,22 @@ control_line_success:
                     parser->version >= 300 &&
                     (strcmp("__LINE__", $3) == 0
                      || strcmp("__FILE__", $3) == 0
                      || strcmp("__VERSION__", $3) == 0
                      || strncmp("GL_", $3, 3) == 0))
 			glcpp_error(& @1, parser, "Built-in (pre-defined)"
 				    " macro names cannot be undefined.");
 
 		entry = _mesa_hash_table_search (parser->defines, $3);
 		if (entry) {
-			macro = entry->data;
 			_mesa_hash_table_remove (parser->defines, entry);
-			ralloc_free (macro);
 		}
-		ralloc_free ($3);
 	}
 |	HASH_TOKEN IF pp_tokens NEWLINE {
 		/* Be careful to only evaluate the 'if' expression if
 		 * we are not skipping. When we are skipping, we
 		 * simply push a new 0-valued 'if' onto the skip
 		 * stack.
 		 *
 		 * This avoids generating diagnostics for invalid
 		 * expressions that are being skipped. */
 		if (parser->skip_stack == NULL ||
@@ -346,21 +342,20 @@ control_line_success:
 		    parser->skip_stack->type == SKIP_NO_SKIP)
 		{
 			glcpp_error(& @1, parser, "#if with no expression");
 		}	
 		_glcpp_parser_skip_stack_push_if (parser, & @1, 0);
 	}
 |	HASH_TOKEN IFDEF IDENTIFIER junk NEWLINE {
 		struct hash_entry *entry =
 				_mesa_hash_table_search(parser->defines, $3);
 		macro_t *macro = entry ? entry->data : NULL;
-		ralloc_free ($3);
 		_glcpp_parser_skip_stack_push_if (parser, & @1, macro != NULL);
 	}
 |	HASH_TOKEN IFNDEF IDENTIFIER junk NEWLINE {
 		struct hash_entry *entry =
 				_mesa_hash_table_search(parser->defines, $3);
 		macro_t *macro = entry ? entry->data : NULL;
 		_glcpp_parser_skip_stack_push_if (parser, & @3, macro == NULL);
 	}
 |	HASH_TOKEN ELIF pp_tokens NEWLINE {
 		/* Be careful to only evaluate the 'elif' expression
@@ -471,21 +466,21 @@ integer_constant:
 	}
 
 expression:
 	integer_constant {
 		$$.value = $1;
 		$$.undefined_macro = NULL;
 	}
 |	IDENTIFIER {
 		$$.value = 0;
 		if (parser->is_gles)
-			$$.undefined_macro = ralloc_strdup (parser, $1);
+			$$.undefined_macro = linear_strdup(parser->linalloc, $1);
 		else
 			$$.undefined_macro = NULL;
 	}
 |	expression OR expression {
 		$$.value = $1.value || $3.value;
 
 		/* Short-circuit: Only flag undefined from right side
 		 * if left side evaluates to false.
 		 */
 		if ($1.undefined_macro)
@@ -643,27 +638,25 @@ expression:
 		$$.undefined_macro = $2.undefined_macro;
 	}
 |	'(' expression ')' {
 		$$ = $2;
 	}
 ;
 
 identifier_list:
 	IDENTIFIER {
 		$$ = _string_list_create (parser);
-		_string_list_append_item ($$, $1);
-		ralloc_steal ($$, $1);
+		_string_list_append_item (parser, $$, $1);
 	}
 |	identifier_list ',' IDENTIFIER {
 		$$ = $1;	
-		_string_list_append_item ($$, $3);
-		ralloc_steal ($$, $3);
+		_string_list_append_item (parser, $$, $3);
 	}
 ;
 
 text_line:
 	NEWLINE { $$ = NULL; }
 |	pp_tokens NEWLINE
 ;
 
 replacement_list:
 	/* empty */ { $$ = NULL; }
@@ -674,25 +667,25 @@ junk:
 	/* empty */
 |	pp_tokens {
 		glcpp_error(&@1, parser, "extra tokens at end of directive");
 	}
 ;
 
 pp_tokens:
 	preprocessing_token {
 		parser->space_tokens = 1;
 		$$ = _token_list_create (parser);
-		_token_list_append ($$, $1);
+		_token_list_append (parser, $$, $1);
 	}
 |	pp_tokens preprocessing_token {
 		$$ = $1;
-		_token_list_append ($$, $2);
+		_token_list_append (parser, $$, $2);
 	}
 ;
 
 preprocessing_token:
 	IDENTIFIER {
 		$$ = _token_create_str (parser, IDENTIFIER, $1);
 		$$->location = yylloc;
 	}
 |	INTEGER_STRING {
 		$$ = _token_create_str (parser, INTEGER_STRING, $1);
@@ -748,38 +741,39 @@ operator:
 |	','			{ $$ = ','; }
 |	'='			{ $$ = '='; }
 |	PASTE			{ $$ = PASTE; }
 |	PLUS_PLUS		{ $$ = PLUS_PLUS; }
 |	MINUS_MINUS		{ $$ = MINUS_MINUS; }
 ;
 
 %%
 
 string_list_t *
-_string_list_create(void *ctx)
+_string_list_create(glcpp_parser_t *parser)
 {
    string_list_t *list;
 
-   list = ralloc (ctx, string_list_t);
+   list = linear_alloc_child(parser->linalloc, sizeof(string_list_t));
    list->head = NULL;
    list->tail = NULL;
 
    return list;
 }
 
 void
-_string_list_append_item(string_list_t *list, const char *str)
+_string_list_append_item(glcpp_parser_t *parser, string_list_t *list,
+                         const char *str)
 {
    string_node_t *node;
 
-   node = ralloc (list, string_node_t);
-   node->str = ralloc_strdup (node, str);
+   node = linear_alloc_child(parser->linalloc, sizeof(string_node_t));
+   node->str = linear_strdup(parser->linalloc, str);
 
    node->next = NULL;
 
    if (list->head == NULL) {
       list->head = node;
    } else {
       list->tail->next = node;
    }
 
    list->tail = node;
@@ -858,37 +852,38 @@ _string_list_equal(string_list_t *a, string_list_t *b)
          return 0;
    }
 
    /* Catch the case of lists being different lengths, (which
     * would cause the loop above to terminate after the shorter
     * list). */
    return node_a == node_b;
 }
 
 argument_list_t *
-_argument_list_create(void *ctx)
+_argument_list_create(glcpp_parser_t *parser)
 {
    argument_list_t *list;
 
-   list = ralloc (ctx, argument_list_t);
+   list = linear_alloc_child(parser->linalloc, sizeof(argument_list_t));
    list->head = NULL;
    list->tail = NULL;
 
    return list;
 }
 
 void
-_argument_list_append(argument_list_t *list, token_list_t *argument)
+_argument_list_append(glcpp_parser_t *parser,
+                      argument_list_t *list, token_list_t *argument)
 {
    argument_node_t *node;
 
-   node = ralloc (list, argument_node_t);
+   node = linear_alloc_child(parser->linalloc, sizeof(argument_node_t));
    node->argument = argument;
 
    node->next = NULL;
 
    if (list->head == NULL) {
       list->head = node;
    } else {
       list->tail->next = node;
    }
 
@@ -925,66 +920,63 @@ _argument_list_member_at(argument_list_t *list, int index)
       if (node == NULL)
          break;
    }
 
    if (node)
       return node->argument;
 
    return NULL;
 }
 
-/* Note: This function ralloc_steal()s the str pointer. */
 token_t *
-_token_create_str(void *ctx, int type, char *str)
+_token_create_str(glcpp_parser_t *parser, int type, char *str)
 {
    token_t *token;
 
-   token = ralloc (ctx, token_t);
+   token = linear_alloc_child(parser->linalloc, sizeof(token_t));
    token->type = type;
    token->value.str = str;
 
-   ralloc_steal (token, str);
-
    return token;
 }
 
 token_t *
-_token_create_ival(void *ctx, int type, int ival)
+_token_create_ival(glcpp_parser_t *parser, int type, int ival)
 {
    token_t *token;
 
-   token = ralloc (ctx, token_t);
+   token = linear_alloc_child(parser->linalloc, sizeof(token_t));
    token->type = type;
    token->value.ival = ival;
 
    return token;
 }
 
 token_list_t *
-_token_list_create(void *ctx)
+_token_list_create(glcpp_parser_t *parser)
 {
    token_list_t *list;
 
-   list = ralloc (ctx, token_list_t);
+   list = linear_alloc_child(parser->linalloc, sizeof(token_list_t));
    list->head = NULL;
    list->tail = NULL;
    list->non_space_tail = NULL;
 
    return list;
 }
 
 void
-_token_list_append(token_list_t *list, token_t *token)
+_token_list_append(glcpp_parser_t *parser, token_list_t *list, token_t *token)
 {
    token_node_t *node;
 
-   node = ralloc (list, token_node_t);
+   node = linear_alloc_child(parser->linalloc, sizeof(token_node_t));
    node->token = token;
    node->next = NULL;
 
    if (list->head == NULL) {
       list->head = node;
    } else {
       list->tail->next = node;
    }
 
    list->tail = node;
@@ -1002,51 +994,50 @@ _token_list_append_list(token_list_t *list, token_list_t *tail)
       list->head = tail->head;
    } else {
       list->tail->next = tail->head;
    }
 
    list->tail = tail->tail;
    list->non_space_tail = tail->non_space_tail;
 }
 
 static token_list_t *
-_token_list_copy(void *ctx, token_list_t *other)
+_token_list_copy(glcpp_parser_t *parser, token_list_t *other)
 {
    token_list_t *copy;
    token_node_t *node;
 
    if (other == NULL)
       return NULL;
 
-   copy = _token_list_create (ctx);
+   copy = _token_list_create (parser);
    for (node = other->head; node; node = node->next) {
-      token_t *new_token = ralloc (copy, token_t);
+      token_t *new_token = linear_alloc_child(parser->linalloc, sizeof(token_t));
       *new_token = *node->token;
-      _token_list_append (copy, new_token);
+      _token_list_append (parser, copy, new_token);
    }
 
    return copy;
 }
 
 static void
 _token_list_trim_trailing_space(token_list_t *list)
 {
    token_node_t *tail, *next;
 
    if (list->non_space_tail) {
       tail = list->non_space_tail->next;
       list->non_space_tail->next = NULL;
       list->tail = list->non_space_tail;
 
       while (tail) {
          next = tail->next;
-         ralloc_free (tail);
          tail = next;
       }
    }
 }
 
 static int
 _token_list_is_empty_ignoring_space(token_list_t *l)
 {
    token_node_t *n;
 
@@ -1177,69 +1168,70 @@ _token_print(char **out, size_t *len, token_t *token)
    case PLACEHOLDER:
       /* Nothing to print. */
       break;
    default:
       assert(!"Error: Don't know how to print token.");
 
       break;
    }
 }
 
-/* Return a new token (ralloc()ed off of 'token') formed by pasting
- * 'token' and 'other'. Note that this function may return 'token' or
- * 'other' directly rather than allocating anything new.
+/* Return a new token formed by pasting 'token' and 'other'. Note that this
+ * function may return 'token' or 'other' directly rather than allocating
+ * anything new.
  *
  * Caution: Only very cursory error-checking is performed to see if
  * the final result is a valid single token. */
 static token_t *
-_token_paste(glcpp_parser_t *parser, token_t *token, token_t *other)
+_token_paste(glcpp_parser_t *parser, token_list_t *list, token_t *token,
+             token_t *other)
 {
    token_t *combined = NULL;
 
    /* Pasting a placeholder onto anything makes no change. */
    if (other->type == PLACEHOLDER)
       return token;
 
    /* When 'token' is a placeholder, just return 'other'. */
    if (token->type == PLACEHOLDER)
       return other;
 
    /* A very few single-character punctuators can be combined
     * with another to form a multi-character punctuator. */
    switch (token->type) {
    case '<':
       if (other->type == '<')
-         combined = _token_create_ival (token, LEFT_SHIFT, LEFT_SHIFT);
+         combined = _token_create_ival (parser, LEFT_SHIFT, LEFT_SHIFT);
       else if (other->type == '=')
-         combined = _token_create_ival (token, LESS_OR_EQUAL, LESS_OR_EQUAL);
+         combined = _token_create_ival (parser, LESS_OR_EQUAL, LESS_OR_EQUAL);
       break;
    case '>':
       if (other->type == '>')
-         combined = _token_create_ival (token, RIGHT_SHIFT, RIGHT_SHIFT);
+         combined = _token_create_ival (parser, RIGHT_SHIFT, RIGHT_SHIFT);
       else if (other->type == '=')
-         combined = _token_create_ival (token, GREATER_OR_EQUAL, GREATER_OR_EQUAL);
+         combined = _token_create_ival (parser, GREATER_OR_EQUAL, GREATER_OR_EQUAL);
       break;
    case '=':
       if (other->type == '=')
-         combined = _token_create_ival (token, EQUAL, EQUAL);
+         combined = _token_create_ival (parser, EQUAL, EQUAL);
       break;
    case '!':
       if (other->type == '=')
-         combined = _token_create_ival (token, NOT_EQUAL, NOT_EQUAL);
+         combined = _token_create_ival (parser, NOT_EQUAL, NOT_EQUAL);
       break;
    case '&':
       if (other->type == '&')
-         combined = _token_create_ival (token, AND, AND);
+         combined = _token_create_ival (parser, AND, AND);
       break;
    case '|':
       if (other->type == '|')
-         combined = _token_create_ival (token, OR, OR);
+         combined = _token_create_ival (parser, OR, OR);
       break;
    }
 
    if (combined != NULL) {
       /* Inherit the location from the first token */
       combined->location = token->location;
       return combined;
    }
 
    /* Two string-valued (or integer) tokens can usually just be
@@ -1269,37 +1261,37 @@ _token_paste(glcpp_parser_t *parser, token_t *token, token_t *other)
          case INTEGER:
             if (other->value.ival < 0)
                goto FAIL;
             break;
          default:
             goto FAIL;
          }
       }
 
       if (token->type == INTEGER)
-         str = ralloc_asprintf (token, "%" PRIiMAX, token->value.ival);
+         str = linear_asprintf(parser->linalloc, "%" PRIiMAX, token->value.ival);
       else
-         str = ralloc_strdup (token, token->value.str);
+         str = linear_strdup(parser->linalloc, token->value.str);
 
       if (other->type == INTEGER)
-         ralloc_asprintf_append (&str, "%" PRIiMAX, other->value.ival);
+         linear_asprintf_append(parser->linalloc, &str, "%" PRIiMAX, other->value.ival);
       else
-         ralloc_strcat (&str, other->value.str);
+         linear_strcat(parser->linalloc, &str, other->value.str);
 
       /* New token is same type as original token, unless we
        * started with an integer, in which case we will be
        * creating an integer-string. */
       combined_type = token->type;
       if (combined_type == INTEGER)
          combined_type = INTEGER_STRING;
 
-      combined = _token_create_str (token, combined_type, str);
+      combined = _token_create_str (parser, combined_type, str);
       combined->location = token->location;
       return combined;
    }
 
     FAIL:
    glcpp_error (&token->location, parser, "");
    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);
@@ -1328,34 +1320,35 @@ yyerror(YYLTYPE *locp, glcpp_parser_t *parser, const char *error)
 
 static void
 add_builtin_define(glcpp_parser_t *parser, const char *name, int value)
 {
    token_t *tok;
    token_list_t *list;
 
    tok = _token_create_ival (parser, INTEGER, value);
 
    list = _token_list_create(parser);
-   _token_list_append(list, tok);
+   _token_list_append(parser, list, tok);
    _define_object_macro(parser, NULL, name, list);
 }
 
 glcpp_parser_t *
 glcpp_parser_create(glcpp_extension_iterator extensions, void *state, gl_api api)
 {
    glcpp_parser_t *parser;
 
    parser = ralloc (NULL, glcpp_parser_t);
 
    glcpp_lex_init_extra (parser, &parser->scanner);
    parser->defines = _mesa_hash_table_create(NULL, _mesa_key_hash_string,
                                              _mesa_key_string_equal);
+   parser->linalloc = linear_alloc_parent(parser, 0);
    parser->active = NULL;
    parser->lexing_directive = 0;
    parser->space_tokens = 1;
    parser->last_token_was_newline = 0;
    parser->last_token_was_space = 0;
    parser->first_non_space_token_this_line = 1;
    parser->newline_as_space = 0;
    parser->in_control_line = 0;
    parser->paren_count = 0;
    parser->commented_newlines = 0;
@@ -1417,94 +1410,95 @@ typedef enum function_status
  *   FUNCTION_NOT_A_FUNCTION:
  *
  *      Macro name not followed by a '('. This is not an error, but
  *      simply that the macro name should be treated as a non-macro.
  *
  *   FUNCTION_UNBALANCED_PARENTHESES
  *
  *      Macro name is not followed by a balanced set of parentheses.
  */
 static function_status_t
-_arguments_parse(argument_list_t *arguments, token_node_t *node,
+_arguments_parse(glcpp_parser_t *parser,
+                 argument_list_t *arguments, token_node_t *node,
                  token_node_t **last)
 {
    token_list_t *argument;
    int paren_count;
 
    node = node->next;
 
    /* Ignore whitespace before first parenthesis. */
    while (node && node->token->type == SPACE)
       node = node->next;
 
    if (node == NULL || node->token->type != '(')
       return FUNCTION_NOT_A_FUNCTION;
 
    node = node->next;
 
-   argument = _token_list_create (arguments);
-   _argument_list_append (arguments, argument);
+   argument = _token_list_create (parser);
+   _argument_list_append (parser, arguments, argument);
 
    for (paren_count = 1; node; node = node->next) {
       if (node->token->type == '(') {
          paren_count++;
       } else if (node->token->type == ')') {
          paren_count--;
          if (paren_count == 0)
             break;
       }
 
       if (node->token->type == ',' && paren_count == 1) {
          _token_list_trim_trailing_space (argument);
-         argument = _token_list_create (arguments);
-         _argument_list_append (arguments, argument);
+         argument = _token_list_create (parser);
+         _argument_list_append (parser, arguments, argument);
       } else {
          if (argument->head == NULL) {
             /* Don't treat initial whitespace as part of the argument. */
             if (node->token->type == SPACE)
                continue;
          }
-         _token_list_append (argument, node->token);
+         _token_list_append(parser, argument, node->token);
       }
    }
 
    if (paren_count)
       return FUNCTION_UNBALANCED_PARENTHESES;
 
    *last = node;
 
    return FUNCTION_STATUS_SUCCESS;
 }
 
 static token_list_t *
-_token_list_create_with_one_ival(void *ctx, int type, int ival)
+_token_list_create_with_one_ival(glcpp_parser_t *parser, int type, int ival)
 {
    token_list_t *list;
    token_t *node;
 
-   list = _token_list_create(ctx);
-   node = _token_create_ival(list, type, ival);
-   _token_list_append(list, node);
+   list = _token_list_create(parser);
+   node = _token_create_ival(parser, type, ival);
+   _token_list_append(parser, list, node);
 
    return list;
 }
 
 static token_list_t *
-_token_list_create_with_one_space(void *ctx)
+_token_list_create_with_one_space(glcpp_parser_t *parser)
 {
-   return _token_list_create_with_one_ival(ctx, SPACE, SPACE);
+   return _token_list_create_with_one_ival(parser, SPACE, SPACE);
 }
 
 static token_list_t *
-_token_list_create_with_one_integer(void *ctx, int ival)
+_token_list_create_with_one_integer(glcpp_parser_t *parser, int ival)
 {
-   return _token_list_create_with_one_ival(ctx, INTEGER, ival);
+   return _token_list_create_with_one_ival(parser, INTEGER, ival);
 }
 
 /* Evaluate a DEFINED token node (based on subsequent tokens in the list).
  *
  * Note: This function must only be called when "node" is a DEFINED token,
  * (and will abort with an assertion failure otherwise).
  *
  * If "node" is followed, (ignoring any SPACE tokens), by an IDENTIFIER token
  * (optionally preceded and followed by '(' and ')' tokens) then the following
  * occurs:
@@ -1594,22 +1588,22 @@ _glcpp_parser_evaluate_defined_in_list(glcpp_parser_t *parser,
 
    while (node) {
 
       if (node->token->type != DEFINED)
          goto NEXT;
 
       value = _glcpp_parser_evaluate_defined (parser, node, &last);
       if (value == -1)
          goto NEXT;
 
-      replacement = ralloc (list, token_node_t);
-      replacement->token = _token_create_ival (list, INTEGER, value);
+      replacement = linear_alloc_child(parser->linalloc, sizeof(token_node_t));
+      replacement->token = _token_create_ival (parser, INTEGER, value);
 
       /* Splice replacement node into list, replacing from "node"
        * through "last". */
       if (node_prev)
          node_prev->next = replacement;
       else
          list->head = replacement;
       replacement->next = last->next;
       if (last == list->tail)
          list->tail = replacement;
@@ -1632,21 +1626,21 @@ _glcpp_parser_evaluate_defined_in_list(glcpp_parser_t *parser,
  */
 static void
 _glcpp_parser_expand_and_lex_from(glcpp_parser_t *parser, int head_token_type,
                                   token_list_t *list, expansion_mode_t mode)
 {
    token_list_t *expanded;
    token_t *token;
 
    expanded = _token_list_create (parser);
    token = _token_create_ival (parser, head_token_type, head_token_type);
-   _token_list_append (expanded, token);
+   _token_list_append (parser, expanded, token);
    _glcpp_parser_expand_token_list (parser, list, mode);
    _token_list_append_list (expanded, list);
    glcpp_parser_lex_from (parser, expanded);
 }
 
 static void
 _glcpp_parser_apply_pastes(glcpp_parser_t *parser, token_list_t *list)
 {
    token_node_t *node;
 
@@ -1670,21 +1664,21 @@ _glcpp_parser_apply_pastes(glcpp_parser_t *parser, token_list_t *list)
       /* Now find the next non-space token after the PASTE. */
       next_non_space = next_non_space->next;
       while (next_non_space && next_non_space->token->type == SPACE)
          next_non_space = next_non_space->next;
 
       if (next_non_space == NULL) {
          yyerror(&node->token->location, parser, "'##' cannot appear at either end of a macro expansion\n");
          return;
       }
 
-      node->token = _token_paste(parser, node->token, next_non_space->token);
+      node->token = _token_paste(parser, list, node->token, next_non_space->token);
       node->next = next_non_space->next;
       if (next_non_space == list->tail)
          list->tail = node;
    }
 
    list->non_space_tail = list->tail;
 }
 
 /* This is a helper function that's essentially part of the
  * implementation of _glcpp_parser_expand_node. It shouldn't be called
@@ -1719,75 +1713,74 @@ _glcpp_parser_expand_function(glcpp_parser_t *parser, token_node_t *node,
    int parameter_index;
 
    identifier = node->token->value.str;
 
    entry = _mesa_hash_table_search(parser->defines, identifier);
    macro = entry ? entry->data : NULL;
 
    assert(macro->is_function);
 
    arguments = _argument_list_create(parser);
-   status = _arguments_parse(arguments, node, last);
+   status = _arguments_parse(parser, arguments, node, last);
 
    switch (status) {
    case FUNCTION_STATUS_SUCCESS:
       break;
    case FUNCTION_NOT_A_FUNCTION:
       return NULL;
    case FUNCTION_UNBALANCED_PARENTHESES:
       glcpp_error(&node->token->location, parser, "Macro %s call has unbalanced parentheses\n", identifier);
       return NULL;
    }
 
    /* Replace a macro defined as empty with a SPACE token. */
    if (macro->replacements == NULL) {
-      ralloc_free(arguments);
       return _token_list_create_with_one_space(parser);
    }
 
    if (!((_argument_list_length (arguments) ==
           _string_list_length (macro->parameters)) ||
          (_string_list_length (macro->parameters) == 0 &&
           _argument_list_length (arguments) == 1 &&
           arguments->head->argument->head == NULL))) {
       glcpp_error(&node->token->location, parser,
                   "Error: macro %s invoked with %d arguments (expected %d)\n",
                   identifier, _argument_list_length (arguments),
                   _string_list_length(macro->parameters));
       return NULL;
    }
 
    /* Perform argument substitution on the replacement list. */
-   substituted = _token_list_create(arguments);
+   substituted = _token_list_create(parser);
 
    for (node = macro->replacements->head; node; node = node->next) {
       if (node->token->type == IDENTIFIER &&
           _string_list_contains(macro->parameters, node->token->value.str,
                                 &parameter_index)) {
          token_list_t *argument;
          argument = _argument_list_member_at(arguments, parameter_index);
          /* Before substituting, we expand the argument tokens, or append a
           * placeholder token for an empty argument. */
          if (argument->head) {
             token_list_t *expanded_argument;
             expanded_argument = _token_list_copy(parser, argument);
             _glcpp_parser_expand_token_list(parser, expanded_argument, mode);
             _token_list_append_list(substituted, expanded_argument);
          } else {
             token_t *new_token;
 
-            new_token = _token_create_ival(substituted, PLACEHOLDER,
+            new_token = _token_create_ival(parser, PLACEHOLDER,
                                            PLACEHOLDER);
-            _token_list_append(substituted, new_token);
+            _token_list_append(parser, substituted, new_token);
          }
       } else {
-         _token_list_append(substituted, node->token);
+         _token_list_append(parser, substituted, node->token);
       }
    }
 
    /* After argument substitution, and before further expansion
     * below, implement token pasting. */
 
    _token_list_trim_trailing_space(substituted);
 
    _glcpp_parser_apply_pastes(parser, substituted);
 
@@ -1847,24 +1840,24 @@ _glcpp_parser_expand_node(glcpp_parser_t *parser, token_node_t *node,
 
    /* Finally, don't expand this macro if we're already actively
     * expanding it, (to avoid infinite recursion). */
    if (_parser_active_list_contains (parser, identifier)) {
       /* We change the token type here from IDENTIFIER to OTHER to prevent any
        * future expansion of this unexpanded token. */
       char *str;
       token_list_t *expansion;
       token_t *final;
 
-      str = ralloc_strdup(parser, token->value.str);
+      str = linear_strdup(parser->linalloc, token->value.str);
       final = _token_create_str(parser, OTHER, str);
       expansion = _token_list_create(parser);
-      _token_list_append(expansion, final);
+      _token_list_append(parser, expansion, final);
       return expansion;
    }
 
    if (! macro->is_function) {
       token_list_t *replacement;
 
       /* Replace a macro defined as empty with a SPACE token. */
       if (macro->replacements == NULL)
          return _token_list_create_with_one_space(parser);
 
@@ -1882,41 +1875,39 @@ _glcpp_parser_expand_node(glcpp_parser_t *parser, token_node_t *node,
  * expansion of 'identifier'. That is, when the list iterator begins
  * examining 'marker', then it is time to pop this node from the
  * active stack.
  */
 static void
 _parser_active_list_push(glcpp_parser_t *parser, const char *identifier,
                          token_node_t *marker)
 {
    active_list_t *node;
 
-   node = ralloc(parser->active, active_list_t);
-   node->identifier = ralloc_strdup(node, identifier);
+   node = linear_alloc_child(parser->linalloc, sizeof(active_list_t));
+   node->identifier = linear_strdup(parser->linalloc, identifier);
    node->marker = marker;
    node->next = parser->active;
 
    parser->active = node;
 }
 
 static void
 _parser_active_list_pop(glcpp_parser_t *parser)
 {
    active_list_t *node = parser->active;
 
    if (node == NULL) {
       parser->active = NULL;
       return;
    }
 
    node = parser->active->next;
-   ralloc_free (parser->active);
-
    parser->active = node;
 }
 
 static int
 _parser_active_list_contains(glcpp_parser_t *parser, const char *identifier)
 {
    active_list_t *node;
 
    if (parser->active == NULL)
       return 0;
@@ -2090,33 +2081,31 @@ _define_object_macro(glcpp_parser_t *parser, YYLTYPE *loc,
 {
    macro_t *macro, *previous;
    struct hash_entry *entry;
 
    /* We define pre-defined macros before we've started parsing the actual
     * file. So if there's no location defined yet, that's what were doing and
     * we don't want to generate an error for using the reserved names. */
    if (loc != NULL)
       _check_for_reserved_macro_name(parser, loc, identifier);
 
-   macro = ralloc (parser, macro_t);
+   macro = linear_alloc_child(parser->linalloc, sizeof(macro_t));
 
    macro->is_function = 0;
    macro->parameters = NULL;
-   macro->identifier = ralloc_strdup (macro, identifier);
+   macro->identifier = linear_strdup(parser->linalloc, identifier);
    macro->replacements = replacements;
-   ralloc_steal (macro, replacements);
 
    entry = _mesa_hash_table_search(parser->defines, identifier);
    previous = entry ? entry->data : NULL;
    if (previous) {
       if (_macro_equal (macro, previous)) {
-         ralloc_free (macro);
          return;
       }
       glcpp_error (loc, parser, "Redefinition of macro %s\n",  identifier);
    }
 
    _mesa_hash_table_insert (parser->defines, identifier, macro);
 }
 
 void
 _define_function_macro(glcpp_parser_t *parser, YYLTYPE *loc,
@@ -2127,34 +2116,31 @@ _define_function_macro(glcpp_parser_t *parser, YYLTYPE *loc,
    struct hash_entry *entry;
    const char *dup;
 
    _check_for_reserved_macro_name(parser, loc, identifier);
 
         /* Check for any duplicate parameter names. */
    if ((dup = _string_list_has_duplicate (parameters)) != NULL) {
       glcpp_error (loc, parser, "Duplicate macro parameter \"%s\"", dup);
    }
 
-   macro = ralloc (parser, macro_t);
-   ralloc_steal (macro, parameters);
-   ralloc_steal (macro, replacements);
+   macro = linear_alloc_child(parser->linalloc, sizeof(macro_t));
 
    macro->is_function = 1;
    macro->parameters = parameters;
-   macro->identifier = ralloc_strdup (macro, identifier);
+   macro->identifier = linear_strdup(parser->linalloc, identifier);
    macro->replacements = replacements;
 
    entry = _mesa_hash_table_search(parser->defines, identifier);
    previous = entry ? entry->data : NULL;
    if (previous) {
       if (_macro_equal (macro, previous)) {
-         ralloc_free (macro);
          return;
       }
       glcpp_error (loc, parser, "Redefinition of macro %s\n", identifier);
    }
 
    _mesa_hash_table_insert(parser->defines, identifier, macro);
 }
 
 static int
 glcpp_parser_lex(YYSTYPE *yylval, YYLTYPE *yylloc, glcpp_parser_t *parser)
@@ -2207,21 +2193,20 @@ glcpp_parser_lex(YYSTYPE *yylval, YYLTYPE *yylloc, glcpp_parser_t *parser)
             parser->paren_count = 0;
          }
       }
 
       return ret;
    }
 
    node = parser->lex_from_node;
 
    if (node == NULL) {
-      ralloc_free (parser->lex_from_list);
       parser->lex_from_list = NULL;
       return NEWLINE;
    }
 
    *yylval = node->token->value;
    ret = node->token->type;
 
    parser->lex_from_node = node->next;
 
    return ret;
@@ -2233,45 +2218,42 @@ glcpp_parser_lex_from(glcpp_parser_t *parser, token_list_t *list)
    token_node_t *node;
 
    assert (parser->lex_from_list == NULL);
 
    /* Copy list, eliminating any space tokens. */
    parser->lex_from_list = _token_list_create (parser);
 
    for (node = list->head; node; node = node->next) {
       if (node->token->type == SPACE)
          continue;
-      _token_list_append (parser->lex_from_list, node->token);
+      _token_list_append (parser,  parser->lex_from_list, node->token);
    }
 
-   ralloc_free (list);
-
    parser->lex_from_node = parser->lex_from_list->head;
 
    /* It's possible the list consisted of nothing but whitespace. */
    if (parser->lex_from_node == NULL) {
-      ralloc_free (parser->lex_from_list);
       parser->lex_from_list = NULL;
    }
 }
 
 static void
 _glcpp_parser_skip_stack_push_if(glcpp_parser_t *parser, YYLTYPE *loc,
                                  int condition)
 {
    skip_type_t current = SKIP_NO_SKIP;
    skip_node_t *node;
 
    if (parser->skip_stack)
       current = parser->skip_stack->type;
 
-   node = ralloc (parser, skip_node_t);
+   node = linear_alloc_child(parser->linalloc, sizeof(skip_node_t));
    node->loc = *loc;
 
    if (current == SKIP_NO_SKIP) {
       if (condition)
          node->type = SKIP_NO_SKIP;
       else
          node->type = SKIP_TO_ELSE;
    } else {
       node->type = SKIP_TO_ENDIF;
    }
@@ -2303,21 +2285,20 @@ _glcpp_parser_skip_stack_pop(glcpp_parser_t *parser, YYLTYPE *loc)
 {
    skip_node_t *node;
 
    if (parser->skip_stack == NULL) {
       glcpp_error (loc, parser, "#endif without #if\n");
       return;
    }
 
    node = parser->skip_stack;
    parser->skip_stack = node->next;
-   ralloc_free (node);
 }
 
 static void
 _glcpp_parser_handle_version_declaration(glcpp_parser_t *parser, intmax_t version,
                                          const char *es_identifier,
                                          bool explicitly_set)
 {
    if (parser->version != 0)
       return;
 
diff --git a/src/compiler/glsl/glcpp/glcpp.h b/src/compiler/glsl/glcpp/glcpp.h
index cab4374..bb4ad67 100644
--- a/src/compiler/glsl/glcpp/glcpp.h
+++ b/src/compiler/glsl/glcpp/glcpp.h
@@ -174,20 +174,21 @@ typedef struct active_list {
 struct _mesa_glsl_parse_state;
 
 typedef void (*glcpp_extension_iterator)(
 		struct _mesa_glsl_parse_state *state,
 		void (*add_builtin_define)(glcpp_parser_t *, const char *, int),
 		glcpp_parser_t *data,
 		unsigned version,
 		bool es);
 
 struct glcpp_parser {
+	void *linalloc;
 	yyscan_t scanner;
 	struct hash_table *defines;
 	active_list_t *active;
 	int lexing_directive;
 	int lexing_version_directive;
 	int space_tokens;
 	int last_token_was_newline;
 	int last_token_was_space;
 	int first_non_space_token_this_line;
 	int newline_as_space;
-- 
2.7.4



More information about the mesa-dev mailing list