mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2024-12-25 23:16:14 +01:00
added optimizations to skip NOP signal emissions.
Tue Aug 19 01:31:28 2003 Tim Janik <timj@gtk.org> * gsignal.c: added optimizations to skip NOP signal emissions.
This commit is contained in:
parent
b1b9636b73
commit
779c44cdfb
@ -1,3 +1,7 @@
|
|||||||
|
Tue Aug 19 01:31:28 2003 Tim Janik <timj@gtk.org>
|
||||||
|
|
||||||
|
* gsignal.c: added optimizations to skip NOP signal emissions.
|
||||||
|
|
||||||
Wed Aug 6 09:57:14 2003 Owen Taylor <otaylor@redhat.com>
|
Wed Aug 6 09:57:14 2003 Owen Taylor <otaylor@redhat.com>
|
||||||
|
|
||||||
* testgobject.c (test_signal_accumulator): Add check
|
* testgobject.c (test_signal_accumulator): Add check
|
||||||
|
@ -175,6 +175,7 @@ struct _SignalNode
|
|||||||
guint destroyed : 1;
|
guint destroyed : 1;
|
||||||
|
|
||||||
/* reinitializable portion */
|
/* reinitializable portion */
|
||||||
|
guint test_class_offset : 12;
|
||||||
guint flags : 8;
|
guint flags : 8;
|
||||||
guint n_params : 8;
|
guint n_params : 8;
|
||||||
GType *param_types; /* mangled with G_SIGNAL_TYPE_STATIC_SCOPE flag */
|
GType *param_types; /* mangled with G_SIGNAL_TYPE_STATIC_SCOPE flag */
|
||||||
@ -184,6 +185,8 @@ struct _SignalNode
|
|||||||
GSignalCMarshaller c_marshaller;
|
GSignalCMarshaller c_marshaller;
|
||||||
GHookList *emission_hooks;
|
GHookList *emission_hooks;
|
||||||
};
|
};
|
||||||
|
#define MAX_TEST_CLASS_OFFSET (4096) /* 2^12, 12 bits for test_class_offset */
|
||||||
|
#define TEST_CLASS_MAGIC (1) /* indicates NULL class closure, candidate for NOP optimization */
|
||||||
|
|
||||||
struct _SignalKey
|
struct _SignalKey
|
||||||
{
|
{
|
||||||
@ -1124,6 +1127,18 @@ g_signal_new (const gchar *signal_name,
|
|||||||
return_type, n_params, args);
|
return_type, n_params, args);
|
||||||
|
|
||||||
va_end (args);
|
va_end (args);
|
||||||
|
|
||||||
|
/* optimize NOP emissions with NULL class handlers */
|
||||||
|
if (signal_id && G_TYPE_IS_INSTANTIATABLE (itype) && return_type == G_TYPE_NONE &&
|
||||||
|
class_offset && class_offset < MAX_TEST_CLASS_OFFSET)
|
||||||
|
{
|
||||||
|
SignalNode *node;
|
||||||
|
|
||||||
|
SIGNAL_LOCK ();
|
||||||
|
node = LOOKUP_SIGNAL_NODE (signal_id);
|
||||||
|
node->test_class_offset = class_offset;
|
||||||
|
SIGNAL_UNLOCK ();
|
||||||
|
}
|
||||||
|
|
||||||
return signal_id;
|
return signal_id;
|
||||||
}
|
}
|
||||||
@ -1174,6 +1189,9 @@ signal_add_class_closure (SignalNode *node,
|
|||||||
{
|
{
|
||||||
ClassClosure key;
|
ClassClosure key;
|
||||||
|
|
||||||
|
/* can't optimize NOP emissions with overridden class closures */
|
||||||
|
node->test_class_offset = 0;
|
||||||
|
|
||||||
if (!node->class_closure_bsa)
|
if (!node->class_closure_bsa)
|
||||||
node->class_closure_bsa = g_bsearch_array_new (&g_class_closure_bconfig);
|
node->class_closure_bsa = g_bsearch_array_new (&g_class_closure_bconfig);
|
||||||
key.instance_type = itype;
|
key.instance_type = itype;
|
||||||
@ -1288,7 +1306,8 @@ g_signal_newv (const gchar *signal_name,
|
|||||||
g_signal_key_bsa = g_bsearch_array_insert (g_signal_key_bsa, &g_signal_key_bconfig, &key, FALSE);
|
g_signal_key_bsa = g_bsearch_array_insert (g_signal_key_bsa, &g_signal_key_bconfig, &key, FALSE);
|
||||||
}
|
}
|
||||||
node->destroyed = FALSE;
|
node->destroyed = FALSE;
|
||||||
|
node->test_class_offset = 0;
|
||||||
|
|
||||||
/* setup reinitializable portion */
|
/* setup reinitializable portion */
|
||||||
node->flags = signal_flags & G_SIGNAL_FLAGS_MASK;
|
node->flags = signal_flags & G_SIGNAL_FLAGS_MASK;
|
||||||
node->n_params = n_params;
|
node->n_params = n_params;
|
||||||
@ -1307,6 +1326,11 @@ g_signal_newv (const gchar *signal_name,
|
|||||||
node->emission_hooks = NULL;
|
node->emission_hooks = NULL;
|
||||||
if (class_closure)
|
if (class_closure)
|
||||||
signal_add_class_closure (node, 0, class_closure);
|
signal_add_class_closure (node, 0, class_closure);
|
||||||
|
else if (G_TYPE_IS_INSTANTIATABLE (itype) && return_type == G_TYPE_NONE)
|
||||||
|
{
|
||||||
|
/* optimize NOP emissions */
|
||||||
|
node->test_class_offset = TEST_CLASS_MAGIC;
|
||||||
|
}
|
||||||
SIGNAL_UNLOCK ();
|
SIGNAL_UNLOCK ();
|
||||||
|
|
||||||
return signal_id;
|
return signal_id;
|
||||||
@ -1354,6 +1378,7 @@ signal_destroy_R (SignalNode *signal_node)
|
|||||||
signal_node->destroyed = TRUE;
|
signal_node->destroyed = TRUE;
|
||||||
|
|
||||||
/* reentrancy caution, zero out real contents first */
|
/* reentrancy caution, zero out real contents first */
|
||||||
|
signal_node->test_class_offset = 0;
|
||||||
signal_node->n_params = 0;
|
signal_node->n_params = 0;
|
||||||
signal_node->param_types = NULL;
|
signal_node->param_types = NULL;
|
||||||
signal_node->return_type = 0;
|
signal_node->return_type = 0;
|
||||||
@ -1947,6 +1972,50 @@ g_signal_has_handler_pending (gpointer instance,
|
|||||||
return has_pending;
|
return has_pending;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline gboolean
|
||||||
|
signal_check_skip_emission (SignalNode *node,
|
||||||
|
gpointer instance,
|
||||||
|
GQuark detail)
|
||||||
|
{
|
||||||
|
HandlerList *hlist;
|
||||||
|
|
||||||
|
/* are we able to check for NULL class handlers? */
|
||||||
|
if (!node->test_class_offset)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
/* are there emission hooks pending? */
|
||||||
|
if (node->emission_hooks && node->emission_hooks->hooks)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
/* is there a non-NULL class handler? */
|
||||||
|
if (node->test_class_offset != TEST_CLASS_MAGIC)
|
||||||
|
{
|
||||||
|
GTypeClass *class = G_TYPE_INSTANCE_GET_CLASS (instance, G_TYPE_FROM_INSTANCE (instance), GTypeClass);
|
||||||
|
|
||||||
|
if (G_STRUCT_MEMBER (gpointer, class, node->test_class_offset))
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* are signals being debugged? */
|
||||||
|
#ifdef G_ENABLE_DEBUG
|
||||||
|
IF_DEBUG (SIGNALS, g_trace_instance_signals || g_trap_instance_signals)
|
||||||
|
return FALSE;
|
||||||
|
#endif /* G_ENABLE_DEBUG */
|
||||||
|
|
||||||
|
/* is this a no-recurse signal already in emission? */
|
||||||
|
if (node->flags & G_SIGNAL_NO_RECURSE &&
|
||||||
|
emission_find (g_restart_emissions, node->signal_id, detail, instance))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
/* do we have pending handlers? */
|
||||||
|
hlist = handler_list_lookup (node->signal_id, instance);
|
||||||
|
if (hlist && hlist->handlers)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
/* none of the above, no emission required */
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
g_signal_emitv (const GValue *instance_and_params,
|
g_signal_emitv (const GValue *instance_and_params,
|
||||||
guint signal_id,
|
guint signal_id,
|
||||||
@ -2020,6 +2089,15 @@ g_signal_emitv (const GValue *instance_and_params,
|
|||||||
return_value = NULL;
|
return_value = NULL;
|
||||||
#endif /* G_ENABLE_DEBUG */
|
#endif /* G_ENABLE_DEBUG */
|
||||||
|
|
||||||
|
/* optimize NOP emissions */
|
||||||
|
if (signal_check_skip_emission (node, instance, detail))
|
||||||
|
{
|
||||||
|
/* nothing to do to emit this signal */
|
||||||
|
SIGNAL_UNLOCK ();
|
||||||
|
/* g_printerr ("omitting emission of \"%s\"\n", node->name); */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
SIGNAL_UNLOCK ();
|
SIGNAL_UNLOCK ();
|
||||||
signal_emit_unlocked_R (node, detail, instance, return_value, instance_and_params);
|
signal_emit_unlocked_R (node, detail, instance, return_value, instance_and_params);
|
||||||
}
|
}
|
||||||
@ -2056,6 +2134,15 @@ g_signal_emit_valist (gpointer instance,
|
|||||||
}
|
}
|
||||||
#endif /* !G_DISABLE_CHECKS */
|
#endif /* !G_DISABLE_CHECKS */
|
||||||
|
|
||||||
|
/* optimize NOP emissions */
|
||||||
|
if (signal_check_skip_emission (node, instance, detail))
|
||||||
|
{
|
||||||
|
/* nothing to do to emit this signal */
|
||||||
|
SIGNAL_UNLOCK ();
|
||||||
|
/* g_printerr ("omitting emission of \"%s\"\n", node->name); */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
n_params = node->n_params;
|
n_params = node->n_params;
|
||||||
signal_return_type = node->return_type;
|
signal_return_type = node->return_type;
|
||||||
if (node->n_params < MAX_STACK_VALUES)
|
if (node->n_params < MAX_STACK_VALUES)
|
||||||
|
Loading…
Reference in New Issue
Block a user