Merge pull request #4621 from alexanderkyte/strdup_env
[mono.git] / mono / mini / aot-runtime.c
index 23a3357d3358ecd018067e870058aad681776f45..9279967b31afbe1f14bc3e47ee00a9625c7be3c5 100644 (file)
@@ -1,5 +1,6 @@
-/*
- * aot-runtime.c: mono Ahead of Time compiler
+/**
+ * \file
+ * mono Ahead of Time compiler
  *
  * Author:
  *   Dietmar Maurer (dietmar@ximian.com)
@@ -257,7 +258,7 @@ load_image (MonoAotModule *amodule, int index, MonoError *error)
 
        g_assert (index < amodule->image_table_len);
 
-       mono_error_init (error);
+       error_init (error);
 
        if (amodule->image_table [index])
                return amodule->image_table [index];
@@ -374,7 +375,7 @@ decode_generic_inst (MonoAotModule *module, guint8 *buf, guint8 **endbuf, MonoEr
        MonoGenericInst *inst;
        guint8 *p = buf;
 
-       mono_error_init (error);
+       error_init (error);
        type_argc = decode_value (p, &p);
        type_argv = g_new0 (MonoType*, type_argc);
 
@@ -401,7 +402,7 @@ decode_generic_context (MonoAotModule *module, MonoGenericContext *ctx, guint8 *
        guint8 *p = buf;
        guint8 *p2;
        int argc;
-       mono_error_init (error);
+       error_init (error);
 
        p2 = p;
        argc = decode_value (p, &p);
@@ -433,7 +434,7 @@ decode_klass_ref (MonoAotModule *module, guint8 *buf, guint8 **endbuf, MonoError
        guint8 *p = buf;
        int reftype;
 
-       mono_error_init (error);
+       error_init (error);
        reftype = decode_value (p, &p);
        if (reftype == 0) {
                *endbuf = p;
@@ -621,7 +622,7 @@ decode_type (MonoAotModule *module, guint8 *buf, guint8 **endbuf, MonoError *err
        MonoType *t;
 
        t = (MonoType *)g_malloc0 (sizeof (MonoType));
-       mono_error_init (error);
+       error_init (error);
 
        while (TRUE) {
                if (*p == MONO_TYPE_PINNED) {
@@ -852,7 +853,7 @@ decode_method_ref_with_target (MonoAotModule *module, MethodRef *ref, MonoMethod
        guint8 *p = buf;
 
        memset (ref, 0, sizeof (MethodRef));
-       mono_error_init (error);
+       error_init (error);
 
        value = decode_value (p, &p);
        image_index = value >> 24;
@@ -1214,7 +1215,9 @@ decode_method_ref_with_target (MonoAotModule *module, MethodRef *ref, MonoMethod
                        klass = decode_klass_ref (module, p, &p, error);
                        if (!klass)
                                return FALSE;
-                       ref->method = mono_marshal_get_managed_wrapper (m, klass, 0);
+                       ref->method = mono_marshal_get_managed_wrapper (m, klass, 0, error);
+                       if (!mono_error_ok (error))
+                               return FALSE;
                        break;
                }
                default:
@@ -1338,7 +1341,7 @@ decode_resolve_method_ref_with_target (MonoAotModule *module, MonoMethod *target
 {
        MethodRef ref;
 
-       mono_error_init (error);
+       error_init (error);
 
        if (!decode_method_ref_with_target (module, &ref, target, buf, endbuf, error))
                return NULL;
@@ -1918,7 +1921,7 @@ init_amodule_got (MonoAotModule *amodule)
 static void
 load_aot_module (MonoAssembly *assembly, gpointer user_data)
 {
-       char *aot_name;
+       char *aot_name, *found_aot_name;
        MonoAotModule *amodule;
        MonoDl *sofile;
        gboolean usable = TRUE;
@@ -1953,6 +1956,8 @@ load_aot_module (MonoAssembly *assembly, gpointer user_data)
 
        sofile = NULL;
 
+       found_aot_name = NULL;
+
        if (info) {
                /* Statically linked AOT module */
                aot_name = g_strdup_printf ("%s", assembly->aname.name);
