[GLIB] improve get_type() fast path in WEBKIT_DEFINE_TYPE
https://bugs.webkit.org/show_bug.cgi?id=186885
Reviewed by Anders Carlsson.
This is a backport of glib commit
https://gitlab.gnome.org/GNOME/glib/commit/e924f777369710221c3e0a9d7bf40392a27d1fa4
"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."
* wtf/glib/WTFGType.h:
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@233071 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/WTF/ChangeLog b/Source/WTF/ChangeLog
index 63c500a..42022b3 100644
--- a/Source/WTF/ChangeLog
+++ b/Source/WTF/ChangeLog
@@ -1,3 +1,29 @@
+2018-06-21 Carlos Garcia Campos <cgarcia@igalia.com>
+
+ [GLIB] improve get_type() fast path in WEBKIT_DEFINE_TYPE
+ https://bugs.webkit.org/show_bug.cgi?id=186885
+
+ Reviewed by Anders Carlsson.
+
+ This is a backport of glib commit
+ https://gitlab.gnome.org/GNOME/glib/commit/e924f777369710221c3e0a9d7bf40392a27d1fa4
+
+ "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."
+
+ * wtf/glib/WTFGType.h:
+
2018-06-20 Yusuke Suzuki <utatane.tea@gmail.com>
[GTK][WPE][Nicosia] Add name for Nicosia Painting Threads
diff --git a/Source/WTF/wtf/glib/WTFGType.h b/Source/WTF/wtf/glib/WTFGType.h
index 7f1cf4d..203522e 100644
--- a/Source/WTF/wtf/glib/WTFGType.h
+++ b/Source/WTF/wtf/glib/WTFGType.h
@@ -20,6 +20,7 @@
#pragma once
#include <glib.h>
+#include <wtf/Compiler.h>
#define WEBKIT_PARAM_READABLE (static_cast<GParamFlags>(G_PARAM_READABLE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB))
#define WEBKIT_PARAM_WRITABLE (static_cast<GParamFlags>(G_PARAM_WRITABLE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB))
@@ -46,6 +47,7 @@
#define _WEBKIT_DEFINE_TYPE_EXTENDED_BEGIN(TypeName, type_name, TYPE_PARENT, flags) \
\
static void type_name##_class_init(TypeName##Class* klass); \
+static GType type_name##_get_type_once(void); \
static gpointer type_name##_parent_class = 0; \
static void type_name##_finalize(GObject* object) \
{ \
@@ -68,23 +70,30 @@
TypeName##Private* priv = G_TYPE_INSTANCE_GET_PRIVATE(self, type_name##_get_type(), TypeName##Private); \
self->priv = priv; \
new (priv) TypeName##Private(); \
-}\
+} \
+\
GType type_name##_get_type(void) \
{ \
static volatile gsize g_define_type_id__volatile = 0; \
if (g_once_init_enter(&g_define_type_id__volatile)) { \
- GType g_define_type_id = \
- g_type_register_static_simple( \
- TYPE_PARENT, \
- g_intern_static_string(#TypeName), \
- sizeof(TypeName##Class), \
- (GClassInitFunc)type_name##_class_intern_init, \
- sizeof(TypeName), \
- (GInstanceInitFunc)type_name##_init, \
- (GTypeFlags)flags); \
- // Custom code follows.
-#define _WEBKIT_DEFINE_TYPE_EXTENDED_END() \
+ 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().
+} /* Closes type_name##_get_type(). */ \
+\
+NEVER_INLINE static GType type_name##_get_type_once(void) \
+{ \
+ GType g_define_type_id = \
+ g_type_register_static_simple( \
+ TYPE_PARENT, \
+ g_intern_static_string(#TypeName), \
+ sizeof(TypeName##Class), \
+ (GClassInitFunc)(void (*)(void))type_name##_class_intern_init, \
+ sizeof(TypeName), \
+ (GInstanceInitFunc)(void (*)(void))type_name##_init, \
+ (GTypeFlags)flags); \
+ /* Custom code follows. */
+#define _WEBKIT_DEFINE_TYPE_EXTENDED_END() \
+ return g_define_type_id; \
+} /* Closes type_name##_get_type_once() */