2003-08-26 Zoltan Varga <vargaz@freemail.hu>
authorZoltan Varga <vargaz@gmail.com>
Tue, 26 Aug 2003 09:45:08 +0000 (09:45 -0000)
committerZoltan Varga <vargaz@gmail.com>
Tue, 26 Aug 2003 09:45:08 +0000 (09:45 -0000)
* appdomain.c (mono_runtime_init): Call the new initializer function
of the marshal module.

* marshal.c (mono_marshal_load_type_info): Ignore the dummy field
inserted into empty structures by mono. Fixes pinvoke7.cs.

* marshal.h marshal.c: Added locks around the wrapper caches to make
this module thread safe.

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

mono/metadata/ChangeLog
mono/metadata/appdomain.c
mono/metadata/marshal.c
mono/metadata/marshal.h

index d70c01f6df4c8e640f757881f3d19e22d18e204e..e26d1f73455b97ce44e11cd47334c329c23d8a59 100644 (file)
@@ -1,5 +1,14 @@
 2003-08-26  Zoltan Varga  <vargaz@freemail.hu>
 
+       * appdomain.c (mono_runtime_init): Call the new initializer function
+       of the marshal module.
+
+       * marshal.c (mono_marshal_load_type_info): Ignore the dummy field
+       inserted into empty structures by mono. Fixes pinvoke7.cs.
+
+       * marshal.h marshal.c: Added locks around the wrapper caches to make
+       this module thread safe.
+
        * icall.c (ves_icall_InternalInvoke): Method wrappers doesn't require a
        this argument. Fixes pinvoke1.exe.
 
index b5ca91ed08a3b053e364a28023b221a209235ece..d0ac5d6f63b39b7bf8cdc037a12323c61fa15bf4 100644 (file)
@@ -23,6 +23,7 @@
 #include <mono/metadata/socket-io.h>
 #include <mono/metadata/tabledefs.h>
 #include <mono/metadata/gc-internal.h>
+#include <mono/metadata/marshal.h>
 
 HANDLE mono_delegate_semaphore = NULL;
 CRITICAL_SECTION mono_delegate_section;
