Merge pull request #2869 from BrzVlad/feature-mod-union-opt
[mono.git] / mono / mini / aot-runtime.c
index f3d63ff909e4551fe89af55e805578ac1146334e..d3f3cf2e952c82b946e69b7a834082609d318d2e 100644 (file)
@@ -8,6 +8,7 @@
  * (C) 2002 Ximian, Inc.
  * Copyright 2003-2011 Novell, Inc.
  * Copyright 2011 Xamarin, Inc.
+ * Licensed under the MIT license. See LICENSE file in the project root for full license information.
  */
 
 #include "config.h"
@@ -245,36 +246,36 @@ amodule_unlock (MonoAotModule *amodule)
  * load_image:
  *
  *   Load one of the images referenced by AMODULE. Returns NULL if the image is not
- * found, and sets the loader error if SET_ERROR is TRUE.
+ * found, and sets @error for what happened
  */
 static MonoImage *
-load_image (MonoAotModule *amodule, int index, gboolean set_error)
+load_image (MonoAotModule *amodule, int index, MonoError *error)
 {
        MonoAssembly *assembly;
        MonoImageOpenStatus status;
 
        g_assert (index < amodule->image_table_len);
 
+       mono_error_init (error);
+
        if (amodule->image_table [index])
                return amodule->image_table [index];
-       if (amodule->out_of_date)
+       if (amodule->out_of_date) {
+               mono_error_set_bad_image_name (error, amodule->aot_name, "Image out of date");
                return NULL;
+       }
 
        assembly = mono_assembly_load (&amodule->image_names [index], amodule->assembly->basedir, &status);
        if (!assembly) {
                mono_trace (G_LOG_LEVEL_INFO, MONO_TRACE_AOT, "AOT: module %s is unusable because dependency %s is not found.\n", amodule->aot_name, amodule->image_names [index].name);
+               mono_error_set_bad_image_name (error, amodule->aot_name, "module is unusable because dependency %s is not found (error %d).\n", amodule->image_names [index].name, status);
                amodule->out_of_date = TRUE;
-
-               if (set_error) {
-                       char *full_name = mono_stringify_assembly_name (&amodule->image_names [index]);
-                       mono_loader_set_error_assembly_load (full_name, FALSE);
-                       g_free (full_name);
-               }
                return NULL;
        }
 
        if (strcmp (assembly->image->guid, amodule->image_guids [index])) {
                mono_trace (G_LOG_LEVEL_INFO, MONO_TRACE_AOT, "AOT: module %s is unusable (GUID of dependent assembly %s doesn't match (expected '%s', got '%s').\n", amodule->aot_name, amodule->image_names [index].name, amodule->image_guids [index], assembly->image->guid);
+               mono_error_set_bad_image_name (error, amodule->aot_name, "module is unusable (GUID of dependent assembly %s doesn't match (expected '%s', got '%s').\n", amodule->image_names [index].name, amodule->image_guids [index], assembly->image->guid);
                amodule->out_of_date = TRUE;
                return NULL;
        }
@@ -356,7 +357,7 @@ mono_aot_get_offset (guint32 *table, int index)
 }
 
 static MonoMethod*
-decode_resolve_method_ref (MonoAotModule *module, guint8 *buf, guint8 **endbuf);
+decode_resolve_method_ref (MonoAotModule *module, guint8 *buf, guint8 **endbuf, MonoError *error);
 
 static MonoClass*
 decode_klass_ref (MonoAotModule *module, guint8 *buf, guint8 **endbuf, MonoError *error);
@@ -394,19 +395,18 @@ decode_generic_inst (MonoAotModule *module, guint8 *buf, guint8 **endbuf, MonoEr
 }
 
 static gboolean
