Merge pull request #3247 from lateralusX/jlorenss/win-x64-lmf-exception
[mono.git] / mono / mini / aot-runtime.c
index 2ebae1f232242f94400f0dba9350a546e639be73..d4eb786235ed89a7de1860e7c2be46fce9e9ecab 100644 (file)
@@ -56,6 +56,7 @@
 #include <mono/utils/mono-compiler.h>
 #include <mono/utils/mono-counters.h>
 #include <mono/utils/mono-digest.h>
+#include <mono/utils/mono-threads-coop.h>
 
 #include "mini.h"
 #include "seq-points.h"
@@ -921,17 +922,17 @@ decode_method_ref_with_target (MonoAotModule *module, MethodRef *ref, MonoMethod
                        }
                        break;
                }
-               case MONO_WRAPPER_LDFLD_REMOTE:
-                       ref->method = mono_marshal_get_ldfld_remote_wrapper (NULL);
-                       break;
                case MONO_WRAPPER_STFLD_REMOTE:
                        ref->method = mono_marshal_get_stfld_remote_wrapper (NULL);
                        break;
 #endif
                case MONO_WRAPPER_ALLOC: {
                        int atype = decode_value (p, &p);
+                       ManagedAllocatorVariant variant =
+                               mono_profiler_get_events () & MONO_PROFILE_ALLOCATIONS ?
+                               MANAGED_ALLOCATOR_SLOW_PATH : MANAGED_ALLOCATOR_REGULAR;
 
-                       ref->method = mono_gc_get_managed_allocator_by_type (atype, !!(mono_profiler_get_events () & MONO_PROFILE_ALLOCATIONS));
+                       ref->method = mono_gc_get_managed_allocator_by_type (atype, variant);
                        if (!ref->method) {
                                mono_error_set_bad_image_name (error, module->aot_name, "Error: No managed allocator, but we need one for AOT.\nAre you using non-standard GC options?\n");
                                return FALSE;
@@ -1781,17 +1782,6 @@ check_usable (MonoAssembly *assembly, MonoAotFileInfo *info, guint8 *blob, char
                msg = g_strdup_printf ("not compiled with --aot=llvmonly");
                usable = FALSE;
        }
-#ifdef TARGET_ARM
-       /* mono_arch_find_imt_method () requires this */
-       if ((info->flags & MONO_AOT_FILE_FLAG_WITH_LLVM) && !mono_use_llvm) {
-               msg = g_strdup_printf ("compiled against LLVM");
-               usable = FALSE;
-       }
-       if (!(info->flags & MONO_AOT_FILE_FLAG_WITH_LLVM) && mono_use_llvm) {
-               msg = g_strdup_printf ("not compiled against LLVM");
-               usable = FALSE;
-       }
-#endif
        if (mini_get_debug_options ()->mdb_optimizations && !(info->flags & MONO_AOT_FILE_FLAG_DEBUG) && !full_aot) {
                msg = g_strdup_printf ("not compiled for debugging");
                usable = FALSE;
@@ -2410,6 +2400,8 @@ mono_aot_get_method_from_vt_slot (MonoDomain *domain, MonoVTable *vtable, int sl
        gboolean err;
        MethodRef ref;
        gboolean res;
+       gpointer addr;
+       MonoError inner_error;
 
        mono_error_init (error);
 
@@ -2424,12 +2416,12 @@ mono_aot_get_method_from_vt_slot (MonoDomain *domain, MonoVTable *vtable, int sl
                return NULL;
 
        for (i = 0; i < slot; ++i) {
-               decode_method_ref (amodule, &ref, p, &p, error);
-               mono_error_cleanup (error); /* FIXME don't swallow the error */
+               decode_method_ref (amodule, &ref, p, &p, &inner_error);
+               mono_error_cleanup (&inner_error); /* FIXME don't swallow the error */
        }
 
-       res = decode_method_ref (amodule, &ref, p, &p, error);
-       mono_error_cleanup (error); /* FIXME don't swallow the error */
+       res = decode_method_ref (amodule, &ref, p, &p, &inner_error);
+       mono_error_cleanup (&inner_error); /* FIXME don't swallow the error */
        if (!res)
                return NULL;
        if (ref.no_aot_trampoline)
@@ -2438,7 +2430,8 @@ mono_aot_get_method_from_vt_slot (MonoDomain *domain, MonoVTable *vtable, int sl
        if (mono_metadata_token_index (ref.token) == 0 || mono_metadata_token_table (ref.token) != MONO_TABLE_METHOD)
                return NULL;
 
-       return mono_aot_get_method_from_token (domain, ref.image, ref.token, error);
+       addr = mono_aot_get_method_from_token (domain, ref.image, ref.token, error);
+       return addr;
 }
 
 gboolean
@@ -4262,9 +4255,9 @@ init_llvmonly_method (MonoAotModule *amodule, guint32 method_index, MonoMethod *
        MonoError error;
 
        res = init_method (amodule, method_index, method, init_class, context, &error);
-       /* Its okay to raise in llvmonly mode */
        if (!is_ok (&error)) {
                MonoException *ex = mono_error_convert_to_exception (&error);
+               /* Its okay to raise in llvmonly mode */
                if (ex)
                        mono_llvm_throw_exception ((MonoObject*)ex);
        }
@@ -4354,6 +4347,7 @@ mono_aot_get_method_checked (MonoDomain *domain, MonoMethod *method, MonoError *
        MonoAotModule *amodule = (MonoAotModule *)klass->image->aot_module;
        guint8 *code;
        gboolean cache_result = FALSE;
+       MonoError inner_error;
 
        mono_error_init (error);
 
@@ -4428,11 +4422,10 @@ mono_aot_get_method_checked (MonoDomain *domain, MonoMethod *method, MonoError *
                if (method_index == 0xffffff && method->wrapper_type == MONO_WRAPPER_MANAGED_TO_MANAGED && method->klass->rank && strstr (method->name, "System.Collections.Generic")) {
                        MonoMethod *m = mono_aot_get_array_helper_from_wrapper (method);
 
-                       code = (guint8 *)mono_aot_get_method_checked (domain, m, error);
+                       code = (guint8 *)mono_aot_get_method_checked (domain, m, &inner_error);
+                       mono_error_cleanup (&inner_error);
                        if (code)
                                return code;
-                       if (!is_ok (error))
-                               return NULL;
                }
 
                /*
@@ -4464,11 +4457,10 @@ mono_aot_get_method_checked (MonoDomain *domain, MonoMethod *method, MonoError *
                         * Get the code for the <object> instantiation which should be emitted into
                         * the mscorlib aot image by the AOT compiler.
                         */
-                       code = (guint8 *)mono_aot_get_method_checked (domain, m, error);
+                       code = (guint8 *)mono_aot_get_method_checked (domain, m, &inner_error);
+                       mono_error_cleanup (&inner_error);
                        if (code)
                                return code;
-                       if (!is_ok (error))
-                               return NULL;
                }
 
                /* Same for CompareExchange<T> and Exchange<T> */
@@ -4504,11 +4496,10 @@ mono_aot_get_method_checked (MonoDomain *domain, MonoMethod *method, MonoError *
                         * Get the code for the <object> instantiation which should be emitted into
                         * the mscorlib aot image by the AOT compiler.
                         */
-                       code = (guint8 *)mono_aot_get_method_checked (domain, m, error);
+                       code = (guint8 *)mono_aot_get_method_checked (domain, m, &inner_error);
+                       mono_error_cleanup (&inner_error);
                        if (code)
                                return code;
-                       if (!is_ok (error))
-                               return NULL;
                }
 
                /* For ARRAY_ACCESSOR wrappers with reference types, use the <object> instantiation saved in corlib */
@@ -4518,17 +4509,24 @@ mono_aot_get_method_checked (MonoDomain *domain, MonoMethod *method, MonoError *
                        if (info->subtype == WRAPPER_SUBTYPE_ARRAY_ACCESSOR) {
                                MonoMethod *array_method = info->d.array_accessor.method;
                                if (MONO_TYPE_IS_REFERENCE (&array_method->klass->element_class->byval_arg)) {
-                                       MonoClass *obj_array_class = mono_array_class_get (mono_defaults.object_class, 1);
+                                       int rank;
+
+                                       if (!strcmp (array_method->name, "Set"))
+                                               rank = mono_method_signature (array_method)->param_count - 1;
+                                       else if (!strcmp (array_method->name, "Get") || !strcmp (array_method->name, "Address"))
+                                               rank = mono_method_signature (array_method)->param_count;
+                                       else
+                                               g_assert_not_reached ();
+                                       MonoClass *obj_array_class = mono_array_class_get (mono_defaults.object_class, rank);
                                        MonoMethod *m = mono_class_get_method_from_name (obj_array_class, array_method->name, mono_method_signature (array_method)->param_count);
                                        g_assert (m);
 
                                        m = mono_marshal_get_array_accessor_wrapper (m);
                                        if (m != method) {
-                                               code = (guint8 *)mono_aot_get_method_checked (domain, m, error);
+                                               code = (guint8 *)mono_aot_get_method_checked (domain, m, &inner_error);
+                                               mono_error_cleanup (&inner_error);
                                                if (code)
                                                        return code;
-                                               if (!is_ok (error))
-                                                       return NULL;
                                        }
                                }
                        }
@@ -4601,8 +4599,8 @@ mono_aot_get_method (MonoDomain *domain, MonoMethod *method)
        MonoError error;
 
        gpointer res = mono_aot_get_method_checked (domain, method, &error);
-       /* This is a public api function so it can raise exceptions */
-       mono_error_raise_exception (&error);
+       /* This is external only, so its ok to raise here */
+       mono_error_raise_exception (&error); /* OK to throw, external only without a good alternative */
        return res;
 }
 
@@ -5832,8 +5830,10 @@ mono_aot_get_method (MonoDomain *domain, MonoMethod *method)
 }
 
 gpointer
-mono_aot_get_method_checked (MonoDomain *domain, MonoMethod *method, MonoError *error)
+mono_aot_get_method_checked (MonoDomain *domain,
+                                                        MonoMethod *method, MonoError *error);
 {
+       mono_error_init (error);
        return NULL;
 }
 
@@ -5864,6 +5864,7 @@ mono_aot_find_jit_info (MonoDomain *domain, MonoImage *image, gpointer addr)
 gpointer
 mono_aot_get_method_from_token (MonoDomain *domain, MonoImage *image, guint32 token, MonoError *error)
 {
+       mono_error_init (error);
        return NULL;
 }
 
@@ -5887,6 +5888,8 @@ mono_aot_patch_plt_entry (guint8 *code, guint8 *plt_entry, gpointer *got, mgreg_
 gpointer
 mono_aot_get_method_from_vt_slot (MonoDomain *domain, MonoVTable *vtable, int slot, MonoError *error)
 {
+       mono_error_init (error);
+
        return NULL;
 }