@@ -60,6 +61,8 @@ mono_runtime_init (MonoDomain *domain, MonoThreadStartCB start_cb,
        MonoAppDomainSetup *setup;
        MonoAppDomain *ad;
        MonoClass *class;
+
+       mono_marshal_init ();
        
        mono_install_assembly_preload_hook (mono_domain_assembly_preload, NULL);
        mono_install_assembly_load_hook (mono_domain_fire_assembly_load, NULL);
index e80ffc907e95b9730a5dcf9d594563aa8b1038a1..fd8ebc25cd80c21ff3543c995cd15b0201ec634c 100644 (file)
@@ -76,6 +76,15 @@ static MonoDisHelper marshal_dh = {
 };
 #endif 
 
+/* This mutex protects the various marshalling related caches in MonoImage */
+static CRITICAL_SECTION marshal_mutex;
+
+void
+mono_marshal_init (void)
+{
+       InitializeCriticalSection (&marshal_mutex);
+}
+
 gpointer
 mono_delegate_to_ftnptr (MonoDelegate *delegate)
 {
@@ -408,7 +417,7 @@ mono_mb_emit_i2 (MonoMethodBuilder *mb, gint16 data)
 void
 mono_mb_emit_ldstr (MonoMethodBuilder *mb, char *str)
 {
-        mono_mb_emit_byte (mb, CEE_LDSTR);
+       mono_mb_emit_byte (mb, CEE_LDSTR);
        mono_mb_emit_i4 (mb, mono_mb_add_data (mb, str));
 }
 
@@ -752,10 +761,10 @@ emit_str_to_ptr_conv (MonoMethodBuilder *mb, MonoType *type, MonoMarshalConv con
                        g_assert_not_reached ();
                }
 
-               if (eclass->valuetype)
-                       esize = mono_class_native_size (eclass, NULL);
-               else
-                       esize = sizeof (gpointer);
+               if (eclass->valuetype)
+                       esize = mono_class_native_size (eclass, NULL);
+               else
+                       esize = sizeof (gpointer);
 
                if (!usize) 
                        break;
@@ -1081,6 +1090,40 @@ mono_signature_to_name (MonoMethodSignature *sig, const char *prefix)
        return result;
 }
 
+static inline MonoMethod*
+mono_marshal_find_in_cache (GHashTable *cache, gpointer key)
+{
+       MonoMethod *res;
+
+       EnterCriticalSection (&marshal_mutex);
+       res = g_hash_table_lookup (cache, key);
+       LeaveCriticalSection (&marshal_mutex);
+       return res;
+}
+
+/* Create the method from the builder and place it in the cache */
+static inline MonoMethod*
+mono_mb_create_and_cache (GHashTable *cache, gpointer key,
+                                                          MonoMethodBuilder *mb, MonoMethodSignature *sig,
+                                                          int max_stack)
+{
+       MonoMethod *res;
+
+       EnterCriticalSection (&marshal_mutex);
+       res = g_hash_table_lookup (cache, key);
+       if (!res) {
+               /* This does not acquire any locks */
+               res = mono_mb_create_method (mb, sig, max_stack);
+               g_hash_table_insert (cache, key, res);
+       }
+       else
+               /* Somebody created it before us */
+               ;
+       LeaveCriticalSection (&marshal_mutex);
+
+       return res;
+}              
+
 MonoMethod *
 mono_marshal_get_delegate_begin_invoke (MonoMethod *method)
 {
@@ -1098,7 +1141,7 @@ mono_marshal_get_delegate_begin_invoke (MonoMethod *method)
        sig = method->signature;
 
        cache = method->klass->image->delegate_begin_invoke_cache;
-       if ((res = (MonoMethod *)g_hash_table_lookup (cache, sig)))
+       if ((res = mono_marshal_find_in_cache (cache, sig)))
                return res;
 
        g_assert (sig->hasthis);
@@ -1127,9 +1170,8 @@ mono_marshal_get_delegate_begin_invoke (MonoMethod *method)
        mono_mb_emit_native_call (mb, csig, mono_delegate_begin_invoke);
        mono_mb_emit_byte (mb, CEE_RET);
 
-       res = mono_mb_create_method (mb, sig, sig->param_count + 16);
+       res = mono_mb_create_and_cache (cache, sig, mb, sig, sig->param_count + 16);
        mono_mb_free (mb);
-       g_hash_table_insert (cache, sig, res);
        return res;
 }
 
@@ -1303,7 +1345,7 @@ mono_marshal_get_delegate_end_invoke (MonoMethod *method)
        sig = method->signature;
 
        cache = method->klass->image->delegate_end_invoke_cache;
-       if ((res = (MonoMethod *)g_hash_table_lookup (cache, sig)))
+       if ((res = mono_marshal_find_in_cache (cache, sig)))
                return res;
 
        g_assert (sig->hasthis);
@@ -1337,9 +1379,9 @@ mono_marshal_get_delegate_end_invoke (MonoMethod *method)
        } else
                mono_mb_emit_restore_result (mb, sig->ret);
 
-       res = mono_mb_create_method (mb, sig, sig->param_count + 16);
+       res = mono_mb_create_and_cache (cache, sig,
+                                                                                mb, sig, sig->param_count + 16);
        mono_mb_free (mb);
-       g_hash_table_insert (cache, sig, res);
 
        return res;
 }
@@ -1416,7 +1458,7 @@ mono_marshal_get_remoting_invoke (MonoMethod *method)
                return method;
 
        cache = method->klass->image->remoting_invoke_cache;
-       if ((res = (MonoMethod *)g_hash_table_lookup (cache, method)))
+       if ((res = mono_marshal_find_in_cache (cache, method)))
                return res;
 
        if (!csig) {
@@ -1445,9 +1487,9 @@ mono_marshal_get_remoting_invoke (MonoMethod *method)
                 mono_mb_emit_restore_result (mb, sig->ret);
        }
 
