X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmini%2Faot-runtime.c;h=f161e27169a7aac854fbe58bbe3068b98c05eaa8;hb=dc2e330a9ff2d5c5271693d5b8d685aa8c0dd3b2;hp=ed2b485a626d415b54fda77ef970106282fca802;hpb=3ab1a56f73cac926676e24b58d07bf0c4e75d3eb;p=mono.git diff --git a/mono/mini/aot-runtime.c b/mono/mini/aot-runtime.c index ed2b485a626..f161e27169a 100644 --- a/mono/mini/aot-runtime.c +++ b/mono/mini/aot-runtime.c @@ -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; @@ -504,6 +505,7 @@ decode_klass_ref (MonoAotModule *module, guint8 *buf, guint8 **endbuf, MonoError return NULL; t = mini_get_shared_gparam (&par_klass->byval_arg, gshared_constraint); + mono_metadata_free_type (gshared_constraint); klass = mono_class_from_mono_type (t); } else { int type = decode_value (p, &p); @@ -621,7 +623,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 +854,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; @@ -1013,6 +1015,8 @@ decode_method_ref_with_target (MonoAotModule *module, MethodRef *ref, MonoMethod ref->method = mono_marshal_get_gsharedvt_in_wrapper (); } else if (subtype == WRAPPER_SUBTYPE_GSHAREDVT_OUT) { ref->method = mono_marshal_get_gsharedvt_out_wrapper (); + } else if (subtype == WRAPPER_SUBTYPE_INTERP_IN) { + ref->method = mini_get_interp_in_wrapper (target->signature); } else if (subtype == WRAPPER_SUBTYPE_GSHAREDVT_IN_SIG) { MonoMethodSignature *sig = decode_signature (module, p, &p); if (!sig) @@ -1214,7 +1218,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 +1344,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; @@ -1941,7 +1947,7 @@ load_aot_module (MonoAssembly *assembly, gpointer user_data) */ return; - if (image_is_dynamic (assembly->image) || assembly->ref_only) + if (image_is_dynamic (assembly->image) || assembly->ref_only || mono_domain_get () != mono_get_root_domain ()) return; mono_aot_lock (); @@ -1963,6 +1969,7 @@ load_aot_module (MonoAssembly *assembly, gpointer user_data) globals = (void **)info->globals; g_assert (globals); } + found_aot_name = g_strdup (aot_name); } else { char *err; @@ -1989,6 +1996,7 @@ load_aot_module (MonoAssembly *assembly, gpointer user_data) 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) { GList *l; @@ -2012,7 +2020,7 @@ load_aot_module (MonoAssembly *assembly, gpointer user_data) } } if (!sofile) { - if (mono_aot_only && assembly->image->tables [MONO_TABLE_METHOD].rows) { + if (mono_aot_only && !mono_use_interpreter && 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); @@ -2056,7 +2064,7 @@ load_aot_module (MonoAssembly *assembly, gpointer user_data) } if (!usable) { - if (mono_aot_only) { + if (mono_aot_only && !mono_use_interpreter) { 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.", found_aot_name, msg); @@ -2260,7 +2268,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, @@ -2278,16 +2286,6 @@ load_aot_module (MonoAssembly *assembly, gpointer user_data) * non-lazily, since we can't handle out-of-date errors later. * The cached class info also depends on the exact assemblies. */ -#if defined(__native_client__) - /* TODO: Don't 'load_image' on mscorlib due to a */ - /* recursive loading problem. This should be */ - /* removed if mscorlib is loaded from disk. */ - if (strncmp(assembly->aname.name, "mscorlib", 8)) { - do_load_image = TRUE; - } else { - do_load_image = FALSE; - } -#endif if (do_load_image) { for (i = 0; i < amodule->image_table_len; ++i) { MonoError error; @@ -2348,13 +2346,14 @@ mono_aot_init (void) mono_os_mutex_init_recursive (&aot_page_mutex); aot_modules = g_hash_table_new (NULL, NULL); -#ifndef __native_client__ mono_install_assembly_load_hook (load_aot_module, NULL); -#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 (); } @@ -2430,7 +2429,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; @@ -2658,15 +2657,15 @@ is_thumb_code (MonoAotModule *amodule, guint8 *code) * * Decode the EH information emitted by our modified LLVM compiler and construct a * MonoJitInfo structure from it. - * LOCKING: Acquires the domain lock. + * If JINFO is NULL, set OUT_LLVM_CLAUSES to the number of llvm level clauses. + * This function is async safe when called in async context. */ -static MonoJitInfo* -decode_llvm_mono_eh_frame (MonoAotModule *amodule, MonoDomain *domain, - MonoMethod *method, guint8 *code, guint32 code_len, +static void +decode_llvm_mono_eh_frame (MonoAotModule *amodule, MonoDomain *domain, MonoJitInfo *jinfo, + guint8 *code, guint32 code_len, MonoJitExceptionInfo *clauses, int num_clauses, - MonoJitInfoFlags flags, GSList **nesting, - int *this_reg, int *this_offset) + int *this_reg, int *this_offset, int *out_llvm_clauses) { guint8 *p, *code1, *code2; guint8 *fde, *cie, *code_start, *code_end; @@ -2676,14 +2675,19 @@ decode_llvm_mono_eh_frame (MonoAotModule *amodule, MonoDomain *domain, MonoJitExceptionInfo *ei; guint32 fde_len, ei_len, nested_len, nindex; gpointer *type_info; - MonoJitInfo *jinfo; MonoLLVMFDEInfo info; + guint8 *unw_info; + gboolean async; + + async = mono_thread_info_is_async_context (); if (!amodule->mono_eh_frame) { - jinfo = (MonoJitInfo *)mono_domain_alloc0_lock_free (domain, mono_jit_info_size (flags, num_clauses, 0)); - mono_jit_info_init (jinfo, method, code, code_len, flags, num_clauses, 0); + if (!jinfo) { + *out_llvm_clauses = num_clauses; + return; + } memcpy (jinfo->clauses, clauses, num_clauses * sizeof (MonoJitExceptionInfo)); - return jinfo; + return; } g_assert (amodule->mono_eh_frame && code); @@ -2752,13 +2756,29 @@ decode_llvm_mono_eh_frame (MonoAotModule *amodule, MonoDomain *domain, /* This won't overflow because there is +1 entry in the table */ fde_len = table [(pos * 2) + 2 + 1] - table [(pos * 2) + 1]; - mono_unwind_decode_llvm_mono_fde (fde, fde_len, cie, code_start, &info); - ei = info.ex_info; + /* Compute lengths */ + mono_unwind_decode_llvm_mono_fde (fde, fde_len, cie, code_start, &info, NULL, NULL, NULL); + + if (async) { + /* These are leaked, but the leak is bounded */ + ei = mono_domain_alloc0_lock_free (domain, info.ex_info_len * sizeof (MonoJitExceptionInfo)); + type_info = mono_domain_alloc0_lock_free (domain, info.ex_info_len * sizeof (gpointer)); + unw_info = mono_domain_alloc0_lock_free (domain, info.unw_info_len); + } else { + ei = (MonoJitExceptionInfo *)g_malloc0 (info.ex_info_len * sizeof (MonoJitExceptionInfo)); + type_info = (gpointer *)g_malloc0 (info.ex_info_len * sizeof (gpointer)); + unw_info = (guint8*)g_malloc0 (info.unw_info_len); + } + mono_unwind_decode_llvm_mono_fde (fde, fde_len, cie, code_start, &info, ei, type_info, unw_info); + ei_len = info.ex_info_len; - type_info = info.type_info; *this_reg = info.this_reg; *this_offset = info.this_offset; + /* + * LLVM might represent one IL region with multiple regions. + */ + /* Count number of nested clauses */ nested_len = 0; for (i = 0; i < ei_len; ++i) { @@ -2770,18 +2790,16 @@ decode_llvm_mono_eh_frame (MonoAotModule *amodule, MonoDomain *domain, nested_len ++; } - /* - * LLVM might represent one IL region with multiple regions, so have to - * allocate a new JI. - */ - jinfo = - (MonoJitInfo *)mono_domain_alloc0_lock_free (domain, mono_jit_info_size (flags, ei_len + nested_len, 0)); - mono_jit_info_init (jinfo, method, code, code_len, flags, ei_len + nested_len, 0); + if (!jinfo) { + *out_llvm_clauses = ei_len + nested_len; + return; + } - jinfo->unwind_info = mono_cache_unwind_info (info.unw_info, info.unw_info_len); - /* This signals that unwind_info points to a normal cached unwind info */ - jinfo->from_aot = 0; - jinfo->from_llvm = 1; + /* Store the unwind info addr/length in the MonoJitInfo structure itself so its async safe */ + MonoUnwindJitInfo *jinfo_unwind = mono_jit_info_get_unwind_info (jinfo); + g_assert (jinfo_unwind); + jinfo_unwind->unw_info = unw_info; + jinfo_unwind->unw_info_len = info.unw_info_len; for (i = 0; i < ei_len; ++i) { /* @@ -2831,8 +2849,6 @@ decode_llvm_mono_eh_frame (MonoAotModule *amodule, MonoDomain *domain, } } g_assert (nindex == ei_len + nested_len); - - return jinfo; } static gpointer @@ -2917,24 +2933,41 @@ decode_exception_debug_info (MonoAotModule *amodule, MonoDomain *domain, MonoJitExceptionInfo *clauses; GSList **nesting; - // FIXME: async - g_assert (!async); - /* * Part of the info is encoded by the AOT compiler, the rest is in the .eh_frame * section. */ - clauses = g_new0 (MonoJitExceptionInfo, num_clauses); - nesting = g_new0 (GSList*, num_clauses); + if (async) { + if (num_clauses < 16) { + clauses = g_newa (MonoJitExceptionInfo, num_clauses); + nesting = g_newa (GSList*, num_clauses); + } else { + clauses = alloc0_jit_info_data (domain, sizeof (MonoJitExceptionInfo) * num_clauses, TRUE); + nesting = alloc0_jit_info_data (domain, sizeof (GSList*) * num_clauses, TRUE); + } + memset (clauses, 0, sizeof (MonoJitExceptionInfo) * num_clauses); + memset (nesting, 0, sizeof (GSList*) * num_clauses); + } else { + clauses = g_new0 (MonoJitExceptionInfo, num_clauses); + nesting = g_new0 (GSList*, num_clauses); + } for (i = 0; i < num_clauses; ++i) { MonoJitExceptionInfo *ei = &clauses [i]; ei->flags = decode_value (p, &p); - if (decode_value (p, &p)) { - ei->data.catch_class = decode_klass_ref (amodule, p, &p, &error); - mono_error_cleanup (&error); /* FIXME don't swallow the error */ + if (!(ei->flags == MONO_EXCEPTION_CLAUSE_FILTER || ei->flags == MONO_EXCEPTION_CLAUSE_FINALLY)) { + int len = decode_value (p, &p); + + if (len > 0) { + if (async) { + p += len; + } else { + ei->data.catch_class = decode_klass_ref (amodule, p, &p, &error); + mono_error_cleanup (&error); /* FIXME don't swallow the error */ + } + } } ei->clause_index = i; @@ -2949,16 +2982,29 @@ decode_exception_debug_info (MonoAotModule *amodule, MonoDomain *domain, int nesting_index = decode_value (p, &p); if (nesting_index == -1) break; + // FIXME: async + g_assert (!async); nesting [i] = g_slist_prepend (nesting [i], GINT_TO_POINTER (nesting_index)); } } - jinfo = decode_llvm_mono_eh_frame (amodule, domain, method, code, code_len, clauses, num_clauses, flags, nesting, &this_reg, &this_offset); + flags |= JIT_INFO_HAS_UNWIND_INFO; - g_free (clauses); - for (i = 0; i < num_clauses; ++i) - g_slist_free (nesting [i]); - g_free (nesting); + int num_llvm_clauses; + /* Get the length first */ + decode_llvm_mono_eh_frame (amodule, domain, NULL, code, code_len, clauses, num_clauses, nesting, &this_reg, &this_offset, &num_llvm_clauses); + len = mono_jit_info_size (flags, num_llvm_clauses, num_holes); + jinfo = (MonoJitInfo *)alloc0_jit_info_data (domain, len, async); + mono_jit_info_init (jinfo, method, code, code_len, flags, num_llvm_clauses, num_holes); + + decode_llvm_mono_eh_frame (amodule, domain, jinfo, code, code_len, clauses, num_clauses, nesting, &this_reg, &this_offset, NULL); + + if (!async) { + g_free (clauses); + for (i = 0; i < num_clauses; ++i) + g_slist_free (nesting [i]); + g_free (nesting); + } } else { len = mono_jit_info_size (flags, num_clauses, num_holes); jinfo = (MonoJitInfo *)alloc0_jit_info_data (domain, len, async); @@ -3496,7 +3542,8 @@ decode_patch (MonoAotModule *aot_module, MonoMemPool *mp, MonoJumpInfo *ji, guin break; } case MONO_PATCH_INFO_INTERNAL_METHOD: - case MONO_PATCH_INFO_JIT_ICALL_ADDR: { + case MONO_PATCH_INFO_JIT_ICALL_ADDR: + case MONO_PATCH_INFO_JIT_ICALL_ADDR_NOCALL: { guint32 len = decode_value (p, &p); ji->data.name = (char*)p; @@ -3849,7 +3896,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); @@ -3886,9 +3933,11 @@ load_method (MonoDomain *domain, MonoAotModule *amodule, MonoImage *image, MonoM if (!method) return NULL; } - full_name = mono_method_full_name (method, TRUE); - mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_AOT, "AOT: NOT FOUND: %s.", full_name); - g_free (full_name); + if (!(method->iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL)) { + full_name = mono_method_full_name (method, TRUE); + mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_AOT, "AOT: NOT FOUND: %s.", full_name); + g_free (full_name); + } } return NULL; } @@ -4142,7 +4191,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)]; @@ -4353,7 +4402,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 */ @@ -4619,7 +4668,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; @@ -4738,7 +4787,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); @@ -5141,7 +5190,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; } @@ -5295,7 +5344,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 @@ -5306,7 +5355,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; } @@ -5575,7 +5624,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); @@ -5837,7 +5886,7 @@ gpointer mono_aot_get_method_checked (MonoDomain *domain, MonoMethod *method, MonoError *error) { - mono_error_init (error); + error_init (error); return NULL; } @@ -5868,7 +5917,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; } @@ -5892,7 +5941,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; }