-decode_generic_context (MonoAotModule *module, MonoGenericContext *ctx, guint8 *buf, guint8 **endbuf)
+decode_generic_context (MonoAotModule *module, MonoGenericContext *ctx, guint8 *buf, guint8 **endbuf, MonoError *error)
 {
-       MonoError error;
        guint8 *p = buf;
        guint8 *p2;
        int argc;
+       mono_error_init (error);
 
        p2 = p;
        argc = decode_value (p, &p);
        if (argc) {
                p = p2;
-               ctx->class_inst = decode_generic_inst (module, p, &p, &error);
-               mono_error_cleanup (&error); /* FIXME don't swallow the error */
+               ctx->class_inst = decode_generic_inst (module, p, &p, error);
                if (!ctx->class_inst)
                        return FALSE;
        }
@@ -414,8 +414,7 @@ decode_generic_context (MonoAotModule *module, MonoGenericContext *ctx, guint8 *
        argc = decode_value (p, &p);
        if (argc) {
                p = p2;
-               ctx->method_inst = decode_generic_inst (module, p, &p, &error);
-               mono_error_cleanup (&error); /* FIXME don't swallow the error */
+               ctx->method_inst = decode_generic_inst (module, p, &p, error);
                if (!ctx->method_inst)
                        return FALSE;
        }
@@ -444,20 +443,16 @@ decode_klass_ref (MonoAotModule *module, guint8 *buf, guint8 **endbuf, MonoError
        switch (reftype) {
        case MONO_AOT_TYPEREF_TYPEDEF_INDEX:
                idx = decode_value (p, &p);
-               image = load_image (module, 0, TRUE);
-               if (!image) {
-                       mono_error_set_from_loader_error (error);
+               image = load_image (module, 0, error);
+               if (!image)
                        return NULL;
-               }
                klass = mono_class_get_checked (image, MONO_TOKEN_TYPE_DEF + idx, error);
                break;
        case MONO_AOT_TYPEREF_TYPEDEF_INDEX_IMAGE:
                idx = decode_value (p, &p);
-               image = load_image (module, decode_value (p, &p), TRUE);
-               if (!image) {
-                       mono_error_set_from_loader_error (error);
+               image = load_image (module, decode_value (p, &p), error);
+               if (!image)
                        return NULL;
-               }
                klass = mono_class_get_checked (image, MONO_TOKEN_TYPE_DEF + idx, error);
                break;
        case MONO_AOT_TYPEREF_TYPESPEC_TOKEN:
@@ -520,11 +515,9 @@ decode_klass_ref (MonoAotModule *module, guint8 *buf, guint8 **endbuf, MonoError
                                if (is_method) {
                                        MonoMethod *method_def;
                                        g_assert (type == MONO_TYPE_MVAR);
-                                       method_def = decode_resolve_method_ref (module, p, &p);
-                                       if (!method_def) {
-                                               mono_error_set_bad_image_name (error, module->aot_name, "Could not decode methodref when computing owned method typeref var");
+                                       method_def = decode_resolve_method_ref (module, p, &p, error);
+                                       if (!method_def)
                                                return NULL;
-                                       }
 
                                        container = mono_method_get_generic_container (method_def);
                                } else {
@@ -847,16 +840,18 @@ typedef struct {
  * that the method reference matches a given method. This is normally not a problem
  * as these wrappers only occur in the extra_methods table, where we already have
  * a method we want to lookup.
+ *
+ * If there was a decoding error, we return FALSE and set @error
  */
 static gboolean
-decode_method_ref_with_target (MonoAotModule *module, MethodRef *ref, MonoMethod *target, guint8 *buf, guint8 **endbuf)
+decode_method_ref_with_target (MonoAotModule *module, MethodRef *ref, MonoMethod *target, guint8 *buf, guint8 **endbuf, MonoError *error)
 {
-       MonoError error;
        guint32 image_index, value;
        MonoImage *image = NULL;
        guint8 *p = buf;
 
        memset (ref, 0, sizeof (MethodRef));
+       mono_error_init (error);
 
        value = decode_value (p, &p);
        image_index = value >> 24;
@@ -868,8 +863,9 @@ decode_method_ref_with_target (MonoAotModule *module, MethodRef *ref, MonoMethod
        }
 
        if (image_index < MONO_AOT_METHODREF_MIN || image_index == MONO_AOT_METHODREF_METHODSPEC || image_index == MONO_AOT_METHODREF_GINST) {
-               if (target && target->wrapper_type)
+               if (target && target->wrapper_type) {
                        return FALSE;
+               }
        }
 
        if (image_index == MONO_AOT_METHODREF_WRAPPER) {
@@ -887,8 +883,7 @@ decode_method_ref_with_target (MonoAotModule *module, MethodRef *ref, MonoMethod
                switch (wrapper_type) {
 #ifndef DISABLE_REMOTING
                case MONO_WRAPPER_REMOTING_INVOKE_WITH_CHECK: {
-                       MonoMethod *m = decode_resolve_method_ref (module, p, &p);
-
+                       MonoMethod *m = decode_resolve_method_ref (module, p, &p, error);
                        if (!m)
                                return FALSE;
                        mono_class_init (m->klass);
@@ -899,8 +894,7 @@ decode_method_ref_with_target (MonoAotModule *module, MethodRef *ref, MonoMethod
                        break;
                }
                case MONO_WRAPPER_PROXY_ISINST: {
-                       MonoClass *klass = decode_klass_ref (module, p, &p, &error);
-                       mono_error_cleanup (&error); /* FIXME don't swallow the error */
+                       MonoClass *klass = decode_klass_ref (module, p, &p, error);
                        if (!klass)
                                return FALSE;
                        ref->method = mono_marshal_get_proxy_cancast (klass);
@@ -910,8 +904,7 @@ decode_method_ref_with_target (MonoAotModule *module, MethodRef *ref, MonoMethod
                case MONO_WRAPPER_LDFLDA:
                case MONO_WRAPPER_STFLD:
                case MONO_WRAPPER_ISINST: {
-                       MonoClass *klass = decode_klass_ref (module, p, &p, &error);
-                       mono_error_cleanup (&error); /* FIXME don't swallow the error */
+                       MonoClass *klass = decode_klass_ref (module, p, &p, error);
                        if (!klass)
                                return FALSE;
                        if (wrapper_type == MONO_WRAPPER_LDFLD)
@@ -922,8 +915,10 @@ decode_method_ref_with_target (MonoAotModule *module, MethodRef *ref, MonoMethod
                                ref->method = mono_marshal_get_stfld_wrapper (&klass->byval_arg);
                        else if (wrapper_type == MONO_WRAPPER_ISINST)
                                ref->method = mono_marshal_get_isinst (klass);
-                       else
-                               g_assert_not_reached ();
+                       else {
+                               mono_error_set_bad_image_name (error, module->aot_name, "Unknown AOT wrapper type %d", wrapper_type);
+                               return FALSE;
+                       }
                        break;
                }
                case MONO_WRAPPER_LDFLD_REMOTE:
@@ -937,8 +932,10 @@ decode_method_ref_with_target (MonoAotModule *module, MethodRef *ref, MonoMethod
                        int atype = decode_value (p, &p);
 
                        ref->method = mono_gc_get_managed_allocator_by_type (atype, !!(mono_profiler_get_events () & MONO_PROFILE_ALLOCATIONS));
-                       if (!ref->method)
-                               g_error ("Error: No managed allocator, but we need one for AOT.\nAre you using non-standard GC options?\n");
+                       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;
+                       }
                        break;
                }
                case MONO_WRAPPER_WRITE_BARRIER: {
@@ -970,13 +967,13 @@ decode_method_ref_with_target (MonoAotModule *module, MethodRef *ref, MonoMethod
                                        return FALSE;
                                }
                        } else {
-                               g_assert_not_reached ();
+                               mono_error_set_bad_image_name (error, module->aot_name, "Invalid STELEMREF subtype %d", subtype);
+                               return FALSE;
                        }
                        break;
                }
                case MONO_WRAPPER_SYNCHRONIZED: {
-                       MonoMethod *m = decode_resolve_method_ref (module, p, &p);
-
+                       MonoMethod *m = decode_resolve_method_ref (module, p, &p, error);
                        if (!m)
                                return FALSE;
                        ref->method = mono_marshal_get_synchronized_wrapper (m);
@@ -986,9 +983,7 @@ decode_method_ref_with_target (MonoAotModule *module, MethodRef *ref, MonoMethod
                        int subtype = decode_value (p, &p);
 
                        if (subtype == WRAPPER_SUBTYPE_PTR_TO_STRUCTURE || subtype == WRAPPER_SUBTYPE_STRUCTURE_TO_PTR) {
-                               MonoClass *klass = decode_klass_ref (module, p, &p, &error);
-                               mono_error_cleanup (&error); /* FIXME don't swallow the error */
-                               
+                               MonoClass *klass = decode_klass_ref (module, p, &p, error);
                                if (!klass)
                                        return FALSE;
 
@@ -1007,14 +1002,12 @@ decode_method_ref_with_target (MonoAotModule *module, MethodRef *ref, MonoMethod
                                        ref->method = mono_marshal_get_struct_to_ptr (klass);
                                }
                        } else if (subtype == WRAPPER_SUBTYPE_SYNCHRONIZED_INNER) {
-                               MonoMethod *m = decode_resolve_method_ref (module, p, &p);
-
+                               MonoMethod *m = decode_resolve_method_ref (module, p, &p, error);
                                if (!m)
                                        return FALSE;
                                ref->method = mono_marshal_get_synchronized_inner_wrapper (m);
                        } else if (subtype == WRAPPER_SUBTYPE_ARRAY_ACCESSOR) {
-                               MonoMethod *m = decode_resolve_method_ref (module, p, &p);
-
+                               MonoMethod *m = decode_resolve_method_ref (module, p, &p, error);
                                if (!m)
                                        return FALSE;
                                ref->method = mono_marshal_get_array_accessor_wrapper (m);
@@ -1033,7 +1026,8 @@ decode_method_ref_with_target (MonoAotModule *module, MethodRef *ref, MonoMethod
                                        return FALSE;
                                ref->method = mini_get_gsharedvt_out_sig_wrapper (sig);
                        } else {
-                               g_assert_not_reached ();
+                               mono_error_set_bad_image_name (error, module->aot_name, "Invalid UNKNOWN wrapper subtype %d", subtype);
+                               return FALSE;
                        }
                        break;
                }
@@ -1048,7 +1042,7 @@ decode_method_ref_with_target (MonoAotModule *module, MethodRef *ref, MonoMethod
                        } else if (subtype == WRAPPER_SUBTYPE_STRING_CTOR) {
                                MonoMethod *m;
 
-                               m = decode_resolve_method_ref (module, p, &p);
+                               m = decode_resolve_method_ref (module, p, &p, error);
                                if (!m)
                                        return FALSE;
 
@@ -1078,8 +1072,7 @@ decode_method_ref_with_target (MonoAotModule *module, MethodRef *ref, MonoMethod
                                        return FALSE;
                                ref->method = target;
                        } else {
-                               m = decode_resolve_method_ref (module, p, &p);
-
+                               m = decode_resolve_method_ref (module, p, &p, error);
                                if (!m)
                                        return FALSE;
 
@@ -1100,8 +1093,10 @@ decode_method_ref_with_target (MonoAotModule *module, MethodRef *ref, MonoMethod
                                ref->method = mono_marshal_get_castclass_with_cache ();
                        else if (subtype == WRAPPER_SUBTYPE_ISINST_WITH_CACHE)
                                ref->method = mono_marshal_get_isinst_with_cache ();
-                       else
-                               g_assert_not_reached ();
+                       else {
+                               mono_error_set_bad_image_name (error, module->aot_name, "Invalid CASTCLASS wrapper subtype %d", subtype);
+                               return FALSE;
+                       }
                        break;
                }
                case MONO_WRAPPER_RUNTIME_INVOKE: {
@@ -1116,15 +1111,13 @@ decode_method_ref_with_target (MonoAotModule *module, MethodRef *ref, MonoMethod
                                ref->method = target;
                        } else if (subtype == WRAPPER_SUBTYPE_RUNTIME_INVOKE_DIRECT) {
                                /* Direct wrapper */
-                               MonoMethod *m = decode_resolve_method_ref (module, p, &p);
-
+                               MonoMethod *m = decode_resolve_method_ref (module, p, &p, error);
                                if (!m)
                                        return FALSE;
                                ref->method = mono_marshal_get_runtime_invoke (m, FALSE);
                        } else if (subtype == WRAPPER_SUBTYPE_RUNTIME_INVOKE_VIRTUAL) {
                                /* Virtual direct wrapper */
-                               MonoMethod *m = decode_resolve_method_ref (module, p, &p);
-
+                               MonoMethod *m = decode_resolve_method_ref (module, p, &p, error);
                                if (!m)
                                        return FALSE;
                                ref->method = mono_marshal_get_runtime_invoke (m, TRUE);
@@ -1155,8 +1148,7 @@ decode_method_ref_with_target (MonoAotModule *module, MethodRef *ref, MonoMethod
                                MonoClass *klass;
                                MonoMethod *invoke, *wrapper;
 
-                               klass = decode_klass_ref (module, p, &p, &error);
-                               mono_error_cleanup (&error); /* FIXME don't swallow the error */
+                               klass = decode_klass_ref (module, p, &p, error);
                                if (!klass)
                                        return FALSE;
 
@@ -1218,11 +1210,10 @@ decode_method_ref_with_target (MonoAotModule *module, MethodRef *ref, MonoMethod
                        MonoMethod *m;
                        MonoClass *klass;
 
-                       m = decode_resolve_method_ref (module, p, &p);
+                       m = decode_resolve_method_ref (module, p, &p, error);
                        if (!m)
                                return FALSE;
-                       klass = decode_klass_ref (module, p, &p, &error);
-                       mono_error_cleanup (&error); /* FIXME don't swallow the error */
+                       klass = decode_klass_ref (module, p, &p, error);
                        if (!klass)
                                return FALSE;
                        ref->method = mono_marshal_get_managed_wrapper (m, klass, 0);
@@ -1235,11 +1226,10 @@ decode_method_ref_with_target (MonoAotModule *module, MethodRef *ref, MonoMethod
                image_index = decode_value (p, &p);
                ref->token = decode_value (p, &p);
 
-               image = load_image (module, image_index, TRUE);
+               image = load_image (module, image_index, error);
                if (!image)
                        return FALSE;
        } else if (image_index == MONO_AOT_METHODREF_GINST) {
-               MonoError error;
                MonoClass *klass;
                MonoGenericContext ctx;
 
@@ -1247,8 +1237,7 @@ decode_method_ref_with_target (MonoAotModule *module, MethodRef *ref, MonoMethod
                 * These methods do not have a token which resolves them, so we 
                 * resolve them immediately.
                 */
-               klass = decode_klass_ref (module, p, &p, &error);
-               mono_error_cleanup (&error); /* FIXME don't swallow the error */
+               klass = decode_klass_ref (module, p, &p, error);
                if (!klass)
                        return FALSE;
 
@@ -1258,15 +1247,14 @@ decode_method_ref_with_target (MonoAotModule *module, MethodRef *ref, MonoMethod
                image_index = decode_value (p, &p);
                ref->token = decode_value (p, &p);
 
-               image = load_image (module, image_index, TRUE);
+               image = load_image (module, image_index, error);
                if (!image)
                        return FALSE;
 
-               ref->method = mono_get_method_checked (image, ref->token, NULL, NULL, &error);
-               if (!ref->method) {
-                       mono_error_cleanup (&error); /* FIXME don't swallow the error */
+               ref->method = mono_get_method_checked (image, ref->token, NULL, NULL, error);
+               if (!ref->method)
                        return FALSE;
-               }
+
 
                memset (&ctx, 0, sizeof (ctx));
 
@@ -1274,26 +1262,25 @@ decode_method_ref_with_target (MonoAotModule *module, MethodRef *ref, MonoMethod
                        ctx.class_inst = klass->generic_class->context.class_inst;
                        ctx.method_inst = NULL;
  
-                       ref->method = mono_class_inflate_generic_method_full_checked (ref->method, klass, &ctx, &error);
+                       ref->method = mono_class_inflate_generic_method_full_checked (ref->method, klass, &ctx, error);
                        if (!ref->method)
-                               g_error ("AOT runtime could not load method due to %s", mono_error_get_message (&error)); /* FIXME don't swallow the error */
+                               return FALSE;
                }                       
 
                memset (&ctx, 0, sizeof (ctx));
 
-               if (!decode_generic_context (module, &ctx, p, &p))
+               if (!decode_generic_context (module, &ctx, p, &p, error))
                        return FALSE;
 
-               ref->method = mono_class_inflate_generic_method_full_checked (ref->method, klass, &ctx, &error);
+               ref->method = mono_class_inflate_generic_method_full_checked (ref->method, klass, &ctx, error);
                if (!ref->method)
-                       g_error ("AOT runtime could not load method due to %s", mono_error_get_message (&error)); /* FIXME don't swallow the error */
+                       return FALSE;
 
        } else if (image_index == MONO_AOT_METHODREF_ARRAY) {
                MonoClass *klass;
                int method_type;
 
-               klass = decode_klass_ref (module, p, &p, &error);
-               mono_error_cleanup (&error); /* FIXME don't swallow the error */
+               klass = decode_klass_ref (module, p, &p, error);
                if (!klass)
                        return FALSE;
                method_type = decode_value (p, &p);
@@ -1314,7 +1301,8 @@ decode_method_ref_with_target (MonoAotModule *module, MethodRef *ref, MonoMethod
                        ref->method = mono_class_get_method_from_name (klass, "Set", -1);
                        break;
                default:
-                       g_assert_not_reached ();
+                       mono_error_set_bad_image_name (error, module->aot_name, "Invalid METHODREF_ARRAY method type %d", method_type);
+                       return FALSE;
                }
        } else {
                if (image_index == MONO_AOT_METHODREF_LARGE_IMAGE_INDEX) {
@@ -1324,7 +1312,7 @@ decode_method_ref_with_target (MonoAotModule *module, MethodRef *ref, MonoMethod
 
                ref->token = MONO_TOKEN_METHOD_DEF | (value & 0xffffff);
 
-               image = load_image (module, image_index, TRUE);
+               image = load_image (module, image_index, error);
                if (!image)
                        return FALSE;
        }
@@ -1337,9 +1325,9 @@ decode_method_ref_with_target (MonoAotModule *module, MethodRef *ref, MonoMethod
 }
 
 static gboolean
-decode_method_ref (MonoAotModule *module, MethodRef *ref, guint8 *buf, guint8 **endbuf)
+decode_method_ref (MonoAotModule *module, MethodRef *ref, guint8 *buf, guint8 **endbuf, MonoError *error)
 {
-       return decode_method_ref_with_target (module, ref, NULL, buf, endbuf);
+       return decode_method_ref_with_target (module, ref, NULL, buf, endbuf, error);
 }
 
 /*
@@ -1348,30 +1336,27 @@ decode_method_ref (MonoAotModule *module, MethodRef *ref, guint8 *buf, guint8 **
  *   Similar to decode_method_ref, but resolve and return the method itself.
  */
 static MonoMethod*
-decode_resolve_method_ref_with_target (MonoAotModule *module, MonoMethod *target, guint8 *buf, guint8 **endbuf)
+decode_resolve_method_ref_with_target (MonoAotModule *module, MonoMethod *target, guint8 *buf, guint8 **endbuf, MonoError *error)
 {
-       MonoError error;
        MethodRef ref;
-       gboolean res;
-       MonoMethod *result;
 
-       res = decode_method_ref_with_target (module, &ref, target, buf, endbuf);
-       if (!res)
+       mono_error_init (error);
+
+       if (!decode_method_ref_with_target (module, &ref, target, buf, endbuf, error))
                return NULL;
        if (ref.method)
                return ref.method;
-       if (!ref.image)
+       if (!ref.image) {
+               mono_error_set_bad_image_name (error, module->aot_name, "No image found for methodref with target");
                return NULL;
-       result = mono_get_method_checked (ref.image, ref.token, NULL, NULL, &error);
-       if (!result)
-               mono_error_cleanup (&error); /* FIXME don't swallow the error */
-       return result;
+       }
+       return mono_get_method_checked (ref.image, ref.token, NULL, NULL, error);
 }
 
 static MonoMethod*
-decode_resolve_method_ref (MonoAotModule *module, guint8 *buf, guint8 **endbuf)
+decode_resolve_method_ref (MonoAotModule *module, guint8 *buf, guint8 **endbuf, MonoError *error)
 {
-       return decode_resolve_method_ref_with_target (module, NULL, buf, endbuf);
+       return decode_resolve_method_ref_with_target (module, NULL, buf, endbuf, error);
 }
 
 #ifdef ENABLE_AOT_CACHE
@@ -2002,7 +1987,10 @@ load_aot_module (MonoAssembly *assembly, gpointer user_data)
                                mono_trace (G_LOG_LEVEL_INFO, MONO_TRACE_AOT, "AOT module '%s' not found: %s\n", aot_name, err);
                                g_free (err);
 
-                               aot_name = g_strdup_printf ("%s/mono/aot-cache/%s/%s%s", mono_assembly_getrootdir(), MONO_ARCHITECTURE, g_path_get_basename (assembly->image->name), MONO_SOLIB_EXT);
+                               g_free (aot_name);
+                               char *basename = g_path_get_basename (assembly->image->name);
+                               aot_name = g_strdup_printf ("%s/mono/aot-cache/%s/%s%s", mono_assembly_getrootdir(), MONO_ARCHITECTURE, basename, MONO_SOLIB_EXT);
+                               g_free (basename);
                                sofile = mono_dl_open (aot_name, MONO_DL_LAZY, &err);
                                if (!sofile) {
                                        mono_trace (G_LOG_LEVEL_INFO, MONO_TRACE_AOT, "AOT module '%s' not found: %s\n", aot_name, err);
@@ -2284,8 +2272,11 @@ load_aot_module (MonoAssembly *assembly, gpointer user_data)
        }
 #endif
        if (do_load_image) {
-               for (i = 0; i < amodule->image_table_len; ++i)
-                       load_image (amodule, i, FALSE);
+               for (i = 0; i < amodule->image_table_len; ++i) {
+                       MonoError error;
+                       load_image (amodule, i, &error);
+                       mono_error_cleanup (&error); /* FIXME don't swallow the error */
+               }
        }
 
        if (amodule->out_of_date) {
@@ -2362,6 +2353,7 @@ mono_aot_cleanup (void)
 static gboolean
 decode_cached_class_info (MonoAotModule *module, MonoCachedClassInfo *info, guint8 *buf, guint8 **endbuf)
 {
+       MonoError error;
        guint32 flags;
        MethodRef ref;
        gboolean res;
@@ -2382,13 +2374,15 @@ decode_cached_class_info (MonoAotModule *module, MonoCachedClassInfo *info, guin
        info->is_generic_container = (flags >> 8) & 0x1;
 
        if (info->has_cctor) {
-               res = decode_method_ref (module, &ref, buf, &buf);
+               res = decode_method_ref (module, &ref, buf, &buf, &error);
+               mono_error_assert_ok (&error); /* FIXME don't swallow the error */
                if (!res)
                        return FALSE;
                info->cctor_token = ref.token;
        }
        if (info->has_finalize) {
-               res = decode_method_ref (module, &ref, buf, &buf);
+               res = decode_method_ref (module, &ref, buf, &buf, &error);
+               mono_error_assert_ok (&error); /* FIXME don't swallow the error */
                if (!res)
                        return FALSE;
                info->finalize_image = ref.image;
@@ -2408,6 +2402,7 @@ decode_cached_class_info (MonoAotModule *module, MonoCachedClassInfo *info, guin
 gpointer
 mono_aot_get_method_from_vt_slot (MonoDomain *domain, MonoVTable *vtable, int slot)
 {
+       MonoError error;
        int i;
        MonoClass *klass = vtable->klass;
        MonoAotModule *amodule = (MonoAotModule *)klass->image->aot_module;
@@ -2427,10 +2422,13 @@ mono_aot_get_method_from_vt_slot (MonoDomain *domain, MonoVTable *vtable, int sl
        if (!err)
                return NULL;
 
-       for (i = 0; i < slot; ++i)
-               decode_method_ref (amodule, &ref, p, &p);
+       for (i = 0; i < slot; ++i) {
+               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);
+       res = decode_method_ref (amodule, &ref, p, &p, &error);
+       mono_error_cleanup (&error); /* FIXME don't swallow the error */
        if (!res)
                return NULL;
        if (ref.no_aot_trampoline)
@@ -3055,12 +3053,14 @@ decode_exception_debug_info (MonoAotModule *amodule, MonoDomain *domain,
                }
 
                len = decode_value (p, &p);
-               if (async)
+               if (async) {
                        p += len;
-               else
-                       jinfo->d.method = decode_resolve_method_ref (amodule, p, &p);
+               } else {
+                       jinfo->d.method = decode_resolve_method_ref (amodule, p, &p, &error);
+                       mono_error_cleanup (&error); /* FIXME don't swallow the error */
+               }
 
-               gi->generic_sharing_context = g_new0 (MonoGenericSharingContext, 1);
+               gi->generic_sharing_context = alloc0_jit_info_data (domain, sizeof (MonoGenericSharingContext), async);
                if (decode_value (p, &p)) {
                        /* gsharedvt */
                        MonoGenericSharingContext *gsctx = gi->generic_sharing_context;
@@ -3217,6 +3217,7 @@ msort_method_addresses (gpointer *array, int *indexes, int len)
 MonoJitInfo *
 mono_aot_find_jit_info (MonoDomain *domain, MonoImage *image, gpointer addr)
 {
+       MonoError error;
        int pos, left, right, code_len;
        int method_index, table_len;
        guint32 token;
@@ -3370,7 +3371,8 @@ mono_aot_find_jit_info (MonoDomain *domain, MonoImage *image, gpointer addr)
                                }
 
                                p = amodule->blob + table [(pos * 2) + 1];
-                               method = decode_resolve_method_ref (amodule, p, &p);
+                               method = decode_resolve_method_ref (amodule, p, &p, &error);
+                               mono_error_cleanup (&error); /* FIXME don't swallow the error */
                                if (!method)
                                        /* Happens when a random address is passed in which matches a not-yey called wrapper encoded using its name */
                                        return NULL;
@@ -3449,7 +3451,8 @@ decode_patch (MonoAotModule *aot_module, MonoMemPool *mp, MonoJumpInfo *ji, guin
                MethodRef ref;
                gboolean res;
 
-               res = decode_method_ref (aot_module, &ref, p, &p);
+               res = decode_method_ref (aot_module, &ref, p, &p, &error);
+               mono_error_assert_ok (&error); /* FIXME don't swallow the error */
                if (!res)
                        goto cleanup;
 
@@ -3481,7 +3484,8 @@ decode_patch (MonoAotModule *aot_module, MonoMemPool *mp, MonoJumpInfo *ji, guin
        }
        case MONO_PATCH_INFO_METHODCONST:
                /* Shared */
-               ji->data.method = decode_resolve_method_ref (aot_module, p, &p);
+               ji->data.method = decode_resolve_method_ref (aot_module, p, &p, &error);
+               mono_error_cleanup (&error); /* FIXME don't swallow the error */
                if (!ji->data.method)
                        goto cleanup;
                break;
@@ -3502,14 +3506,16 @@ decode_patch (MonoAotModule *aot_module, MonoMemPool *mp, MonoJumpInfo *ji, guin
                if (!ji->data.del_tramp->klass)
                        goto cleanup;
                if (decode_value (p, &p)) {
-                       ji->data.del_tramp->method = decode_resolve_method_ref (aot_module, p, &p);
+                       ji->data.del_tramp->method = decode_resolve_method_ref (aot_module, p, &p, &error);
+                       mono_error_cleanup (&error); /* FIXME don't swallow the error */
                        if (!ji->data.del_tramp->method)
                                goto cleanup;
                }
                ji->data.del_tramp->is_virtual = decode_value (p, &p) ? TRUE : FALSE;
                break;
        case MONO_PATCH_INFO_IMAGE:
-               ji->data.image = load_image (aot_module, decode_value (p, &p), TRUE);
+               ji->data.image = load_image (aot_module, decode_value (p, &p), &error);
+               mono_error_cleanup (&error); /* FIXME don't swallow the error */
                if (!ji->data.image)
                        goto cleanup;
                break;
@@ -3549,7 +3555,8 @@ decode_patch (MonoAotModule *aot_module, MonoMemPool *mp, MonoJumpInfo *ji, guin
                break;
        }
        case MONO_PATCH_INFO_LDSTR:
-               image = load_image (aot_module, decode_value (p, &p), TRUE);
+               image = load_image (aot_module, decode_value (p, &p), &error);
+               mono_error_cleanup (&error); /* FIXME don't swallow the error */
                if (!image)
                        goto cleanup;
                ji->data.token = mono_jump_info_token_new (mp, image, MONO_TOKEN_STRING + decode_value (p, &p));
@@ -3559,14 +3566,16 @@ decode_patch (MonoAotModule *aot_module, MonoMemPool *mp, MonoJumpInfo *ji, guin
        case MONO_PATCH_INFO_LDTOKEN:
        case MONO_PATCH_INFO_TYPE_FROM_HANDLE:
                /* Shared */
-               image = load_image (aot_module, decode_value (p, &p), TRUE);
+               image = load_image (aot_module, decode_value (p, &p), &error);
+               mono_error_cleanup (&error); /* FIXME don't swallow the error */
                if (!image)
                        goto cleanup;
                ji->data.token = mono_jump_info_token_new (mp, image, decode_value (p, &p));
 
                ji->data.token->has_context = decode_value (p, &p);
                if (ji->data.token->has_context) {
-                       gboolean res = decode_generic_context (aot_module, &ji->data.token->context, p, &p);
+                       gboolean res = decode_generic_context (aot_module, &ji->data.token->context, p, &p, &error);
+                       mono_error_cleanup (&error); /* FIXME don't swallow the error */
                        if (!res)
                                goto cleanup;
                }
@@ -3602,11 +3611,12 @@ decode_patch (MonoAotModule *aot_module, MonoMemPool *mp, MonoJumpInfo *ji, guin
 
                entry = (MonoJumpInfoRgctxEntry *)mono_mempool_alloc0 (mp, sizeof (MonoJumpInfoRgctxEntry));
                p2 = aot_module->blob + offset;
-               entry->method = decode_resolve_method_ref (aot_module, p2, &p2);
+               entry->method = decode_resolve_method_ref (aot_module, p2, &p2, &error);
                entry->in_mrgctx = ((val & 1) > 0) ? TRUE : FALSE;
                entry->info_type = (MonoRgctxInfoType)((val >> 1) & 0xff);
                entry->data = (MonoJumpInfo *)mono_mempool_alloc0 (mp, sizeof (MonoJumpInfo));
                entry->data->type = (MonoJumpInfoType)((val >> 9) & 0xff);
+               mono_error_cleanup (&error); /* FIXME don't swallow the error */
                
                res = decode_patch (aot_module, mp, entry->data, p, &p);
                if (!res)
@@ -3629,8 +3639,8 @@ decode_patch (MonoAotModule *aot_module, MonoMemPool *mp, MonoJumpInfo *ji, guin
                MonoJumpInfoGSharedVtCall *info = (MonoJumpInfoGSharedVtCall *)mono_mempool_alloc0 (mp, sizeof (MonoJumpInfoGSharedVtCall));
                info->sig = decode_signature (aot_module, p, &p);
                g_assert (info->sig);
-               info->method = decode_resolve_method_ref (aot_module, p, &p);
-               g_assert (info->method);
+               info->method = decode_resolve_method_ref (aot_module, p, &p, &error);
+               mono_error_assert_ok (&error); /* FIXME don't swallow the error */
 
                ji->data.target = info;
                break;
@@ -3639,8 +3649,9 @@ decode_patch (MonoAotModule *aot_module, MonoMemPool *mp, MonoJumpInfo *ji, guin
                MonoGSharedVtMethodInfo *info = (MonoGSharedVtMethodInfo *)mono_mempool_alloc0 (mp, sizeof (MonoGSharedVtMethodInfo));
                int i;
                
-               info->method = decode_resolve_method_ref (aot_module, p, &p);
-               g_assert (info->method);
+               info->method = decode_resolve_method_ref (aot_module, p, &p, &error);
+               mono_error_assert_ok (&error); /* FIXME don't swallow the error */
+
                info->num_entries = decode_value (p, &p);
                info->count_entries = info->num_entries;
                info->entries = (MonoRuntimeGenericContextInfoTemplate *)mono_mempool_alloc0 (mp, sizeof (MonoRuntimeGenericContextInfoTemplate) * info->num_entries);
@@ -3685,10 +3696,10 @@ decode_patch (MonoAotModule *aot_module, MonoMemPool *mp, MonoJumpInfo *ji, guin
                MonoJumpInfoVirtMethod *info = (MonoJumpInfoVirtMethod *)mono_mempool_alloc0 (mp, sizeof (MonoJumpInfoVirtMethod));
 
                info->klass = decode_klass_ref (aot_module, p, &p, &error);
-               mono_error_cleanup (&error); /* FIXME don't swallow the error */
-               g_assert (info->klass);
-               info->method = decode_resolve_method_ref (aot_module, p, &p);
-               g_assert (info->method);
+               mono_error_assert_ok (&error); /* FIXME don't swallow the error */
+
+               info->method = decode_resolve_method_ref (aot_module, p, &p, &error);
+               mono_error_assert_ok (&error); /* FIXME don't swallow the error */
 
                ji->data.target = info;
                break;
@@ -3967,6 +3978,7 @@ load_method (MonoDomain *domain, MonoAotModule *amodule, MonoImage *image, MonoM
 static guint32
 find_aot_method_in_amodule (MonoAotModule *amodule, MonoMethod *method, guint32 hash_full)
 {
+       MonoError error;
        guint32 table_size, entry_size, hash;
        guint32 *table, *entry;
        guint32 index;
@@ -4002,7 +4014,8 @@ find_aot_method_in_amodule (MonoAotModule *amodule, MonoMethod *method, guint32
                m = (MonoMethod *)g_hash_table_lookup (amodule->method_ref_to_method, p);
                amodule_unlock (amodule);
                if (!m) {
-                       m = decode_resolve_method_ref_with_target (amodule, method, p, &p);
+                       m = decode_resolve_method_ref_with_target (amodule, method, p, &p, &error);
+                       mono_error_cleanup (&error); /* FIXME don't swallow the error */
                        /*
                         * Can't catche runtime invoke wrappers since it would break
                         * the check in decode_method_ref_with_target ().
@@ -5209,7 +5222,9 @@ get_new_trampoline_from_page (int tramp_type)
                /* allocate two contiguous pages of memory: the first page will contain the data (like a local constant pool)
                 * while the second will contain the trampolines.
                 */
-               ret = vm_allocate (mach_task_self (), &addr, psize * 2, VM_FLAGS_ANYWHERE);
+               do {
+                       ret = vm_allocate (mach_task_self (), &addr, psize * 2, VM_FLAGS_ANYWHERE);
+               } while (ret == KERN_ABORTED);
                if (ret != KERN_SUCCESS) {
                        g_error ("Cannot allocate memory for trampolines: %d", ret);
                        break;