-       res = mono_mb_create_method (mb, sig, sig->param_count + 16);
+       res = mono_mb_create_and_cache (cache, method, mb, sig, sig->param_count + 16);
        mono_mb_free (mb);
-       g_hash_table_insert (cache, method, res);
+
        return res;
 }
 
@@ -1471,7 +1513,7 @@ mono_marshal_get_remoting_invoke_with_check (MonoMethod *method)
        g_assert (sig->hasthis);
 
        cache = method->klass->image->remoting_invoke_cache;
-       if ((res = (MonoMethod *)g_hash_table_lookup (cache, (char *)method + 1)))
+       if ((res = mono_marshal_find_in_cache (cache, (char *)method + 1)))
                return res;
 
        mb = mono_mb_new (method->klass, method->name, MONO_WRAPPER_REMOTING_INVOKE_WITH_CHECK);
@@ -1495,9 +1537,10 @@ mono_marshal_get_remoting_invoke_with_check (MonoMethod *method)
        mono_mb_emit_managed_call (mb, method, method->signature);
        mono_mb_emit_byte (mb, CEE_RET);
 
-       res = mono_mb_create_method (mb, sig, sig->param_count + 16);
+       res = mono_mb_create_and_cache (cache, (char*)method + 1,
+                                                                                mb, sig, sig->param_count + 16);
        mono_mb_free (mb);
-       g_hash_table_insert (cache, (char *)method + 1, res);
+
        return res;
 }
 
@@ -1521,7 +1564,7 @@ mono_marshal_get_delegate_invoke (MonoMethod *method)
        sig = method->signature;
 
        cache = method->klass->image->delegate_invoke_cache;
-       if ((res = (MonoMethod *)g_hash_table_lookup (cache, sig)))
+       if ((res = mono_marshal_find_in_cache (cache, sig)))
                return res;
 
        sigsize = sizeof (MonoMethodSignature) + sig->param_count * sizeof (MonoType *);
@@ -1608,11 +1651,10 @@ mono_marshal_get_delegate_invoke (MonoMethod *method)
        mono_mb_patch_addr (mb, pos1, mb->pos - (pos1 + 4));
        mono_mb_emit_byte (mb, CEE_RET);
 
-       res = mono_mb_create_method (mb, sig, sig->param_count + 16);
+       res = mono_mb_create_and_cache (cache, sig,
+                                                                                mb, sig, sig->param_count + 16);
        mono_mb_free (mb);
 
-       g_hash_table_insert (cache, sig, res);
-
        return res;     
 }
 
@@ -1637,7 +1679,7 @@ mono_marshal_get_runtime_invoke (MonoMethod *method)
        g_assert (method);
 
        cache = method->klass->image->runtime_invoke_cache;
-       if ((res = (MonoMethod *)g_hash_table_lookup (cache, method)))
+       if ((res = mono_marshal_find_in_cache (cache, method)))
                return res;
        
        /* to make it work with our special string constructors */
@@ -1850,15 +1892,14 @@ handle_enum:
        mono_mb_emit_ldloc (mb, 0);
        mono_mb_emit_byte (mb, CEE_RET);
        
-       res = mono_mb_create_method (mb, csig, sig->param_count + 16);
+       res = mono_mb_create_and_cache (cache, method,
+                                                                                mb, csig, sig->param_count + 16);
        mono_mb_free (mb);
 
        header = ((MonoMethodNormal *)res)->header;
        header->num_clauses = 1;
        header->clauses = clause;
 
-       g_hash_table_insert (cache, method, res);
-
        return res;     
 }
 
