[glib/gobject-speedups3: 7/7] Avoid malloc for construct params




commit ecc641de710e226a979e1a3e9e2fe605b480a490
Author: Matthias Clasen <mclasen redhat com>
Date:   Thu May 26 09:47:10 2022 -0400

    Avoid malloc for construct params
    
    Stack-allocate the GObjectConstructParams (except for
    extreme cases), for a small speedup of object construction.

 gobject/gobject.c | 27 ++++++++++++++++++++++-----
 1 file changed, 22 insertions(+), 5 deletions(-)
---
diff --git a/gobject/gobject.c b/gobject/gobject.c
index e44494b13d..ef62a03fa8 100644
--- a/gobject/gobject.c
+++ b/gobject/gobject.c
@@ -1881,6 +1881,7 @@ g_object_new_with_custom_constructor (GObjectClass          *class,
   GObjectNotifyQueue *nqueue = NULL;
   gboolean newly_constructed;
   GObjectConstructParam *cparams;
+  gboolean free_cparams = FALSE;
   GObject *object;
   GValue *cvalues;
   gint cvals_used;
@@ -1897,9 +1898,21 @@ g_object_new_with_custom_constructor (GObjectClass          *class,
    * while their constructor() is running.
    */
 
-  /* Create the array of GObjectConstructParams for constructor() */
-  cparams = g_new (GObjectConstructParam, class->n_construct_properties);
-  cvalues = g_new0 (GValue, class->n_construct_properties);
+  /* Create the array of GObjectConstructParams for constructor(),
+   * The 1024 here is an arbitrary, high limit that no sane code
+   * will ever hit, just to avoid the possibility of stack overflow.
+   */
+  if (G_LIKELY (class->n_construct_properties < 1024))
+    {
+      cparams = g_newa0 (GObjectConstructParam, class->n_construct_properties);
+      cvalues = g_newa0 (GValue, class->n_construct_properties);
+    }
+  else
+    {
+      cparams = g_new0 (GObjectConstructParam, class->n_construct_properties);
+      cvalues = g_new0 (GValue, class->n_construct_properties);
+      free_cparams = TRUE;
+    }
   cvals_used = 0;
   i = 0;
 
@@ -1942,10 +1955,14 @@ g_object_new_with_custom_constructor (GObjectClass          *class,
   /* construct object from construction parameters */
   object = class->constructor (class->g_type_class.g_type, class->n_construct_properties, cparams);
   /* free construction values */
-  g_free (cparams);
   while (cvals_used--)
     g_value_unset (&cvalues[cvals_used]);
-  g_free (cvalues);
+
+  if (free_cparams)
+    {
+      g_free (cparams);
+      g_free (cvalues);
+    }
 
   /* There is code in the wild that relies on being able to return NULL
    * from its custom constructor.  This was never a supported operation,


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