@@ -1962,34 +1967,59 @@ load_aot_module (MonoAssembly *assembly, gpointer user_data)
                        g_assert (globals);
                }
        } else {
+               char *err;
+
                if (enable_aot_cache)
                        sofile = aot_cache_load_module (assembly, &aot_name);
                if (!sofile) {
-                       char *err;
                        aot_name = g_strdup_printf ("%s%s", assembly->image->name, MONO_SOLIB_EXT);
 
                        sofile = mono_dl_open (aot_name, MONO_DL_LAZY, &err);
-
+                       if (sofile) {
+                               found_aot_name = g_strdup (aot_name);
+                       } else {
+                               mono_trace (G_LOG_LEVEL_INFO, MONO_TRACE_AOT, "AOT: image '%s' not found: %s", aot_name, err);
+                               g_free (err);
+                       }
+                       g_free (aot_name);
+               }
+               if (!sofile) {
+                       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", aot_name, err);
+                               mono_trace (G_LOG_LEVEL_INFO, MONO_TRACE_AOT, "AOT: image '%s' not found: %s", aot_name, err);
                                g_free (err);
+                       }
+               }
+               if (!sofile) {
+                       GList *l;
+
+                       for (l = mono_aot_paths; l; l = l->next) {
+                               char *path = l->data;
 
-                               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);
+                               aot_name = g_strdup_printf ("%s/%s%s", path, basename, MONO_SOLIB_EXT);
                                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", aot_name, err);
+                               if (sofile) {
+                                       found_aot_name = g_strdup (aot_name);
+                               } else {
+                                       mono_trace (G_LOG_LEVEL_INFO, MONO_TRACE_AOT, "AOT: image '%s' not found: %s", aot_name, err);
                                        g_free (err);
                                }
-
+                               g_free (basename);
+                               g_free (aot_name);
+                               if (sofile)
+                                       break;
                        }
                }
                if (!sofile) {
-                       if (mono_aot_only && assembly->image->tables [MONO_TABLE_METHOD].rows)
+                       if (mono_aot_only && assembly->image->tables [MONO_TABLE_METHOD].rows) {
+                               aot_name = g_strdup_printf ("%s%s", assembly->image->name, MONO_SOLIB_EXT);
                                g_error ("Failed to load AOT module '%s' in aot-only mode.\n", aot_name);
-                       g_free (aot_name);
+                               g_free (aot_name);
+                       }
                        return;
                }
        }