@@ -1879,7 +1920,7 @@ mono_marshal_get_managed_wrapper (MonoMethod *method, MonoObject *this, MonoMars
        g_assert (!method->signature->pinvoke);
 
        cache = method->klass->image->managed_wrapper_cache;
-       if (!this && (res = (MonoMethod *)g_hash_table_lookup (cache, method)))
+       if (!this && (res = mono_marshal_find_in_cache (cache, method)))
                return res;
 
        if (this) {
@@ -2165,11 +2206,12 @@ mono_marshal_get_managed_wrapper (MonoMethod *method, MonoObject *this, MonoMars
                mono_mb_emit_byte (mb, CEE_RET);
        }
 
-       res = mono_mb_create_method (mb, csig, sig->param_count + 16);
-       mono_mb_free (mb);
-
        if (!this)
-               g_hash_table_insert (cache, method, res);
+               res = mono_mb_create_and_cache (cache, method,
+                                                                                        mb, csig, sig->param_count + 16);
+       else
+               res = mono_mb_create_method (mb, csig, sig->param_count + 16);
+       mono_mb_free (mb);
 
        return res;
 }
@@ -2193,10 +2235,6 @@ mono_marshal_get_ldfld_wrapper (MonoType *type)
        char *name;
        int t, pos0, pos1;
 
-       if (!ldfld_hash) 
-               ldfld_hash = g_hash_table_new (NULL, NULL);
-
-
        t = type->type;
 
        if (!type->byref) {
@@ -2220,7 +2258,12 @@ mono_marshal_get_ldfld_wrapper (MonoType *type)
                klass = mono_defaults.int_class;
        }
 
-       if ((res = g_hash_table_lookup (ldfld_hash, klass)))
+       EnterCriticalSection (&marshal_mutex);
+       if (!ldfld_hash) 
+               ldfld_hash = g_hash_table_new (NULL, NULL);
+       res = g_hash_table_lookup (ldfld_hash, klass);
+       LeaveCriticalSection (&marshal_mutex);
+       if (res)
                return res;
 
        name = g_strdup_printf ("__ldfld_wrapper_%s.%s", klass->name_space, klass->name); 
@@ -2322,11 +2365,10 @@ mono_marshal_get_ldfld_wrapper (MonoType *type)
 
        mono_mb_emit_byte (mb, CEE_RET);
        
-       res = mono_mb_create_method (mb, sig, sig->param_count + 16);
+       res = mono_mb_create_and_cache (ldfld_hash, klass,
+                                                                                mb, sig, sig->param_count + 16);
        mono_mb_free (mb);
        
-       g_hash_table_insert (ldfld_hash, klass, res);
-
        return res;
 }
 
@@ -2349,9 +2391,6 @@ mono_marshal_get_stfld_wrapper (MonoType *type)
        char *name;
        int t, pos;
 
-       if (!stfld_hash) 
-               stfld_hash = g_hash_table_new (NULL, NULL);
-
        t = type->type;
 
        if (!type->byref) {
@@ -2375,7 +2414,12 @@ mono_marshal_get_stfld_wrapper (MonoType *type)
                klass = mono_defaults.int_class;
        }
 
-       if ((res = g_hash_table_lookup (stfld_hash, klass)))
+       EnterCriticalSection (&marshal_mutex);
+       if (!stfld_hash) 
+               stfld_hash = g_hash_table_new (NULL, NULL);
+       res = g_hash_table_lookup (stfld_hash, klass);
+       LeaveCriticalSection (&marshal_mutex);
+       if (res)
                return res;
 
        name = g_strdup_printf ("__stfld_wrapper_%s.%s", klass->name_space, klass->name); 
@@ -2474,11 +2518,10 @@ mono_marshal_get_stfld_wrapper (MonoType *type)
 
        mono_mb_emit_byte (mb, CEE_RET);
        
-       res = mono_mb_create_method (mb, sig, sig->param_count + 16);
+       res = mono_mb_create_and_cache (stfld_hash, klass,
+                                                                       mb, sig, sig->param_count + 16);
        mono_mb_free (mb);
        
-       g_hash_table_insert (stfld_hash, klass, res);
-
        return res;
 }
 
