css: Avoid more allocations for tokens
authorMatthias Clasen <mclasen@redhat.com>
Thu, 12 Jan 2023 05:00:54 +0000 (00:00 -0500)
committerMatthias Clasen <mclasen@redhat.com>
Thu, 12 Jan 2023 05:12:09 +0000 (00:12 -0500)
Make short string tokens static.

gdk/gdkrgba.c
gsk/gskrendernodeparser.c
gtk/css/gtkcssparser.c
gtk/css/gtkcsstokenizer.c
gtk/css/gtkcsstokenizerprivate.h
gtk/gtkcsscolorvalue.c
gtk/gtkcssselector.c

index 7732e507c819d47172f5f3e2ee39ece89042bd31..9b52204038a95e7fc322e134fd08265099715ed0 100644 (file)
@@ -586,7 +586,7 @@ gdk_rgba_parser_parse (GtkCssParser *parser,
   else if (gtk_css_token_is (token, GTK_CSS_TOKEN_HASH_ID) ||
            gtk_css_token_is (token, GTK_CSS_TOKEN_HASH_UNRESTRICTED))
     {
-      const char *s = token->string.string;
+      const char *s = gtk_css_token_get_string (token);
 
       switch (strlen (s))
         {
@@ -637,13 +637,13 @@ gdk_rgba_parser_parse (GtkCssParser *parser,
         {
           *rgba = (GdkRGBA) { 0, 0, 0, 0 };
         }
-      else if (gdk_rgba_parse (rgba, token->string.string))
+      else if (gdk_rgba_parse (rgba, gtk_css_token_get_string (token)))
         {
           /* everything's fine */
         }
       else
         {
-          gtk_css_parser_error_syntax (parser, "\"%s\" is not a valid color name.", token->string.string);
+          gtk_css_parser_error_syntax (parser, "\"%s\" is not a valid color name.", gtk_css_token_get_string (token));
           return FALSE;
         }
 
index 25943ec305e8c158a9f96f2970c99608a8c07e49..68069b477e8b60b9239575e814747f6f5b59221f 100644 (file)
@@ -418,7 +418,7 @@ parse_string (GtkCssParser *parser,
   if (!gtk_css_token_is (token, GTK_CSS_TOKEN_STRING))
     return FALSE;
 
-  s = g_strdup (token->string.string);
+  s = g_strdup (gtk_css_token_get_string (token));
   gtk_css_parser_consume_token (parser);
 
   g_free (*(char **) out_string);
@@ -931,7 +931,7 @@ parse_declarations (GtkCssParser      *parser,
         {
           if (gtk_css_parser_has_token (parser, GTK_CSS_TOKEN_IDENT))
             gtk_css_parser_error_syntax (parser, "No variable named \"%s\"",
-                                         gtk_css_parser_get_token (parser)->string.string);
+                                         gtk_css_token_get_string (gtk_css_parser_get_token (parser)));
           else
             gtk_css_parser_error_syntax (parser, "Expected a variable name");
         }
@@ -1894,7 +1894,7 @@ parse_node (GtkCssParser *parser,
 
   if (gtk_css_parser_has_token (parser, GTK_CSS_TOKEN_IDENT))
     gtk_css_parser_error_value (parser, "\"%s\" is not a valid node name",
-                                gtk_css_parser_get_token (parser)->string.string);
+                                gtk_css_token_get_string (gtk_css_parser_get_token (parser)));
   else
     gtk_css_parser_error_syntax (parser, "Expected a node name");
 
index 886e84f9529e34fdd7667cb83112d67289d646e1..7b0cbcdaeb0d06ae525b363ad89430dea221e566 100644 (file)
@@ -648,7 +648,7 @@ gtk_css_parser_consume_function (GtkCssParser *self,
   token = gtk_css_parser_get_token (self);
   g_return_val_if_fail (gtk_css_token_is (token, GTK_CSS_TOKEN_FUNCTION), FALSE);
 
-  g_strlcpy (function_name, token->string.string, 64);
+  g_strlcpy (function_name, gtk_css_token_get_string (token), 64);
   gtk_css_parser_start_block (self);
 
   arg = 0;
@@ -733,7 +733,7 @@ gtk_css_parser_has_ident (GtkCssParser *self,
   token = gtk_css_parser_get_token (self);
 
   return gtk_css_token_is (token, GTK_CSS_TOKEN_IDENT) &&
-         g_ascii_strcasecmp (token->string.string, ident) == 0;
+         g_ascii_strcasecmp (gtk_css_token_get_string (token), ident) == 0;
 }
 
 gboolean
@@ -765,7 +765,7 @@ gtk_css_parser_has_function (GtkCssParser *self,
   token = gtk_css_parser_get_token (self);
 
   return gtk_css_token_is (token, GTK_CSS_TOKEN_FUNCTION) &&
-         g_ascii_strcasecmp (token->string.string, name) == 0;
+         g_ascii_strcasecmp (gtk_css_token_get_string (token), name) == 0;
 }
 
 /**
@@ -818,7 +818,7 @@ gtk_css_parser_try_ident (GtkCssParser *self,
   token = gtk_css_parser_get_token (self);
 
   if (!gtk_css_token_is (token, GTK_CSS_TOKEN_IDENT) ||
-      g_ascii_strcasecmp (token->string.string, ident) != 0)
+      g_ascii_strcasecmp (gtk_css_token_get_string (token), ident) != 0)
     return FALSE;
 
   gtk_css_parser_consume_token (self);
@@ -845,7 +845,7 @@ gtk_css_parser_try_at_keyword (GtkCssParser *self,
   token = gtk_css_parser_get_token (self);
 
   if (!gtk_css_token_is (token, GTK_CSS_TOKEN_AT_KEYWORD) ||
-      g_ascii_strcasecmp (token->string.string, keyword) != 0)
+      g_ascii_strcasecmp (gtk_css_token_get_string (token), keyword) != 0)
     return FALSE;
 
   gtk_css_parser_consume_token (self);
@@ -907,7 +907,7 @@ gtk_css_parser_consume_ident (GtkCssParser *self)
       return NULL;
     }
 
-  ident = g_strdup (token->string.string);
+  ident = g_strdup (gtk_css_token_get_string (token));
   gtk_css_parser_consume_token (self);
 
   return ident;
@@ -938,7 +938,7 @@ gtk_css_parser_consume_string (GtkCssParser *self)
       return NULL;
     }
 
-  ident = g_strdup (token->string.string);
+  ident = g_strdup (gtk_css_token_get_string (token));
   gtk_css_parser_consume_token (self);
 
   return ident;
@@ -979,7 +979,7 @@ gtk_css_parser_consume_url (GtkCssParser *self)
 
   if (gtk_css_token_is (token, GTK_CSS_TOKEN_URL))
     {
-      url = g_strdup (token->string.string);
+      url = g_strdup (gtk_css_token_get_string (token));
       gtk_css_parser_consume_token (self);
     }
   else if (gtk_css_token_is_function (token, "url"))
index 9cf59e1559dda58e7bf667eea46db8fc51a366c5..899221b5dc88744ca5ddfef3b93b2a0ed816d0f0 100644 (file)
@@ -50,7 +50,8 @@ gtk_css_token_clear (GtkCssToken *token)
     case GTK_CSS_TOKEN_HASH_UNRESTRICTED:
     case GTK_CSS_TOKEN_HASH_ID:
     case GTK_CSS_TOKEN_URL:
-      g_free (token->string.string);
+      if (token->string.len >= 16)
+        g_free (token->string.u.string);
       break;
 
     case GTK_CSS_TOKEN_SIGNED_INTEGER_DIMENSION:
@@ -294,7 +295,7 @@ gtk_css_token_is_ident (const GtkCssToken *token,
                         const char        *ident)
 {
   return gtk_css_token_is (token, GTK_CSS_TOKEN_IDENT)
-      && (g_ascii_strcasecmp (token->string.string, ident) == 0);
+      && (g_ascii_strcasecmp (gtk_css_token_get_string (token), ident) == 0);
 }
 
 gboolean
@@ -302,7 +303,7 @@ gtk_css_token_is_function (const GtkCssToken *token,
                            const char        *ident)
 {
   return gtk_css_token_is (token, GTK_CSS_TOKEN_FUNCTION)
-      && (g_ascii_strcasecmp (token->string.string, ident) == 0);
+      && (g_ascii_strcasecmp (gtk_css_token_get_string (token), ident) == 0);
 }
 
 gboolean
@@ -322,33 +323,33 @@ gtk_css_token_print (const GtkCssToken *token,
   switch (token->type)
     {
     case GTK_CSS_TOKEN_STRING:
-      append_string (string, token->string.string);
+      append_string (string, gtk_css_token_get_string (token));
       break;
 
     case GTK_CSS_TOKEN_IDENT:
-      append_ident (string, token->string.string);
+      append_ident (string, gtk_css_token_get_string (token));
       break;
 
     case GTK_CSS_TOKEN_URL:
       g_string_append (string, "url(");
-      append_ident (string, token->string.string);
+      append_ident (string, gtk_css_token_get_string (token));
       g_string_append (string, ")");
       break;
 
     case GTK_CSS_TOKEN_FUNCTION:
-      append_ident (string, token->string.string);
+      append_ident (string, gtk_css_token_get_string (token));
       g_string_append_c (string, '(');
       break;
 
     case GTK_CSS_TOKEN_AT_KEYWORD:
       g_string_append_c (string, '@');
-      append_ident (string, token->string.string);
+      append_ident (string, gtk_css_token_get_string (token));
       break;
 
     case GTK_CSS_TOKEN_HASH_UNRESTRICTED:
     case GTK_CSS_TOKEN_HASH_ID:
       g_string_append_c (string, '#');
-      append_ident (string, token->string.string);
+      append_ident (string, gtk_css_token_get_string (token));
       break;
 
     case GTK_CSS_TOKEN_DELIM:
@@ -490,7 +491,7 @@ gtk_css_token_to_string (const GtkCssToken *token)
 static void
 gtk_css_token_init_string (GtkCssToken     *token,
                            GtkCssTokenType  type,
-                           char            *string)
+                           GString         *string)
 {
   token->type = type;
 
@@ -503,7 +504,11 @@ gtk_css_token_init_string (GtkCssToken     *token,
     case GTK_CSS_TOKEN_HASH_UNRESTRICTED:
     case GTK_CSS_TOKEN_HASH_ID:
     case GTK_CSS_TOKEN_URL:
-      token->string.string = string;
+      token->string.len = string->len;
+      if (string->len < 16)
+        g_strlcpy (token->string.u.buf, string->str, 16);
+      else
+        token->string.u.string = g_strdup (string->str);
       break;
     default:
       g_assert_not_reached ();
@@ -543,8 +548,7 @@ static void
 gtk_css_token_init_dimension (GtkCssToken     *token,
                               GtkCssTokenType  type,
                               double           value,
-                              const char      *dimension,
-                              int              len)
+                              GString         *string)
 {
   token->type = type;
 
@@ -555,13 +559,7 @@ gtk_css_token_init_dimension (GtkCssToken     *token,
     case GTK_CSS_TOKEN_SIGNED_DIMENSION:
     case GTK_CSS_TOKEN_SIGNLESS_DIMENSION:
       token->dimension.value = value;
-      for (int i = 0; i < MIN (8, len); i++)
-        {
-          token->dimension.dimension[i] = dimension[i];
-          if (dimension[i] == 0)
-            break;
-        }
-      token->dimension.dimension[7] = 0;
+      g_strlcpy (token->dimension.dimension, string->str, 8);
       break;
     default:
       g_assert_not_reached ();
@@ -880,7 +878,7 @@ gtk_css_tokenizer_read_escape (GtkCssTokenizer *tokenizer)
   return value;
 }
 
-static char *
+static void
 gtk_css_tokenizer_read_name (GtkCssTokenizer *tokenizer)
 {
   g_string_set_size (tokenizer->name_buffer, 0);
@@ -916,8 +914,6 @@ gtk_css_tokenizer_read_name (GtkCssTokenizer *tokenizer)
         }
     }
   while (tokenizer->data != tokenizer->end);
-
-  return g_strndup (tokenizer->name_buffer->str, tokenizer->name_buffer->len);
 }
 
 static void
@@ -1010,7 +1006,8 @@ gtk_css_tokenizer_read_url (GtkCssTokenizer  *tokenizer,
         }
     }
 
-  gtk_css_token_init_string (token, GTK_CSS_TOKEN_URL, g_string_free (url, FALSE));
+  gtk_css_token_init_string (token, GTK_CSS_TOKEN_URL, url);
+  g_string_free (url, TRUE);
 
   return TRUE;
 }
@@ -1020,12 +1017,12 @@ gtk_css_tokenizer_read_ident_like (GtkCssTokenizer  *tokenizer,
                                    GtkCssToken      *token,
                                    GError          **error)
 {
-  char *name = gtk_css_tokenizer_read_name (tokenizer);
+  gtk_css_tokenizer_read_name (tokenizer);
 
   if (*tokenizer->data == '(')
     {
       gtk_css_tokenizer_consume_ascii (tokenizer);
-      if (g_ascii_strcasecmp (name, "url") == 0)
+      if (g_ascii_strcasecmp (tokenizer->name_buffer->str, "url") == 0)
         {
           const char *data = tokenizer->data;
 
@@ -1033,18 +1030,15 @@ gtk_css_tokenizer_read_ident_like (GtkCssTokenizer  *tokenizer,
             data++;
 
           if (*data != '"' && *data != '\'')
-            {
-              g_free (name);
-              return gtk_css_tokenizer_read_url (tokenizer, token, error);
-            }
+            return gtk_css_tokenizer_read_url (tokenizer, token, error);
         }
 
-      gtk_css_token_init_string (token, GTK_CSS_TOKEN_FUNCTION, name);
+      gtk_css_token_init_string (token, GTK_CSS_TOKEN_FUNCTION, tokenizer->name_buffer);
       return TRUE;
     }
   else
     {
-      gtk_css_token_init_string (token, GTK_CSS_TOKEN_IDENT, name);
+      gtk_css_token_init_string (token, GTK_CSS_TOKEN_IDENT, tokenizer->name_buffer);
       return TRUE;
     }
 }
@@ -1134,8 +1128,8 @@ gtk_css_tokenizer_read_numeric (GtkCssTokenizer *tokenizer,
       else
         type = has_sign ? GTK_CSS_TOKEN_SIGNED_DIMENSION : GTK_CSS_TOKEN_SIGNLESS_DIMENSION;
 
-      char *name = gtk_css_tokenizer_read_name (tokenizer);
-      gtk_css_token_init_dimension (token, type, value, name, strlen (name));
+      gtk_css_tokenizer_read_name (tokenizer);
+      gtk_css_token_init_dimension (token, type, value, tokenizer->name_buffer);
     }
   else if (gtk_css_tokenizer_remaining (tokenizer) > 0 && *tokenizer->data == '%')
     {
@@ -1244,7 +1238,7 @@ gtk_css_tokenizer_read_string (GtkCssTokenizer  *tokenizer,
         }
     }
 
-  gtk_css_token_init_string (token, GTK_CSS_TOKEN_STRING, g_strdup (tokenizer->name_buffer->str));
+  gtk_css_token_init_string (token, GTK_CSS_TOKEN_STRING, tokenizer->name_buffer);
 
   return TRUE;
 }
@@ -1328,9 +1322,8 @@ gtk_css_tokenizer_read_token (GtkCssTokenizer  *tokenizer,
           else
             type = GTK_CSS_TOKEN_HASH_UNRESTRICTED;
 
-          gtk_css_token_init_string (token,
-                                     type,
-                                     gtk_css_tokenizer_read_name (tokenizer));
+          gtk_css_tokenizer_read_name (tokenizer);
+          gtk_css_token_init_string (token, type, tokenizer->name_buffer);
         }
       else
         {
@@ -1410,9 +1403,8 @@ gtk_css_tokenizer_read_token (GtkCssTokenizer  *tokenizer,
       gtk_css_tokenizer_consume_ascii (tokenizer);
       if (gtk_css_tokenizer_has_identifier (tokenizer))
         {
-          gtk_css_token_init_string (token,
-                                     GTK_CSS_TOKEN_AT_KEYWORD,
-                                     gtk_css_tokenizer_read_name (tokenizer));
+          gtk_css_tokenizer_read_name (tokenizer);
+          gtk_css_token_init_string (token, GTK_CSS_TOKEN_AT_KEYWORD, tokenizer->name_buffer);
         }
       else
         {
index 6f97bd904ef54699154afb23e61f2c6994a37aaa..6f4df9c22e026e0903f6f2d23bea30b031b21361 100644 (file)
@@ -81,7 +81,11 @@ typedef struct _GtkCssDimensionToken GtkCssDimensionToken;
 
 struct _GtkCssStringToken {
   GtkCssTokenType  type;
-  char            *string;
+  int len;
+  union {
+    char             buf[16];
+    char            *string;
+  } u;
 };
 
 struct _GtkCssDelimToken {
@@ -108,6 +112,15 @@ union _GtkCssToken {
   GtkCssDimensionToken dimension;
 };
 
+static inline const char *
+gtk_css_token_get_string (const GtkCssToken *token)
+{
+  if (token->string.len < 16)
+    return token->string.u.buf;
+  else
+    return token->string.u.string;
+}
+
 void                    gtk_css_token_clear                     (GtkCssToken            *token);
 
 gboolean                gtk_css_token_is_finite                 (const GtkCssToken      *token) G_GNUC_PURE;
index 4b0b4adfe4315bb7264e5cbccf35f56434f5da99..b326b9cae9fdedeaf09624875eaf594d4b039adb 100644 (file)
@@ -722,7 +722,7 @@ _gtk_css_color_value_parse (GtkCssParser *parser)
     {
       const GtkCssToken *token = gtk_css_parser_get_token (parser);
 
-      value = _gtk_css_color_value_new_name (token->string.string);
+      value = _gtk_css_color_value_new_name (gtk_css_token_get_string (token));
       gtk_css_parser_consume_token (parser);
 
       return value;
index 207d83ac7d5a3808f4993a23ef8cb4502fa0552e..baed35dadb35548676eabc2d75ffd6780f772c9a 100644 (file)
@@ -947,7 +947,7 @@ gtk_css_selector_parse_selector_class (GtkCssParser   *parser,
       selector = gtk_css_selector_new (negate ? &GTK_CSS_SELECTOR_NOT_CLASS
                                               : &GTK_CSS_SELECTOR_CLASS,
                                        selector);
-      selector->style_class.style_class = g_quark_from_string (token->string.string);
+      selector->style_class.style_class = g_quark_from_string (gtk_css_token_get_string (token));
       gtk_css_parser_consume_token (parser);
       return selector;
     }
@@ -1060,7 +1060,7 @@ parse_n_plus_b (GtkCssParser *parser,
       return parse_plus_b (parser, TRUE, b);
     }
   else if (gtk_css_token_is (token, GTK_CSS_TOKEN_IDENT) &&
-           string_has_number (token->string.string, "n-", b))
+           string_has_number (gtk_css_token_get_string (token), "n-", b))
     {
       *a = before;
       *b = -*b;
@@ -1156,7 +1156,7 @@ parse_a_n_plus_b (GtkCssParser *parser,
     }
   else if (!seen_sign &&
            gtk_css_token_is (token, GTK_CSS_TOKEN_IDENT) &&
-           string_has_number (token->string.string, "-n-", b))
+           string_has_number (gtk_css_token_get_string (token), "-n-", b))
     {
       *a = -1;
       *b = -*b;
@@ -1169,7 +1169,7 @@ parse_a_n_plus_b (GtkCssParser *parser,
       return parse_n_plus_b (parser, seen_sign ? seen_sign : 1, a, b);
     }
   else if (gtk_css_token_is (token, GTK_CSS_TOKEN_IDENT) &&
-           string_has_number (token->string.string, "n-", b))
+           string_has_number (gtk_css_token_get_string (token), "n-", b))
     {
       *a = seen_sign ? seen_sign : 1;
       *b = -*b;
@@ -1177,7 +1177,7 @@ parse_a_n_plus_b (GtkCssParser *parser,
       return TRUE;
     }
   else if (!seen_sign && gtk_css_token_is (token, GTK_CSS_TOKEN_IDENT) &&
-           string_has_number (token->string.string, "-n-", b))
+           string_has_number (gtk_css_token_get_string (token), "-n-", b))
     {
       *a = -1;
       *b = -*b;
@@ -1288,7 +1288,7 @@ gtk_css_selector_parse_selector_pseudo_class (GtkCssParser   *parser,
 
       for (i = 0; i < G_N_ELEMENTS (pseudo_classes); i++)
         {
-          if (g_ascii_strcasecmp (pseudo_classes[i].name, token->string.string) == 0)
+          if (g_ascii_strcasecmp (pseudo_classes[i].name, gtk_css_token_get_string (token)) == 0)
             {
               if (pseudo_classes[i].state_flag)
                 {
@@ -1380,13 +1380,13 @@ gtk_css_selector_parse_selector_pseudo_class (GtkCssParser   *parser,
               else if (gtk_css_token_is (token, GTK_CSS_TOKEN_IDENT))
                 {
                   selector = gtk_css_selector_new (&GTK_CSS_SELECTOR_NOT_NAME, selector);
-                  selector->name.name = g_quark_from_string (token->string.string);
+                  selector->name.name = g_quark_from_string (gtk_css_token_get_string (token));
                   gtk_css_parser_consume_token (parser);
                 }
               else if (gtk_css_token_is (token, GTK_CSS_TOKEN_HASH_ID))
                 {
                   selector = gtk_css_selector_new (&GTK_CSS_SELECTOR_NOT_ID, selector);
-                  selector->id.name = g_quark_from_string (token->string.string);
+                  selector->id.name = g_quark_from_string (gtk_css_token_get_string (token));
                   gtk_css_parser_consume_token (parser);
                 }
               else if (gtk_css_token_is_delim (token, '.'))
@@ -1499,13 +1499,13 @@ gtk_css_selector_parse_simple_selector (GtkCssParser   *parser,
       else if (!parsed_something && gtk_css_token_is (token, GTK_CSS_TOKEN_IDENT))
         {
           selector = gtk_css_selector_new (&GTK_CSS_SELECTOR_NAME, selector);
-          selector->name.name = g_quark_from_string (token->string.string);
+          selector->name.name = g_quark_from_string (gtk_css_token_get_string (token));
           gtk_css_parser_consume_token (parser);
         }
       else if (gtk_css_token_is (token, GTK_CSS_TOKEN_HASH_ID))
         {
           selector = gtk_css_selector_new (&GTK_CSS_SELECTOR_ID, selector);
-          selector->id.name = g_quark_from_string (token->string.string);
+          selector->id.name = g_quark_from_string (gtk_css_token_get_string (token));
           gtk_css_parser_consume_token (parser);
         }
       else if (gtk_css_token_is_delim (token, '.'))