+2005-05-11 Matthias Clasen <mclasen@redhat.com>
+
+ * src/compiler.c (main): Add a --verbose cmdline option
+ and only log messages if it is specified.
+
+ * src/gidlnode.h:
+ * src/gidlnode.c (init_stats, dump_stats): Collect some
+ statistics on string and type sharing.
+
+ * src/gidlmodule.c (g_idl_module_build_metadata): Use
+ g_message() instead of fprintf().
+
+ * src/gidlnode.c (g_idl_node_free): Make this more robust.
+ (g_idl_node_get_size): Implement for structs.
+ (g_idl_node_get_full_size): Handle parent being NULL.
+ (serialize_type): Handle lookup failures more gracefully.
+
2005-05-10 Matthias Clasen <mclasen@redhat.com>
* src/gidlnode.c (g_idl_node_get_full_size): Correct the
gboolean raw = FALSE;
gboolean no_init = FALSE;
-gboolean debug = FALSE;
gchar **input = NULL;
gchar *output = NULL;
gchar *mname = NULL;
+gboolean debug = FALSE;
+gboolean verbose = FALSE;
static gchar *
format_output (guchar *metadata,
fclose (file);
}
+GLogLevelFlags logged_levels;
+
+static void log_handler (const gchar *log_domain,
+ GLogLevelFlags log_level,
+ const gchar *message,
+ gpointer user_data)
+{
+
+ if (log_level & logged_levels)
+ g_log_default_handler (log_domain, log_level, message, user_data);
+}
+
static GOptionEntry options[] =
{
{ "raw", 0, 0, G_OPTION_ARG_NONE, &raw, "emit raw metadata", NULL },
{ "output", 'o', 0, G_OPTION_ARG_FILENAME, &output, "output file", "FILE" },
{ "module", 'm', 0, G_OPTION_ARG_STRING, &mname, "module to compile", "NAME" },
{ "debug", 0, 0, G_OPTION_ARG_NONE, &debug, "show debug messages", NULL },
+ { "verbose", 0, 0, G_OPTION_ARG_NONE, &verbose, "show verbose messages", NULL },
{ G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_FILENAME_ARRAY, &input, NULL, NULL },
{ NULL, }
};
-static void log_handler (const gchar *log_domain,
- GLogLevelFlags log_level,
- const gchar *message,
- gpointer user_data)
-{
- if (debug || log_level & G_LOG_LEVEL_DEBUG == 0)
- g_log_default_handler (log_domain, log_level, message, user_data);
-}
-
int
main (int argc, char ** argv)
{
g_option_context_parse (context, &argc, &argv, &error);
g_option_context_free (context);
+ logged_levels = G_LOG_LEVEL_MASK & ~(G_LOG_LEVEL_MESSAGE|G_LOG_LEVEL_DEBUG);
+ if (debug)
+ logged_levels = logged_levels | G_LOG_LEVEL_DEBUG;
+ if (verbose)
+ logged_levels = logged_levels | G_LOG_LEVEL_MESSAGE;
+
g_log_set_default_handler (log_handler, NULL);
if (!input)
n_local_entries = g_list_length (module->entries);
restart:
+ init_stats ();
strings = g_hash_table_new (g_str_hash, g_str_equal);
types = g_hash_table_new (g_str_hash, g_str_equal);
n_entries = g_list_length (module->entries);
- g_debug ("%d entries (%d local)\n", n_entries, n_local_entries);
+ g_message ("%d entries (%d local)\n", n_entries, n_local_entries);
dir_size = n_entries * 12;
size = header_size + dir_size;
size += g_idl_node_get_full_size (node);
}
- g_debug ("allocating %d bytes (%d header, %d directory, %d entries)\n",
- size, header_size, dir_size, size - header_size - dir_size);
+ g_message ("allocating %d bytes (%d header, %d directory, %d entries)\n",
+ size, header_size, dir_size, size - header_size - dir_size);
data = g_malloc (size);
/* we picked up implicit xref nodes, start over */
if (i == n_entries)
{
- g_fprintf (stderr, "Found implicit cross references, starting over\n");
+ g_message ("Found implicit cross references, starting over");
+
g_hash_table_destroy (strings);
g_hash_table_destroy (types);
strings = NULL;
entry++;
}
+ dump_stats ();
g_hash_table_destroy (strings);
g_hash_table_destroy (types);
header->annotations = offset2;
+ g_message ("reallocating to %d bytes", offset2);
+
*metadata = g_realloc (data, offset2);
*length = header->size = offset2;
}
#include "gidlnode.h"
#include "gmetadata.h"
+static gulong string_count = 0;
+static gulong unique_string_count = 0;
+static gulong string_size = 0;
+static gulong unique_string_size = 0;
+static gulong types_count = 0;
+static gulong unique_types_count = 0;
+
+void
+init_stats (void)
+{
+ string_count = 0;
+ unique_string_count = 0;
+ string_size = 0;
+ unique_string_size = 0;
+ types_count = 0;
+ unique_types_count = 0;
+}
+
+void
+dump_stats (void)
+{
+ g_message ("%d strings (%d before sharing), %d bytes (%d before sharing)",
+ unique_string_count, string_count, unique_string_size, string_size);
+ g_message ("%d types (%d before sharing)", unique_types_count, types_count);
+}
+
+
#define ALIGN_VALUE(this, boundary) \
(( ((unsigned long)(this)) + (((unsigned long)(boundary)) -1)) & (~(((unsigned long)(boundary))-1)))
{
GList *l;
+ if (node == NULL)
+ return;
+
switch (node->type)
{
case G_IDL_NODE_FUNCTION:
+ case G_IDL_NODE_CALLBACK:
{
GIdlNodeFunction *function = (GIdlNodeFunction *)node;
GIdlNodeType *type = (GIdlNodeType *)node;
g_free (node->name);
- if (type->parameter_type1)
- g_idl_node_free ((GIdlNode *)type->parameter_type1);
- if (type->parameter_type2)
- g_idl_node_free ((GIdlNode *)type->parameter_type2);
+ g_idl_node_free ((GIdlNode *)type->parameter_type1);
+ g_idl_node_free ((GIdlNode *)type->parameter_type2);
g_free (type->interface);
g_strfreev (type->errors);
break;
case G_IDL_NODE_STRUCT:
+ {
+ GIdlNodeStruct *struct_ = (GIdlNodeStruct *)node;
+
+ size = 20;
+ for (l = struct_->members; l; l = l->next)
+ size += g_idl_node_get_size ((GIdlNode *)l->data);
+ }
+ break;
+
case G_IDL_NODE_BOXED:
{
GIdlNodeBoxed *boxed = (GIdlNodeBoxed *)node;
n = g_list_length (iface->interfaces);
size = 32;
- size += ALIGN_VALUE (strlen (iface->parent) + 1, 4);
+ if (iface->parent)
+ size += ALIGN_VALUE (strlen (iface->parent) + 1, 4);
size += ALIGN_VALUE (strlen (node->name) + 1, 4);
size += ALIGN_VALUE (strlen (iface->gtype_name) + 1, 4);
size += ALIGN_VALUE (strlen (iface->gtype_init) + 1, 4);
else if (node->tag == 21)
{
GIdlNode *iface;
+ gchar *name;
iface = find_entry_node (module, modules, node->interface, NULL);
- g_string_append_printf (str, "%s%s",
- iface->name, node->is_pointer ? "*" : "");
+ if (iface)
+ name = iface->name;
+ else
+ {
+ g_warning ("Interface for type reference %s not found", node->interface);
+ name = node->interface;
+ }
+
+ g_string_append_printf (str, "%s%s", name, node->is_pointer ? "*" : "");
}
else if (node->tag == 22)
{
serialize_type (module, modules, type, str);
s = g_string_free (str, FALSE);
+ types_count += 1;
value = g_hash_table_lookup (types, s);
if (value)
{
}
else
{
+ unique_types_count += 1;
g_hash_table_insert (types, s, GINT_TO_POINTER(*offset2));
blob->offset = *offset2;
{
InterfaceBlob *blob = (InterfaceBlob *)&data[*offset];
GIdlNodeInterface *iface = (GIdlNodeInterface *)node;
- gint parent;
blob->blob_type = BLOB_TYPE_INTERFACE;
blob->deprecated = iface->deprecated;
gpointer value;
guint32 start;
+ string_count += 1;
+ string_size += strlen (str);
+
value = g_hash_table_lookup (strings, str);
if (value)
- return GPOINTER_TO_INT (value);
-
+ return GPOINTER_TO_INT (value);
+
+ unique_string_count += 1;
+ unique_string_size += strlen (str);
+
g_hash_table_insert (strings, (gpointer)str, GINT_TO_POINTER (*offset));
start = *offset;
return start;
}
+
guchar *data,
guint32 *offset);
+void init_stats (void);
+void dump_stats (void);
+
G_END_DECLS
#endif /* __G_IDL_NODE_H__ */