mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-02-22 18:22:11 +01:00
gobject: Register a global with the object/interface GType
This makes the G_DEFINE_TYPE(), G_DEFINE_INTERFACE() and similar variants provide a TypeName##_type_id global simimlar to how the private offset is stored as a global. What this allows for, is for applications and libraries which have high demand on the type system to have an escape hatch to improve performance. It has been observed that most of the type checking comes from inside the same module that implements the type. Therefore, if that source file can access the GType without an external call to the get_type() function, the overhead can be reduced to an address load. For example, this is used in libdex heavily to ensure that get_type() do not show up in performance profiles. This is done by redefining the type macro to use the global variable. #undef FOO_TYPE_BAR #define FOO_TYPE_BAR FooBar_type_id The one place where you need to be careful of this is the new function which may cause the registration of the type if global registration at library/application startup is not performed. Additionally, if using new-style G_DECLARE_* macros, you may also want to override the IS_TYPE() macro to use the fast path. #define FOO_IS_BAR(obj) G_TYPE_CHECK_INSTANCE_TYPE(obj, FOO_TYPE_BAR) On this system, this can have a wild performance implication. For example, the type check for GDBusMessage when dragging a window around in GNOME Shell and activating the overview had a whopping 2.96% of samples.
This commit is contained in:
parent
8810cf7a24
commit
afa562c832
@ -2285,6 +2285,7 @@ static void type_name##_class_init (TypeName##Class *klass); \
|
||||
static GType type_name##_get_type_once (void); \
|
||||
static gpointer type_name##_parent_class = NULL; \
|
||||
static gint TypeName##_private_offset; \
|
||||
static GType TypeName##_type_id; \
|
||||
\
|
||||
_G_DEFINE_TYPE_EXTENDED_CLASS_INIT(TypeName, type_name) \
|
||||
\
|
||||
@ -2306,6 +2307,7 @@ type_name##_get_type (void) \
|
||||
if (_g_type_once_init_enter (&static_g_define_type_id)) \
|
||||
{ \
|
||||
GType g_define_type_id = type_name##_get_type_once (); \
|
||||
TypeName##_type_id = g_define_type_id; \
|
||||
_g_type_once_init_leave (&static_g_define_type_id, g_define_type_id); \
|
||||
} \
|
||||
return static_g_define_type_id; \
|
||||
@ -2342,6 +2344,7 @@ type_name##_get_type_once (void) \
|
||||
#define _G_DEFINE_INTERFACE_EXTENDED_BEGIN(TypeName, type_name, TYPE_PREREQ) \
|
||||
\
|
||||
static void type_name##_default_init (TypeName##Interface *klass); \
|
||||
static GType TypeName##_type_id; \
|
||||
\
|
||||
GType \
|
||||
type_name##_get_type (void) \
|
||||
@ -2357,6 +2360,7 @@ type_name##_get_type (void) \
|
||||
0, \
|
||||
(GInstanceInitFunc)NULL, \
|
||||
(GTypeFlags) 0); \
|
||||
TypeName##_type_id = g_define_type_id; \
|
||||
if (TYPE_PREREQ != G_TYPE_INVALID) \
|
||||
g_type_interface_add_prerequisite (g_define_type_id, TYPE_PREREQ); \
|
||||
{ /* custom code follows */
|
||||
|
Loading…
x
Reference in New Issue
Block a user