mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-02-24 11:12:11 +01:00
gtype: improve get_type fast path
The -fstack-protector-strong used in many distributions by default has a rather drastic slowdown of the fast path in generated _get_type() functions using G_DEFINE_* macros. The amount can vary by architecture, GCC version, and compiler flags. To work around this, and ensure a higher probability that our fast-path will match what we had previously, we need to break out the slow-path (registering the type) into a secondary function that is not a candidate for inlining. This ensures that the common case (type registered, return the GType id) is the hot path and handled in the prologue of the generated assembly even when -fstack-protector-strong is enabled. https://bugzilla.gnome.org/show_bug.cgi?id=795180
This commit is contained in:
parent
ede5c3f8d9
commit
e924f77736
@ -1948,6 +1948,7 @@ static void type_name##_class_intern_init (gpointer klass) \
|
|||||||
\
|
\
|
||||||
static void type_name##_init (TypeName *self); \
|
static void type_name##_init (TypeName *self); \
|
||||||
static void type_name##_class_init (TypeName##Class *klass); \
|
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 gpointer type_name##_parent_class = NULL; \
|
||||||
static gint TypeName##_private_offset; \
|
static gint TypeName##_private_offset; \
|
||||||
\
|
\
|
||||||
@ -1969,6 +1970,16 @@ type_name##_get_type (void) \
|
|||||||
/* Added for _G_DEFINE_TYPE_EXTENDED_WITH_PRELUDE */
|
/* Added for _G_DEFINE_TYPE_EXTENDED_WITH_PRELUDE */
|
||||||
#define _G_DEFINE_TYPE_EXTENDED_BEGIN_REGISTER(TypeName, type_name, TYPE_PARENT, flags) \
|
#define _G_DEFINE_TYPE_EXTENDED_BEGIN_REGISTER(TypeName, type_name, TYPE_PARENT, flags) \
|
||||||
if (g_once_init_enter (&g_define_type_id__volatile)) \
|
if (g_once_init_enter (&g_define_type_id__volatile)) \
|
||||||
|
{ \
|
||||||
|
GType g_define_type_id = type_name##_get_type_once (); \
|
||||||
|
g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); \
|
||||||
|
} \
|
||||||
|
return g_define_type_id__volatile; \
|
||||||
|
} /* closes type_name##_get_type() */ \
|
||||||
|
\
|
||||||
|
G_GNUC_NO_INLINE \
|
||||||
|
static GType \
|
||||||
|
type_name##_get_type_once (void) \
|
||||||
{ \
|
{ \
|
||||||
GType g_define_type_id = \
|
GType g_define_type_id = \
|
||||||
g_type_register_static_simple (TYPE_PARENT, \
|
g_type_register_static_simple (TYPE_PARENT, \
|
||||||
@ -1982,10 +1993,8 @@ type_name##_get_type (void) \
|
|||||||
#define _G_DEFINE_TYPE_EXTENDED_END() \
|
#define _G_DEFINE_TYPE_EXTENDED_END() \
|
||||||
/* following custom code */ \
|
/* following custom code */ \
|
||||||
} \
|
} \
|
||||||
g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); \
|
return g_define_type_id; \
|
||||||
} \
|
} /* closes type_name##_get_type_once() */
|
||||||
return g_define_type_id__volatile; \
|
|
||||||
} /* closes type_name##_get_type() */
|
|
||||||
|
|
||||||
/* This was defined before we had G_DEFINE_TYPE_WITH_CODE_AND_PRELUDE, it's simplest
|
/* This was defined before we had G_DEFINE_TYPE_WITH_CODE_AND_PRELUDE, it's simplest
|
||||||
* to keep it.
|
* to keep it.
|
||||||
@ -2070,11 +2079,23 @@ type_name##_get_type (void) \
|
|||||||
*/
|
*/
|
||||||
#if !defined (__cplusplus) && (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 7)) && !(defined (__APPLE__) && defined (__ppc64__))
|
#if !defined (__cplusplus) && (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 7)) && !(defined (__APPLE__) && defined (__ppc64__))
|
||||||
#define _G_DEFINE_BOXED_TYPE_BEGIN(TypeName, type_name, copy_func, free_func) \
|
#define _G_DEFINE_BOXED_TYPE_BEGIN(TypeName, type_name, copy_func, free_func) \
|
||||||
|
static GType type_name##_get_type_once (void); \
|
||||||
|
\
|
||||||
GType \
|
GType \
|
||||||
type_name##_get_type (void) \
|
type_name##_get_type (void) \
|
||||||
{ \
|
{ \
|
||||||
static volatile gsize g_define_type_id__volatile = 0; \
|
static volatile gsize g_define_type_id__volatile = 0; \
|
||||||
if (g_once_init_enter (&g_define_type_id__volatile)) \
|
if (g_once_init_enter (&g_define_type_id__volatile)) \
|
||||||
|
{ \
|
||||||
|
GType g_define_type_id = type_name##_get_type_once (); \
|
||||||
|
g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); \
|
||||||
|
} \
|
||||||
|
return g_define_type_id__volatile; \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
G_GNUC_NO_INLINE \
|
||||||
|
static GType \
|
||||||
|
type_name##_get_type_once (void) \
|
||||||
{ \
|
{ \
|
||||||
GType (* _g_register_boxed) \
|
GType (* _g_register_boxed) \
|
||||||
(const gchar *, \
|
(const gchar *, \
|
||||||
@ -2095,11 +2116,23 @@ type_name##_get_type (void) \
|
|||||||
{ /* custom code follows */
|
{ /* custom code follows */
|
||||||
#else
|
#else
|
||||||
#define _G_DEFINE_BOXED_TYPE_BEGIN(TypeName, type_name, copy_func, free_func) \
|
#define _G_DEFINE_BOXED_TYPE_BEGIN(TypeName, type_name, copy_func, free_func) \
|
||||||
|
static GType type_name##_get_type_once (void); \
|
||||||
|
\
|
||||||
GType \
|
GType \
|
||||||
type_name##_get_type (void) \
|
type_name##_get_type (void) \
|
||||||
{ \
|
{ \
|
||||||
static volatile gsize g_define_type_id__volatile = 0; \
|
static volatile gsize g_define_type_id__volatile = 0; \
|
||||||
if (g_once_init_enter (&g_define_type_id__volatile)) \
|
if (g_once_init_enter (&g_define_type_id__volatile)) \
|
||||||
|
{ \
|
||||||
|
GType g_define_type_id = type_name##_get_type_once (); \
|
||||||
|
g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); \
|
||||||
|
} \
|
||||||
|
return g_define_type_id__volatile; \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
G_GNUC_NO_INLINE \
|
||||||
|
static GType \
|
||||||
|
type_name##_get_type_once (void) \
|
||||||
{ \
|
{ \
|
||||||
GType g_define_type_id = \
|
GType g_define_type_id = \
|
||||||
g_boxed_type_register_static (g_intern_static_string (#TypeName), \
|
g_boxed_type_register_static (g_intern_static_string (#TypeName), \
|
||||||
@ -2136,11 +2169,23 @@ type_name##_get_type (void) \
|
|||||||
#define G_DEFINE_POINTER_TYPE_WITH_CODE(TypeName, type_name, _C_) _G_DEFINE_POINTER_TYPE_BEGIN (TypeName, type_name) {_C_;} _G_DEFINE_TYPE_EXTENDED_END()
|
#define G_DEFINE_POINTER_TYPE_WITH_CODE(TypeName, type_name, _C_) _G_DEFINE_POINTER_TYPE_BEGIN (TypeName, type_name) {_C_;} _G_DEFINE_TYPE_EXTENDED_END()
|
||||||
|
|
||||||
#define _G_DEFINE_POINTER_TYPE_BEGIN(TypeName, type_name) \
|
#define _G_DEFINE_POINTER_TYPE_BEGIN(TypeName, type_name) \
|
||||||
|
static GType type_name##_get_type_once (void); \
|
||||||
|
\
|
||||||
GType \
|
GType \
|
||||||
type_name##_get_type (void) \
|
type_name##_get_type (void) \
|
||||||
{ \
|
{ \
|
||||||
static volatile gsize g_define_type_id__volatile = 0; \
|
static volatile gsize g_define_type_id__volatile = 0; \
|
||||||
if (g_once_init_enter (&g_define_type_id__volatile)) \
|
if (g_once_init_enter (&g_define_type_id__volatile)) \
|
||||||
|
{ \
|
||||||
|
GType g_define_type_id = type_name##_get_type_once (); \
|
||||||
|
g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); \
|
||||||
|
} \
|
||||||
|
return g_define_type_id__volatile; \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
G_GNUC_NO_INLINE \
|
||||||
|
static GType \
|
||||||
|
type_name##_get_type_once (void) \
|
||||||
{ \
|
{ \
|
||||||
GType g_define_type_id = \
|
GType g_define_type_id = \
|
||||||
g_pointer_type_register_static (g_intern_static_string (#TypeName)); \
|
g_pointer_type_register_static (g_intern_static_string (#TypeName)); \
|
||||||
|
Loading…
x
Reference in New Issue
Block a user