Merge pull request #3436 from ntherning/fix-alt-dir-separator-not-replaced-in-Path...
[mono.git] / mono / mini / aot-runtime.c
index 2ebae1f232242f94400f0dba9350a546e639be73..afa3a7dd0af38706cfa39638829ec6a420e9fc0b 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);
-
-                       ref->method = mono_gc_get_managed_allocator_by_type (atype, !!(mono_profiler_get_events () & MONO_PROFILE_ALLOCATIONS));
+                       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, variant);
+                       /* Try to fallback to the slow path version */
+                       if (!ref->method && variant == MANAGED_ALLOCATOR_REGULAR)
+                               ref->method = mono_gc_get_managed_allocator_by_type (atype, MANAGED_ALLOCATOR_SLOW_PATH);
                        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;
@@ -2012,6 +2002,9 @@ load_aot_module (MonoAssembly *assembly, gpointer user_data)
                find_symbol (sofile, globals, "mono_aot_file_info", (gpointer*)&info);
        }
 
+       // Copy aotid to MonoImage
+       memcpy(&assembly->image->aotid, info->aotid, 16);
+
        if (version_symbol) {
                /* Old file format */
                version = atoi (version_symbol);
@@ -2410,6 +2403,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 +2419,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 +2433,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
@@ -4048,7 +4044,7 @@ find_aot_method_in_amodule (MonoAotModule *amodule, MonoMethod *method, guint32
                        WrapperInfo *info1 = mono_marshal_get_wrapper_info (method);
                        WrapperInfo *info2 = mono_marshal_get_wrapper_info (m);
 
-                       if (info1 && info2 && info1->subtype == info2->subtype && method->klass == m->klass) {
+                       if (info1 && info2 && info1->subtype == info2->subtype && info1->d.delegate_invoke.method == info2->d.delegate_invoke.method) {
                                index = value;
                                break;
                        }
@@ -4262,9 +4258,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 +4350,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 +4425,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 +4460,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 +4499,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 +4512,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 +4602,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 +5833,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 +5867,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 +5891,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;
 }