Avoid some allocations
authorRaja R Harinath <harinath@hurrynot.org>
Wed, 28 Jan 2009 07:30:59 +0000 (07:30 -0000)
committerRaja R Harinath <harinath@hurrynot.org>
Wed, 28 Jan 2009 07:30:59 +0000 (07:30 -0000)
* class-internals.h (_MonoGenericInst::type_argv): Convert from
pointer to tail array to avoid extra allocation.
* metadata.c (free_generic_inst): Update to changes.
(mono_metadata_get_generic_inst): Likewise.  Use alloca instead of
on-stack struct.

This adds a blit to get_generic_inst as compared to the original version.
However, both arms of the 'if' in there traverse the 'type_argv' array
_fully_ with 'for' loops, recursion and whatnot; the extra blit is unlikely
to add overhead.

svn path=/trunk/mono/; revision=124754

mono/metadata/ChangeLog
mono/metadata/class-internals.h
mono/metadata/metadata.c

index 39eac43898de90986bed8a6ae5f72f0c94e367c9..0ad5548248574cc024e6cdb67e11c39f553c472b 100644 (file)
@@ -1,3 +1,12 @@
+2009-01-28  Raja R Harinath  <harinath@hurrynot.org>
+
+       Avoid some allocations
+       * class-internals.h (_MonoGenericInst::type_argv): Convert from
+       pointer to tail array to avoid extra allocation.
+       * metadata.c (free_generic_inst): Update to changes.
+       (mono_metadata_get_generic_inst): Likewise.  Use alloca instead of
+       on-stack struct.
+
 2009-01-27  Zoltan Varga  <vargaz@gmail.com>
 
        * icall.c (ves_icall_System_Type_EqualsInternal): For user-defined types,
index cd927318b3f8ecf5a85ea810867d54e6cdee8e93..911108a01ebb806f08d35bbc2a70644760a13853 100644 (file)
@@ -431,7 +431,7 @@ struct _MonoGenericInst {
        guint id;                       /* unique ID for debugging */
        guint type_argc    : 22;        /* number of type arguments */
        guint is_open      :  1;        /* if this is an open type */
-       MonoType **type_argv;
+       MonoType *type_argv [MONO_ZERO_LEN_ARRAY];
 };
 
 /*
index 2f1dbf8fb226d7491da66299235c20cf8b0f2090..145124d2f443e5c4d3691b0498e94c10397a1a6c 100644 (file)
@@ -2257,7 +2257,6 @@ free_generic_inst (MonoGenericInst *ginst)
 
        for (i = 0; i < ginst->type_argc; ++i)
                mono_metadata_free_type (ginst->type_argv [i]);
-       g_free (ginst->type_argv);
        g_free (ginst);
 }
 
@@ -2376,40 +2375,37 @@ MonoGenericInst *
 mono_metadata_get_generic_inst (int type_argc, MonoType **type_argv)
 {
        MonoGenericInst *ginst;
-       MonoGenericInst helper;
+       gboolean is_open;
        int i;
-
-       helper.type_argc = type_argc;
-       helper.type_argv = type_argv;
-       helper.id = 0;
+       int size = sizeof (MonoGenericInst) + (type_argc - MONO_ZERO_LEN_ARRAY) * sizeof (MonoType *);
 
        for (i = 0; i < type_argc; ++i)
                if (mono_class_is_open_constructed_type (type_argv [i]))
                        break;
-       helper.is_open = (i < type_argc);
+       is_open = (i < type_argc);
+
+       ginst = alloca (size);
+       ginst->id = 0;
+       ginst->is_open = is_open;
+       ginst->type_argc = type_argc;
+       memcpy (ginst->type_argv, type_argv, type_argc * sizeof (MonoType *));
 
-       /*dump_ginst (&helper);*/
        mono_loader_lock ();
-       ginst = g_hash_table_lookup (generic_inst_cache, &helper);
-       if (ginst) {
-               mono_loader_unlock ();
-               /*g_print (" found cached\n");*/
-               return ginst;
-       }
 
-       ginst = g_new0 (MonoGenericInst, 1);
-       ginst->type_argc = type_argc;
-       ginst->type_argv = g_new (MonoType*, type_argc);
-       ginst->id = ++next_generic_inst_id;
-       ginst->is_open = helper.is_open;
+       ginst = g_hash_table_lookup (generic_inst_cache, ginst);
+       if (!ginst) {
+               ginst = g_malloc (size);
+               ginst->id = ++next_generic_inst_id;
+               ginst->is_open = is_open;
+               ginst->type_argc = type_argc;
 
-       for (i = 0; i < type_argc; ++i)
-               ginst->type_argv [i] = mono_metadata_type_dup (NULL, type_argv [i]);
+               for (i = 0; i < type_argc; ++i)
+                       ginst->type_argv [i] = mono_metadata_type_dup (NULL, type_argv [i]);
 
-       g_hash_table_insert (generic_inst_cache, ginst, ginst);
+               g_hash_table_insert (generic_inst_cache, ginst, ginst);
+       }
 
        mono_loader_unlock ();
-       /*g_print (" inserted\n");*/
        return ginst;
 }