@@ -2524,7 +2567,7 @@ mono_marshal_get_icall_wrapper (MonoMethodSignature *sig, const char *name, gcon
 
 /*
  * generates IL code for the pinvoke wrapper (the generated method
- * calls the unamnage code in method->addr)
+ * calls the unmanaged code in method->addr)
  */
 MonoMethod *
 mono_marshal_get_native_wrapper (MonoMethod *method)
@@ -2544,7 +2587,7 @@ mono_marshal_get_native_wrapper (MonoMethod *method)
        g_assert (method->signature->pinvoke);
 
        cache = method->klass->image->native_wrapper_cache;
-       if ((res = (MonoMethod *)g_hash_table_lookup (cache, method)))
+       if ((res = mono_marshal_find_in_cache (cache, method)))
                return res;
 
        sig = method->signature;
@@ -2567,9 +2610,9 @@ mono_marshal_get_native_wrapper (MonoMethod *method)
                mono_mb_emit_exception (mb);
                csig = g_memdup (sig, sigsize);
                csig->pinvoke = 0;
-               res = mono_mb_create_method (mb, csig, csig->param_count + 16);
+               res = mono_mb_create_and_cache (cache, method,
+                                                                               mb, csig, csig->param_count + 16);
                mono_mb_free (mb);
-               g_hash_table_insert (cache, method, res);
                return res;
        }
 
@@ -2596,9 +2639,9 @@ mono_marshal_get_native_wrapper (MonoMethod *method)
 
                csig = g_memdup (csig, sigsize);
                csig->pinvoke = 0;
-               res = mono_mb_create_method (mb, csig, csig->param_count + 16);
+               res = mono_mb_create_and_cache (cache, method,
+                                                                               mb, csig, csig->param_count + 16);
                mono_mb_free (mb);
-               g_hash_table_insert (cache, method, res);
                return res;
        }
 
@@ -3270,11 +3313,10 @@ mono_marshal_get_native_wrapper (MonoMethod *method)
 
        csig = g_memdup (sig, sigsize);
        csig->pinvoke = 0;
-       res = mono_mb_create_method (mb, csig, csig->param_count + 16);
+       res = mono_mb_create_and_cache (cache, method,
+                                                                       mb, csig, csig->param_count + 16);
        mono_mb_free (mb);
 
-       g_hash_table_insert (cache, method, res);
-
        for (i = sig->param_count; i >= 0; i--)
                g_free (mspecs [i]);
        g_free (mspecs);
@@ -3433,7 +3475,7 @@ mono_marshal_get_synchronized_wrapper (MonoMethod *method)
                return method;
 
        cache = method->klass->image->synchronized_cache;
-       if ((res = (MonoMethod *)g_hash_table_lookup (cache, method)))
+       if ((res = mono_marshal_find_in_cache (cache, method)))
                return res;
 
        sig = method->signature;
@@ -3518,15 +3560,14 @@ mono_marshal_get_synchronized_wrapper (MonoMethod *method)
                mono_mb_emit_ldloc (mb, ret_local);
        mono_mb_emit_byte (mb, CEE_RET);
 
-       res = mono_mb_create_method (mb, sig, sig->param_count + 16);
+       res = mono_mb_create_and_cache (cache, method,
+                                                                       mb, sig, sig->param_count + 16);
        mono_mb_free (mb);
 
        header = ((MonoMethodNormal *)res)->header;
        header->num_clauses = 1;
        header->clauses = clause;
 
-       g_hash_table_insert (cache, method, res);
-
        return res;     
 }
 
@@ -4040,6 +4081,12 @@ mono_marshal_load_type_info (MonoClass* klass)
 
                info->fields [j].field = &klass->fields [i];
 
+               if ((klass->field.count == 1) && (klass->instance_size == sizeof (MonoObject)) &&
+                       (strcmp (klass->fields [i].name, "$PRIVATE$") == 0)) {
+                       /* This field is a hack inserted by MCS to empty structures */
+                       continue;
+               }
+
                switch (layout) {
                case TYPE_ATTRIBUTE_AUTO_LAYOUT:
                case TYPE_ATTRIBUTE_SEQUENTIAL_LAYOUT:
index da3597d8d71d621ff9d62302d3af022a68eab694..943e6b3508dec6758aab61131b04bdbea07a0c9d 100644 (file)
@@ -21,6 +21,9 @@ typedef struct _MonoMethodBuilder MonoMethodBuilder;
 
 /* marshaling helper functions */
 
+void
+mono_marshal_init (void);
+
 gint32
 mono_class_native_size (MonoClass *klass, guint32 *align);