2010-01-15 Zoltan Varga <vargaz@gmail.com>
authorZoltan Varga <vargaz@gmail.com>
Fri, 15 Jan 2010 05:29:42 +0000 (05:29 -0000)
committerZoltan Varga <vargaz@gmail.com>
Fri, 15 Jan 2010 05:29:42 +0000 (05:29 -0000)
* metadata.c (mono_metadata_str_hash): New helper function to compute a stable
hash value which doesn't depend on glib/eglib versions.
(mono_metadata_type_hash): Use it.

* object.c (mono_method_get_imt_slot): Ditto.

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

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

index 9be73fdb5e9da8fdf7bc85329b585fb903ad6bb6..6181d59665cc188c83a251aa6dbcb9e51061f31a 100644 (file)
@@ -1,3 +1,11 @@
+2010-01-15  Zoltan Varga  <vargaz@gmail.com>
+
+       * metadata.c (mono_metadata_str_hash): New helper function to compute a stable
+       hash value which doesn't depend on glib/eglib versions.
+       (mono_metadata_type_hash): Use it.
+
+       * object.c (mono_method_get_imt_slot): Ditto.
+
 2010-01-14  Rodrigo Kumpera  <rkumpera@novell.com>
 
        * class.c (mono_type_has_exceptions): Check the generic instance. It can fail
index 95d809452a7be2d6944ea694f788bbdddc4d1a38..d6c35861d7985ffacb7d0446677e750d2d316930 100644 (file)
@@ -590,6 +590,8 @@ mono_metadata_get_corresponding_property_from_generic_type_definition (MonoPrope
 guint32
 mono_metadata_signature_size (MonoMethodSignature *sig) MONO_INTERNAL;
 
+guint mono_metadata_str_hash (gconstpointer v1) MONO_INTERNAL;
+
 gboolean mono_image_load_pe_data (MonoImage *image) MONO_INTERNAL;
 
 gboolean mono_image_load_cli_data (MonoImage *image) MONO_INTERNAL;
index 0a795b93b971b06b3b6c121ed65aaa8b367c4acf..9755987a5532d7adad727115bf38a50e81ce5d02 100644 (file)
@@ -4381,11 +4381,34 @@ mono_metadata_generic_context_equal (const MonoGenericContext *g1, const MonoGen
        return g1->class_inst == g2->class_inst && g1->method_inst == g2->method_inst;
 }
 
+/*
+ * mono_metadata_str_hash:
+ *
+ *   This should be used instead of g_str_hash for computing hash codes visible
+ * outside this module, since g_str_hash () is not guaranteed to be stable
+ * (its not the same in eglib for example).
+ */
+guint
+mono_metadata_str_hash (gconstpointer v1)
+{
+       /* Same as g_str_hash () in glib */
+       char *p = (char *) v1;
+       guint hash = *p;
+
+       while (*p++) {
+               if (*p)
+                       hash = (hash << 5) - hash + *p;
+       }
+
+       return hash;
+} 
+
 /*
  * mono_metadata_type_hash:
  * @t1: a type
  *
  * Computes an hash value for @t1 to be used in GHashTable.
+ * The returned hash is guaranteed to be the same across executions.
  */
 guint
 mono_metadata_type_hash (MonoType *t1)
@@ -4398,7 +4421,7 @@ mono_metadata_type_hash (MonoType *t1)
        case MONO_TYPE_CLASS:
        case MONO_TYPE_SZARRAY:
                /* check if the distribution is good enough */
-               return ((hash << 5) - hash) ^ g_str_hash (t1->data.klass->name);
+               return ((hash << 5) - hash) ^ mono_metadata_str_hash (t1->data.klass->name);
        case MONO_TYPE_PTR:
                return ((hash << 5) - hash) ^ mono_metadata_type_hash (t1->data.type);
        case MONO_TYPE_ARRAY:
index a2de0848046eb32b5b7b4205bee87bf43d0775c7..a587cf96203306636dd434d174d67dcbe0cb1cf3 100644 (file)
@@ -1020,6 +1020,14 @@ mono_install_vtable_trampoline (gpointer tramp_code)
        c ^= b; c -= rot(b,24); \
 }
 
+/*
+ * mono_method_get_imt_slot:
+ *
+ *   The IMT slot is embedded into AOTed code, so this must return the same value
+ * for the same method across all executions. This means:
+ * - pointers shouldn't be used as hash values.
+ * - mono_metadata_str_hash () should be used for hashing strings.
+ */
 guint32
 mono_method_get_imt_slot (MonoMethod *method)
 {
@@ -1053,14 +1061,14 @@ mono_method_get_imt_slot (MonoMethod *method)
        }
        
        /* Initialize hashes */
-       hashes [0] = g_str_hash (method->klass->name);
-       hashes [1] = g_str_hash (method->klass->name_space);
-       hashes [2] = g_str_hash (method->name);
+       hashes [0] = mono_metadata_str_hash (method->klass->name);
+       hashes [1] = mono_metadata_str_hash (method->klass->name_space);
+       hashes [2] = mono_metadata_str_hash (method->name);
        hashes [3] = mono_metadata_type_hash (sig->ret);
        for (i = 0; i < sig->param_count; i++) {
                hashes [4 + i] = mono_metadata_type_hash (sig->params [i]);
        }
-       
+
        /* Setup internal state */
        a = b = c = 0xdeadbeef + (((guint32)hashes_count)<<2);