[vala/staging] codegen: Improve *_get_type() fast path (requires glib >= 2.58)



commit d240befa369200c4f403a4781fd60818578c40a3
Author: Rico Tzschichholz <ricotz ubuntu com>
Date:   Thu Dec 5 14:08:36 2019 +0100

    codegen: Improve *_get_type() fast path (requires glib >= 2.58)
    
    Uses G_GNUC_NO_INLINE if glib >= 2.58 is targetted otherwise the
    compiler is free to inline the separate *_get_type_once() function.
    
    Follows the changes introduced in glib by
    https://gitlab.gnome.org/GNOME/glib/commit/e924f777369710221c3e0a9d7bf40392a27d1fa4
    
    See https://gitlab.gnome.org/GNOME/glib/issues/541
    and https://gitlab.gnome.org/GNOME/vala/issues/879

 ccode/valaccodefunction.vala          |  3 +++
 ccode/valaccodemodifiers.vala         |  3 ++-
 codegen/valatyperegisterfunction.vala | 29 ++++++++++++++++++++++++++---
 3 files changed, 31 insertions(+), 4 deletions(-)
---
diff --git a/ccode/valaccodefunction.vala b/ccode/valaccodefunction.vala
index 688c6d1eb..7d29de9fd 100644
--- a/ccode/valaccodefunction.vala
+++ b/ccode/valaccodefunction.vala
@@ -111,6 +111,9 @@ public class Vala.CCodeFunction : CCodeNode {
                if (CCodeModifiers.INTERNAL in modifiers) {
                        writer.write_string ("G_GNUC_INTERNAL ");
                }
+               if (!is_declaration && CCodeModifiers.NO_INLINE in modifiers) {
+                       writer.write_string ("G_GNUC_NO_INLINE ");
+               }
                if (CCodeModifiers.STATIC in modifiers) {
                        writer.write_string ("static ");
                }
diff --git a/ccode/valaccodemodifiers.vala b/ccode/valaccodemodifiers.vala
index 257423040..7b83b5a91 100644
--- a/ccode/valaccodemodifiers.vala
+++ b/ccode/valaccodemodifiers.vala
@@ -41,5 +41,6 @@ public enum Vala.CCodeModifiers {
        DESTRUCTOR = 1 << 11,
        FORMAT_ARG = 1 << 12,
        PRINTF = 1 << 13,
-       SCANF = 1 << 14
+       SCANF = 1 << 14,
+       NO_INLINE = 1 << 15
 }
diff --git a/codegen/valatyperegisterfunction.vala b/codegen/valatyperegisterfunction.vala
index 23ab2321a..a42069c45 100644
--- a/codegen/valatyperegisterfunction.vala
+++ b/codegen/valatyperegisterfunction.vala
@@ -45,6 +45,7 @@ public abstract class Vala.TypeRegisterFunction {
                string type_id_name = "%s_type_id".printf (get_ccode_lower_case_name (type_symbol));
 
                var type_block = new CCodeBlock ();
+               var type_once_block = new CCodeBlock ();
                CCodeDeclaration cdecl;
                if (!plugin) {
                        cdecl = new CCodeDeclaration ("gsize");
@@ -59,6 +60,7 @@ public abstract class Vala.TypeRegisterFunction {
                }
 
                CCodeFunction fun;
+               CCodeFunction fun_once = null;
                if (!plugin) {
                        fun = new CCodeFunction (get_ccode_type_function (type_symbol), "GType");
                        fun.modifiers = CCodeModifiers.CONST;
@@ -75,6 +77,16 @@ public abstract class Vala.TypeRegisterFunction {
                        fun.is_declaration = true;
                        declaration_fragment.append (fun.copy ());
                        fun.is_declaration = false;
+
+                       fun_once = new CCodeFunction ("%s_once".printf (fun.name), "GType");
+                       fun_once.modifiers = CCodeModifiers.CONST | CCodeModifiers.STATIC;
+                       if (context.require_glib_version (2, 58)) {
+                               fun_once.modifiers |= CCodeModifiers.NO_INLINE;
+                       }
+
+                       fun_once.is_declaration = true;
+                       declaration_fragment.append (fun_once.copy ());
+                       fun_once.is_declaration = false;
                } else {
                        fun = new CCodeFunction ("%s_register_type".printf (get_ccode_lower_case_name 
(type_symbol)), "GType");
                        fun.add_parameter (new CCodeParameter ("module", "GTypeModule *"));
@@ -194,10 +206,14 @@ public abstract class Vala.TypeRegisterFunction {
                        reg_call.add_argument (new CCodeConstant (get_type_flags ()));
                }
 
+               var once_call_block = new CCodeBlock ();
                if (!plugin) {
                        var temp_decl = new CCodeDeclaration ("GType");
                        temp_decl.add_declarator (new CCodeVariableDeclarator (type_id_name, reg_call));
                        type_init.add_statement (temp_decl);
+                       temp_decl = new CCodeDeclaration ("GType");
+                       temp_decl.add_declarator (new CCodeVariableDeclarator (type_id_name, new 
CCodeFunctionCall (new CCodeIdentifier (fun_once.name))));
+                       once_call_block.add_statement (temp_decl);
                } else {
                        type_init.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new 
CCodeIdentifier (type_id_name), reg_call)));
                }
@@ -234,18 +250,25 @@ public abstract class Vala.TypeRegisterFunction {
                        var leave = new CCodeFunctionCall (new CCodeIdentifier ("g_once_init_leave"));
                        leave.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new 
CCodeIdentifier (type_id_name + "__volatile")));
                        leave.add_argument (new CCodeIdentifier (type_id_name));
-                       type_init.add_statement (new CCodeExpressionStatement (leave));
+                       once_call_block.add_statement (new CCodeExpressionStatement (leave));
 
-                       var cif = new CCodeIfStatement (enter, type_init);
+                       var cif = new CCodeIfStatement (enter, once_call_block);
                        type_block.add_statement (cif);
                        type_block.add_statement (new CCodeReturnStatement (new CCodeIdentifier (type_id_name 
+ "__volatile")));
+
+                       type_once_block = type_init;
+                       type_once_block.add_statement (new CCodeReturnStatement (new CCodeIdentifier 
(type_id_name)));
                } else {
                        type_block = type_init;
                        type_block.add_statement (new CCodeReturnStatement (new CCodeIdentifier 
(type_id_name)));
                }
 
-               fun.block = type_block;
+               if (!plugin) {
+                       fun_once.block = type_once_block;
+                       definition_fragment.append (fun_once);
+               }
 
+               fun.block = type_block;
                definition_fragment.append (fun);
        }
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]