Merge pull request #3247 from lateralusX/jlorenss/win-x64-lmf-exception
[mono.git] / mono / metadata / marshal.c
index 86e66ece626ce9a7560ea03a47cf58d44222bf69..3edf257bee53630bcae260331657d73c757d2a3a 100644 (file)
@@ -962,7 +962,7 @@ mono_string_utf16_to_builder (MonoStringBuilder *sb, gunichar2 *text)
  *
  * Returns: a utf8 string with the contents of the StringBuilder.
  *
- * The return value must be released with g_free.
+ * The return value must be released with mono_marshal_free.
  *
  * This is a JIT icall, it sets the pending exception and returns NULL on error.
  */
@@ -983,14 +983,14 @@ mono_string_builder_to_utf8 (MonoStringBuilder *sb)
 
        if (gerror) {
                g_error_free (gerror);
-               g_free (str_utf16);
+               mono_marshal_free (str_utf16);
                mono_set_pending_exception (mono_get_exception_execution_engine ("Failed to convert StringBuilder from utf16 to utf8"));
                return NULL;
        } else {
                guint len = mono_string_builder_capacity (sb) + 1;
                gchar *res = (gchar *)mono_marshal_alloc (len * sizeof (gchar), &error);
                if (!mono_error_ok (&error)) {
-                       g_free (str_utf16);
+                       mono_marshal_free (str_utf16);
                        g_free (tmp);
                        mono_error_set_pending_exception (&error);
                        return NULL;
@@ -1000,7 +1000,7 @@ mono_string_builder_to_utf8 (MonoStringBuilder *sb)
                memcpy (res, tmp, str_len * sizeof (gchar));
                res[str_len] = '\0';
 
-               g_free (str_utf16);
+               mono_marshal_free (str_utf16);
                g_free (tmp);
                return res;
        }
@@ -1014,7 +1014,8 @@ mono_string_builder_to_utf8 (MonoStringBuilder *sb)
  *
  * Returns: a utf16 string with the contents of the StringBuilder.
  *
- * The return value must not be freed.
+ * The return value must be released with mono_marshal_free.
+ *
  * This is a JIT icall, it sets the pending exception and returns NULL on error.
  */
 gunichar2*
@@ -4219,7 +4220,6 @@ mono_marshal_get_runtime_invoke (MonoMethod *method, gboolean virtual_)
  * ARGS should contain the this argument too.
  * This wrapper serves the same purpose as the runtime-invoke wrappers, but there
  * is only one copy of it, which is useful in full-aot.
- * The wrapper info for the wrapper is a WrapperInfo structure.
  */
 MonoMethod*
 mono_marshal_get_runtime_invoke_dynamic (void)
@@ -4446,7 +4446,6 @@ mono_mb_emit_auto_layout_exception (MonoMethodBuilder *mb, MonoClass *klass)
 /*
  * generates IL code for the icall wrapper (the generated method
  * calls the unmanaged code in func)
- * The wrapper info for the wrapper is a WrapperInfo structure.
  */
 MonoMethod *
 mono_marshal_get_icall_wrapper (MonoMethodSignature *sig, const char *name, gconstpointer func, gboolean check_exceptions)
@@ -4457,6 +4456,10 @@ mono_marshal_get_icall_wrapper (MonoMethodSignature *sig, const char *name, gcon
        int i;
        WrapperInfo *info;
        
+       GHashTable *cache = get_cache (&mono_defaults.object_class->image->icall_wrapper_cache, mono_aligned_addr_hash, NULL);
+       if ((res = mono_marshal_find_in_cache (cache, (gpointer) func)))
+               return res;
+
        g_assert (sig->pinvoke);
 
        mb = mono_mb_new (mono_defaults.object_class, name, MONO_WRAPPER_MANAGED_TO_NATIVE);
@@ -4491,7 +4494,7 @@ mono_marshal_get_icall_wrapper (MonoMethodSignature *sig, const char *name, gcon
 
        info = mono_wrapper_info_create (mb, WRAPPER_SUBTYPE_ICALL_WRAPPER);
        info->d.icall.func = (gpointer)func;
-       res = mono_mb_create (mb, csig, csig->param_count + 16, info);
+       res = mono_mb_create_and_cache_full (cache, (gpointer) func, mb, csig, csig->param_count + 16, info, NULL);
        mono_mb_free (mb);
 
        return res;
@@ -7589,7 +7592,6 @@ mono_marshal_emit_native_wrapper (MonoImage *image, MonoMethodBuilder *mb, MonoM
  *
  * generates IL code for the pinvoke wrapper (the generated method
  * calls the unmanaged code in piinfo->addr)
- * The wrapper info for the wrapper is a WrapperInfo structure.
  */
 MonoMethod *
 mono_marshal_get_native_wrapper (MonoMethod *method, gboolean check_exceptions, gboolean aot)
@@ -8648,7 +8650,6 @@ generate_check_cache (int obj_arg_position, int class_arg_position, int cache_ar
 
 /*
  * This does the equivalent of mono_object_castclass_with_cache.
- * The wrapper info for the wrapper is a WrapperInfo structure.
  */
 MonoMethod *
 mono_marshal_get_castclass_with_cache (void)
@@ -8734,7 +8735,6 @@ mono_marshal_isinst_with_cache (MonoObject *obj, MonoClass *klass, uintptr_t *ca
 
 /*
  * This does the equivalent of mono_object_isinst_with_cache.
- * The wrapper info for the wrapper is a WrapperInfo structure.
  */
 MonoMethod *
 mono_marshal_get_isinst_with_cache (void)
@@ -8911,7 +8911,6 @@ mono_marshal_get_isinst (MonoClass *klass)
  * an instance of the given type, icluding the case where the object is a proxy.
  * The generated function has the following signature:
  * MonoObject* __castclass_wrapper_ (MonoObject *obj)
- * The wrapper info for the wrapper is a WrapperInfo structure.
  */
 MonoMethod *
 mono_marshal_get_castclass (MonoClass *klass)
@@ -8994,7 +8993,6 @@ mono_marshal_get_castclass (MonoClass *klass)
  * @klass:
  *
  * generates IL code for StructureToPtr (object structure, IntPtr ptr, bool fDeleteOld)
- * The wrapper info for the wrapper is a WrapperInfo structure.
  */
 MonoMethod *
 mono_marshal_get_struct_to_ptr (MonoClass *klass)
@@ -9068,7 +9066,6 @@ mono_marshal_get_struct_to_ptr (MonoClass *klass)
  * @klass:
  *
  * generates IL code for PtrToStructure (IntPtr src, object structure)
- * The wrapper info for the wrapper is a WrapperInfo structure.
  */
 MonoMethod *
 mono_marshal_get_ptr_to_struct (MonoClass *klass)
@@ -9147,7 +9144,6 @@ mono_marshal_get_ptr_to_struct (MonoClass *klass)
  * This is used to avoid infinite recursion since it is hard to determine where to
  * replace a method with its synchronized wrapper, and where not.
  * The runtime should execute METHOD instead of the wrapper.
- * The wrapper info for the wrapper is a WrapperInfo structure.
  */
 MonoMethod *
 mono_marshal_get_synchronized_inner_wrapper (MonoMethod *method)
@@ -9515,8 +9511,6 @@ record_slot_vstore (MonoObject *array, size_t index, MonoObject *value)
 #endif
 
 /*
- * The wrapper info for the wrapper is a WrapperInfo structure.
- *
  * TODO:
  *     - Separate simple interfaces from variant interfaces or mbr types. This way we can avoid the icall for them.
  *     - Emit a (new) mono bytecode that produces OP_COND_EXC_NE_UN to raise ArrayTypeMismatch
@@ -9925,9 +9919,6 @@ mono_marshal_get_virtual_stelemref_wrappers (int *nwrappers)
        return res;
 }
 
-/*
- * The wrapper info for the wrapper is a WrapperInfo structure.
- */
 MonoMethod*
 mono_marshal_get_stelemref (void)
 {
@@ -10078,8 +10069,6 @@ mono_marshal_get_stelemref (void)
  * mono_marshal_get_gsharedvt_in_wrapper:
  *
  *   This wrapper handles calls from normal code to gsharedvt code.
- *
- * The wrapper info for the wrapper is a WrapperInfo structure.
  */
 MonoMethod*
 mono_marshal_get_gsharedvt_in_wrapper (void)
@@ -10114,8 +10103,6 @@ mono_marshal_get_gsharedvt_in_wrapper (void)
  * mono_marshal_get_gsharedvt_out_wrapper:
  *
  *   This wrapper handles calls from gsharedvt code to normal code.
- *
- * The wrapper info for the wrapper is a WrapperInfo structure.
  */
 MonoMethod*
 mono_marshal_get_gsharedvt_out_wrapper (void)