@@ -2030,12 +2060,12 @@ load_aot_module (MonoAssembly *assembly, gpointer user_data)
 
        if (!usable) {
                if (mono_aot_only) {
-                       g_error ("Failed to load AOT module '%s' while running in aot-only mode: %s.\n", aot_name, msg);
+                       g_error ("Failed to load AOT module '%s' while running in aot-only mode: %s.\n", found_aot_name, msg);
                } else {
-                       mono_trace (G_LOG_LEVEL_INFO, MONO_TRACE_AOT, "AOT: module %s is unusable: %s.", aot_name, msg);
+                       mono_trace (G_LOG_LEVEL_INFO, MONO_TRACE_AOT, "AOT: module %s is unusable: %s.", found_aot_name, msg);
                }
                g_free (msg);
-               g_free (aot_name);
+               g_free (found_aot_name);
                if (sofile)
                        mono_dl_close (sofile);
                assembly->image->aot_module = NULL;
@@ -2050,7 +2080,7 @@ load_aot_module (MonoAssembly *assembly, gpointer user_data)
        g_assert (info->generic_tramp_num == MONO_TRAMPOLINE_NUM);
 
        amodule = g_new0 (MonoAotModule, 1);
-       amodule->aot_name = aot_name;
+       amodule->aot_name = found_aot_name;
        amodule->assembly = assembly;
 
        memcpy (&amodule->info, info, sizeof (*info));
@@ -2233,7 +2263,7 @@ load_aot_module (MonoAssembly *assembly, gpointer user_data)
        /*
         * Register the plt region as a single trampoline so we can unwind from this code
         */
-       mono_tramp_info_register (
+       mono_aot_tramp_info_register (
                mono_tramp_info_create (
                        NULL,
                        amodule->plt,
@@ -2272,10 +2302,10 @@ load_aot_module (MonoAssembly *assembly, gpointer user_data)
        if (amodule->out_of_date) {
                mono_trace (G_LOG_LEVEL_INFO, MONO_TRACE_AOT, "AOT: Module %s is unusable because a dependency is out-of-date.", assembly->image->name);
                if (mono_aot_only)
-                       g_error ("Failed to load AOT module '%s' while running in aot-only mode because a dependency cannot be found or it is out of date.\n", aot_name);
+                       g_error ("Failed to load AOT module '%s' while running in aot-only mode because a dependency cannot be found or it is out of date.\n", found_aot_name);
+       } else {
+               mono_trace (G_LOG_LEVEL_INFO, MONO_TRACE_AOT, "AOT: image '%s' found.", found_aot_name);
        }
-       else
-               mono_trace (G_LOG_LEVEL_INFO, MONO_TRACE_AOT, "AOT: loaded AOT Module for %s.", assembly->image->name);
 }
 
 /*
@@ -2326,8 +2356,11 @@ mono_aot_init (void)
 #endif
        mono_counters_register ("Async JIT info size", MONO_COUNTER_INT|MONO_COUNTER_JIT, &async_jit_info_size);
 
-       if (g_getenv ("MONO_LASTAOT"))
-               mono_last_aot_method = atoi (g_getenv ("MONO_LASTAOT"));
+       char *lastaot = g_getenv ("MONO_LASTAOT");
+       if (lastaot) {
+               mono_last_aot_method = atoi (lastaot);
+               g_free (lastaot);
+       }
        aot_cache_init ();
 }
 
@@ -2403,7 +2436,7 @@ mono_aot_get_method_from_vt_slot (MonoDomain *domain, MonoVTable *vtable, int sl
        gpointer addr;
        MonoError inner_error;
 
-       mono_error_init (error);
+       error_init (error);
 
        if (MONO_CLASS_IS_INTERFACE (klass) || klass->rank || !amodule)
                return NULL;
@@ -3822,7 +3855,7 @@ load_method (MonoDomain *domain, MonoAotModule *amodule, MonoImage *image, MonoM
        guint8 *code = NULL, *info;
        gboolean res;
 
-       mono_error_init (error);
+       error_init (error);
 
        init_amodule_got (amodule);
 
@@ -3931,15 +3964,18 @@ load_method (MonoDomain *domain, MonoAotModule *amodule, MonoImage *image, MonoM
 
        amodule_lock (amodule);
 
-       InterlockedIncrement (&mono_jit_stats.methods_aot);
-
-       amodule->methods_loaded [method_index / 32] |= 1 << (method_index % 32);
-
        init_plt (amodule);
 
+       InterlockedIncrement (&mono_jit_stats.methods_aot);
+
        if (method && method->wrapper_type)
                g_hash_table_insert (amodule->method_to_code, method, code);
 
+       /* Commit changes since methods_loaded is accessed outside the lock */
+       mono_memory_barrier ();
+
+       amodule->methods_loaded [method_index / 32] |= 1 << (method_index % 32);
+
        amodule_unlock (amodule);
 
        if (mono_profiler_get_events () & MONO_PROFILE_JIT_COMPILATION) {
@@ -4112,7 +4148,7 @@ init_method (MonoAotModule *amodule, guint32 method_index, MonoMethod *method, M
        MonoJitInfo *jinfo = NULL;
        guint8 *code, *info;
 
-       mono_error_init (error);
+       error_init (error);
 
        code = (guint8 *)amodule->methods [method_index];
        info = &amodule->blob [mono_aot_get_offset (amodule->method_info_offsets, method_index)];
@@ -4323,7 +4359,7 @@ mono_aot_get_method_checked (MonoDomain *domain, MonoMethod *method, MonoError *
        gboolean cache_result = FALSE;
        MonoError inner_error;
 
-       mono_error_init (error);
+       error_init (error);
 
        if (domain != mono_get_root_domain ())
                /* Non shared AOT code can't be used in other appdomains */
@@ -4527,7 +4563,7 @@ mono_aot_get_method_checked (MonoDomain *domain, MonoMethod *method, MonoError *
                }
 
                if (method_index == 0xffffff) {
-                       if (mono_aot_only && mono_trace_is_traced (G_LOG_LEVEL_DEBUG, MONO_TRACE_AOT)) {
+                       if (mono_trace_is_traced (G_LOG_LEVEL_DEBUG, MONO_TRACE_AOT)) {
                                char *full_name;
 
                                full_name = mono_method_full_name (method, TRUE);
@@ -4589,7 +4625,7 @@ mono_aot_get_method_from_token (MonoDomain *domain, MonoImage *image, guint32 to
        int method_index;
        gpointer res;
 
-       mono_error_init (error);
+       error_init (error);
 
        if (!aot_module)
                return NULL;
@@ -4708,7 +4744,7 @@ mono_aot_plt_resolve (gpointer aot_module, guint32 plt_info_offset, guint8 *code
        MonoMemPool *mp;
        gboolean using_gsharedvt = FALSE;
 
-       mono_error_init (error);
+       error_init (error);
 
        //printf ("DYN: %p %d\n", aot_module, plt_info_offset);
 
@@ -5111,7 +5147,7 @@ mono_aot_get_trampoline (const char *name)
        gpointer code;
 
        code =  mono_aot_get_trampoline_full (name, &out_tinfo);
-       mono_tramp_info_register (out_tinfo, NULL);
+       mono_aot_tramp_info_register (out_tinfo, NULL);
 
        return code;
 }
@@ -5265,7 +5301,7 @@ get_new_trampoline_from_page (int tramp_type)
                /* Register the generic part at the beggining of the trampoline page */
                gen_info = mono_tramp_info_create (NULL, (guint8*)taddr, amodule->info.tramp_page_code_offsets [tramp_type], NULL, NULL);
                read_page_trampoline_uwinfo (gen_info, tramp_type, TRUE);
-               mono_tramp_info_register (gen_info, NULL);
+               mono_aot_tramp_info_register (gen_info, NULL);
                /*
                 * FIXME
                 * Registering each specific trampoline produces a lot of
@@ -5276,7 +5312,7 @@ get_new_trampoline_from_page (int tramp_type)
                        /* Register the rest of the page as a single trampoline */
                        sp_info = mono_tramp_info_create (NULL, code, page->trampolines_end - code, NULL, NULL);
                        read_page_trampoline_uwinfo (sp_info, tramp_type, FALSE);
-                       mono_tramp_info_register (sp_info, NULL);
+                       mono_aot_tramp_info_register (sp_info, NULL);
                }
                return code;
        }
@@ -5545,7 +5581,7 @@ mono_aot_get_unbox_trampoline (MonoMethod *method)
        }
 
        tinfo->code_size = *(guint32*)symbol_addr;
-       mono_tramp_info_register (tinfo, NULL);
+       mono_aot_tramp_info_register (tinfo, NULL);
 
        /* The caller expects an ftnptr */
        return mono_create_ftnptr (mono_domain_get (), code);
@@ -5807,7 +5843,7 @@ gpointer
 mono_aot_get_method_checked (MonoDomain *domain,
                                                         MonoMethod *method, MonoError *error)
 {
-       mono_error_init (error);
+       error_init (error);
        return NULL;
 }
 
@@ -5838,7 +5874,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);
+       error_init (error);
        return NULL;
 }
 
@@ -5862,7 +5898,7 @@ 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);
+       error_init (error);
 
        return NULL;
 }