[gtk/optimize-precompile: 7/11] builder: Reduce memory usage in precompile
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/optimize-precompile: 7/11] builder: Reduce memory usage in precompile
- Date: Fri, 10 Dec 2021 19:48:10 +0000 (UTC)
commit abf14d68120facb4e3d60bed967b453e5d1d5308
Author: Garrett Regier <garrettregier gmail com>
Date: Tue Sep 21 15:13:34 2021 -0700
builder: Reduce memory usage in precompile
Split the Element and Text nodes into separate structures.
gtk/gtkbuilderprecompile.c | 168 ++++++++++++++++++++++++++++++---------------
1 file changed, 112 insertions(+), 56 deletions(-)
---
diff --git a/gtk/gtkbuilderprecompile.c b/gtk/gtkbuilderprecompile.c
index ba9f593c63..f9d216cfb6 100644
--- a/gtk/gtkbuilderprecompile.c
+++ b/gtk/gtkbuilderprecompile.c
@@ -30,7 +30,7 @@ typedef enum
RECORD_TYPE_ELEMENT,
RECORD_TYPE_END_ELEMENT,
RECORD_TYPE_TEXT,
-} RecordTreeType;
+} RecordDataType;
/* All strings are owned by the string chunk */
typedef struct {
@@ -42,53 +42,105 @@ typedef struct {
gboolean include_len;
} RecordDataString;
-typedef struct RecordDataTree RecordDataTree;
+typedef struct {
+ RecordDataType type;
+ GList link;
+} RecordDataNode;
+
+typedef struct RecordDataElement RecordDataElement;
-struct RecordDataTree {
- RecordDataTree *parent;
- RecordTreeType type;
+struct RecordDataElement {
+ RecordDataNode base;
+
+ RecordDataElement *parent;
int n_attributes;
- RecordDataString *data;
+ RecordDataString *name;
RecordDataString **attributes;
- GList link;
GQueue children;
};
+typedef struct {
+ RecordDataNode base;
+
+ RecordDataString *string;
+} RecordDataText;
+
typedef struct {
GHashTable *strings;
GStringChunk *chunks;
- RecordDataTree *root;
- RecordDataTree *current;
+ RecordDataElement *root;
+ RecordDataElement *current;
} RecordData;
-static RecordDataTree *
-record_data_tree_new (RecordDataTree *parent,
- RecordTreeType type,
- RecordDataString *data)
+static gpointer
+record_data_node_new (RecordDataElement *parent,
+ RecordDataType type,
+ gsize size)
{
- RecordDataTree *tree = g_slice_new0 (RecordDataTree);
+ RecordDataNode *node = g_slice_alloc0 (size);
- tree->parent = parent;
- tree->type = type;
- tree->data = data;
- tree->link.data = tree;
+ node->type = type;
+ node->link.data = node;
if (parent)
- g_queue_push_tail_link (&parent->children, &tree->link);
+ g_queue_push_tail_link (&parent->children, &node->link);
+
+ return node;
+}
+
+static RecordDataElement *
+record_data_element_new (RecordDataElement *parent,
+ RecordDataString *name)
+{
+ RecordDataElement *element;
+
+ element = record_data_node_new (parent,
+ RECORD_TYPE_ELEMENT,
+ sizeof (RecordDataElement));
+ element->parent = parent;
+ element->name = name;
+
+ return element;
+}
+
+static void
+record_data_element_append_text (RecordDataElement *parent,
+ RecordDataString *string)
+{
+ RecordDataText *text;
- return tree;
+ text = record_data_node_new (parent,
+ RECORD_TYPE_TEXT,
+ sizeof (RecordDataText));
+ text->string = string;
}
static void
-record_data_tree_free (RecordDataTree *tree)
+record_data_node_free (RecordDataNode *node)
{
GList *l;
+ RecordDataText *text;
+ RecordDataElement *element;
- for (l = tree->children.head; l != NULL; l = l->next)
- record_data_tree_free (l->data);
+ switch (node->type)
+ {
+ case RECORD_TYPE_ELEMENT:
+ element = (RecordDataElement *)node;
- g_free (tree->attributes);
- g_slice_free (RecordDataTree, tree);
+ for (l = element->children.head; l != NULL; l = l->next)
+ record_data_node_free (l->data);
+
+ g_free (element->attributes);
+ g_slice_free (RecordDataElement, element);
+ break;
+ case RECORD_TYPE_TEXT:
+ text = (RecordDataText *)node;
+ g_slice_free (RecordDataText, text);
+ break;
+ case RECORD_TYPE_END_ELEMENT:
+ default:
+ g_assert_not_reached ();
+ }
}
static void
@@ -175,12 +227,12 @@ record_start_element (GMarkupParseContext *context,
{
gsize n_attrs = g_strv_length ((char **)names);
RecordData *data = user_data;
- RecordDataTree *child;
- RecordDataString **attr_names, **attr_values;
+ RecordDataElement *child;
+ RecordDataString *name, **attr_names, **attr_values;
int i;
- child = record_data_tree_new (data->current, RECORD_TYPE_ELEMENT,
- record_data_string_lookup (data, element_name, -1));
+ name = record_data_string_lookup (data, element_name, -1);
+ child = record_data_element_new (data->current, name);
data->current = child;
child->n_attributes = n_attrs;
@@ -214,9 +266,10 @@ record_text (GMarkupParseContext *context,
GError **error)
{
RecordData *data = user_data;
+ RecordDataString *string;
- record_data_tree_new (data->current, RECORD_TYPE_TEXT,
- record_data_string_lookup (data, text, text_len));
+ string = record_data_string_lookup (data, text, text_len);
+ record_data_element_append_text (data->current, string);
}
static const GMarkupParser record_parser =
@@ -296,42 +349,45 @@ marshal_uint32_len (guint32 v)
static void
marshal_tree (GString *marshaled,
- RecordDataTree *tree)
+ RecordDataNode *node)
{
GList *l;
int i;
+ RecordDataText *text;
+ RecordDataElement *element;
RecordDataString **attr_names, **attr_values;
- /* Special case the root */
- if (tree->parent == NULL)
- {
- for (l = tree->children.head; l != NULL; l = l->next)
- marshal_tree (marshaled, l->data);
- return;
- }
-
- switch (tree->type)
+ switch (node->type)
{
case RECORD_TYPE_ELEMENT:
- marshal_uint32 (marshaled, RECORD_TYPE_ELEMENT);
- marshal_uint32 (marshaled, tree->data->offset);
- marshal_uint32 (marshaled, tree->n_attributes);
+ element = (RecordDataElement *)node;
- attr_names = &tree->attributes[0];
- attr_values = &tree->attributes[tree->n_attributes];
- for (i = 0; i < tree->n_attributes; i++)
+ /* Special case the root */
+ if (element->parent != NULL)
{
- marshal_uint32 (marshaled, attr_names[i]->offset);
- marshal_uint32 (marshaled, attr_values[i]->offset);
+ marshal_uint32 (marshaled, RECORD_TYPE_ELEMENT);
+ marshal_uint32 (marshaled, element->name->offset);
+ marshal_uint32 (marshaled, element->n_attributes);
+
+ attr_names = &element->attributes[0];
+ attr_values = &element->attributes[element->n_attributes];
+ for (i = 0; i < element->n_attributes; i++)
+ {
+ marshal_uint32 (marshaled, attr_names[i]->offset);
+ marshal_uint32 (marshaled, attr_values[i]->offset);
+ }
}
- for (l = tree->children.head; l != NULL; l = l->next)
+
+ for (l = element->children.head; l != NULL; l = l->next)
marshal_tree (marshaled, l->data);
- marshal_uint32 (marshaled, RECORD_TYPE_END_ELEMENT);
+ if (element->parent != NULL)
+ marshal_uint32 (marshaled, RECORD_TYPE_END_ELEMENT);
break;
case RECORD_TYPE_TEXT:
+ text = (RecordDataText *)node;
marshal_uint32 (marshaled, RECORD_TYPE_TEXT);
- marshal_uint32 (marshaled, tree->data->text_offset);
+ marshal_uint32 (marshaled, text->string->text_offset);
break;
case RECORD_TYPE_END_ELEMENT:
default:
@@ -364,7 +420,7 @@ _gtk_buildable_parser_precompile (const char *text,
data.strings = g_hash_table_new_full (record_data_string_hash, record_data_string_equal,
(GDestroyNotify)record_data_string_free, NULL);
data.chunks = g_string_chunk_new (512);
- data.root = record_data_tree_new (NULL, RECORD_TYPE_ELEMENT, NULL);
+ data.root = record_data_element_new (NULL, NULL);
data.current = data.root;
ctx = g_markup_parse_context_new (&record_parser, G_MARKUP_TREAT_CDATA_AS_TEXT,
@@ -372,7 +428,7 @@ _gtk_buildable_parser_precompile (const char *text,
if (!g_markup_parse_context_parse (ctx, text, text_len, error))
{
- record_data_tree_free (data.root);
+ record_data_node_free (&data.root->base);
g_string_chunk_free (data.chunks);
g_hash_table_destroy (data.strings);
g_markup_parse_context_free (ctx);
@@ -416,9 +472,9 @@ _gtk_buildable_parser_precompile (const char *text,
g_list_free (string_table);
- marshal_tree (marshaled, data.root);
+ marshal_tree (marshaled, &data.root->base);
- record_data_tree_free (data.root);
+ record_data_node_free (&data.root->base);
g_string_chunk_free (data.chunks);
g_hash_table_destroy (data.strings);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]