[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() */