X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmini%2Faot-compiler.c;h=5bfa4d0920387d4bcbaf388a254e24f328622407;hb=caa9ed689f20ab27f43ed988848fca7f7834b6b0;hp=d6dfd3b69d2eb0411c9a2d1a77be821123d8931c;hpb=f704d56c378b28e252572db4730a6e13edc14aa0;p=mono.git diff --git a/mono/mini/aot-compiler.c b/mono/mini/aot-compiler.c index d6dfd3b69d2..5bfa4d09203 100644 --- a/mono/mini/aot-compiler.c +++ b/mono/mini/aot-compiler.c @@ -56,7 +56,7 @@ #include #include #include -#include +#include #include #include "aot-compiler.h" @@ -78,7 +78,7 @@ #define TARGET_WIN32_MSVC #endif -#if defined(__linux__) || defined(__native_client_codegen__) +#if defined(__linux__) #define RODATA_SECT ".rodata" #elif defined(TARGET_MACH) #define RODATA_SECT ".section __TEXT, __const" @@ -298,6 +298,7 @@ typedef struct MonoAotCompile { guint32 label_generator; gboolean llvm; gboolean has_jitted_code; + gboolean is_full_aot; MonoAotFileFlags flags; MonoDynamicStream blob; gboolean blob_closed; @@ -420,7 +421,7 @@ aot_printerrf (MonoAotCompile *acfg, const gchar *format, ...) } static void -report_loader_error (MonoAotCompile *acfg, MonoError *error, const char *format, ...) +report_loader_error (MonoAotCompile *acfg, MonoError *error, gboolean fatal, const char *format, ...) { FILE *output; va_list args; @@ -438,7 +439,10 @@ report_loader_error (MonoAotCompile *acfg, MonoError *error, const char *format, va_end (args); mono_error_cleanup (error); - g_error ("FullAOT cannot continue if there are loader errors"); + if (acfg->is_full_aot && fatal) { + fprintf (output, "FullAOT cannot continue if there are loader errors.\n"); + exit (1); + } } /* Wrappers around the image writer functions */ @@ -949,10 +953,8 @@ emit_code_bytes (MonoAotCompile *acfg, const guint8* buf, int size) #ifdef TARGET_X86 #ifdef TARGET_WIN32 #define AOT_TARGET_STR "X86 (WIN32)" -#elif defined(__native_client_codegen__) -#define AOT_TARGET_STR "X86 (native client codegen)" #else -#define AOT_TARGET_STR "X86 (!native client codegen)" +#define AOT_TARGET_STR "X86" #endif #endif @@ -2895,7 +2897,7 @@ encode_klass_ref_inner (MonoAotCompile *acfg, MonoClass *klass, guint8 *buf, gui if (par->gshared_constraint) { MonoGSharedGenericParam *gpar = (MonoGSharedGenericParam*)par; encode_type (acfg, par->gshared_constraint, p, &p); - encode_klass_ref (acfg, mono_class_from_generic_parameter (gpar->parent, NULL, klass->byval_arg.type == MONO_TYPE_MVAR), p, &p); + encode_klass_ref (acfg, mono_class_from_generic_parameter_internal (gpar->parent), p, &p); } else { encode_value (klass->byval_arg.type, p, &p); encode_value (mono_type_get_generic_param_num (&klass->byval_arg), p, &p); @@ -3830,7 +3832,7 @@ add_wrappers (MonoAotCompile *acfg) gboolean skip = FALSE; method = mono_get_method_checked (acfg->image, token, NULL, NULL, &error); - report_loader_error (acfg, &error, "Failed to load method token 0x%x due to %s\n", i, mono_error_get_message (&error)); + report_loader_error (acfg, &error, TRUE, "Failed to load method token 0x%x due to %s\n", i, mono_error_get_message (&error)); if ((method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL) || (method->iflags & METHOD_IMPL_ATTRIBUTE_RUNTIME) || @@ -3976,6 +3978,8 @@ add_wrappers (MonoAotCompile *acfg) add_method (acfg, m); if ((m = mono_gc_get_managed_allocator_by_type (i, MANAGED_ALLOCATOR_SLOW_PATH))) add_method (acfg, m); + if ((m = mono_gc_get_managed_allocator_by_type (i, MANAGED_ALLOCATOR_PROFILER))) + add_method (acfg, m); } /* write barriers */ @@ -4179,7 +4183,7 @@ add_wrappers (MonoAotCompile *acfg) MonoError error; token = MONO_TOKEN_METHOD_DEF | (i + 1); method = mono_get_method_checked (acfg->image, token, NULL, NULL, &error); - report_loader_error (acfg, &error, "Failed to load method token 0x%x due to %s\n", i, mono_error_get_message (&error)); + report_loader_error (acfg, &error, TRUE, "Failed to load method token 0x%x due to %s\n", i, mono_error_get_message (&error)); if (method->iflags & METHOD_IMPL_ATTRIBUTE_SYNCHRONIZED) { if (method->is_generic) { @@ -4212,7 +4216,7 @@ add_wrappers (MonoAotCompile *acfg) guint32 token = MONO_TOKEN_METHOD_DEF | (i + 1); method = mono_get_method_checked (acfg->image, token, NULL, NULL, &error); - report_loader_error (acfg, &error, "Failed to load method token 0x%x due to %s\n", i, mono_error_get_message (&error)); + report_loader_error (acfg, &error, TRUE, "Failed to load method token 0x%x due to %s\n", i, mono_error_get_message (&error)); if ((method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL) || (method->iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL)) { @@ -4236,7 +4240,7 @@ add_wrappers (MonoAotCompile *acfg) int j; method = mono_get_method_checked (acfg->image, token, NULL, NULL, &error); - report_loader_error (acfg, &error, "Failed to load method token 0x%x due to %s\n", i, mono_error_get_message (&error)); + report_loader_error (acfg, &error, TRUE, "Failed to load method token 0x%x due to %s\n", i, mono_error_get_message (&error)); /* * Only generate native-to-managed wrappers for methods which have an @@ -4246,7 +4250,7 @@ add_wrappers (MonoAotCompile *acfg) cattr = mono_custom_attrs_from_method_checked (method, &error); if (!is_ok (&error)) { char *name = mono_method_get_full_name (method); - report_loader_error (acfg, &error, "Failed to load custom attributes from method %s due to %s\n", name, mono_error_get_message (&error)); + report_loader_error (acfg, &error, TRUE, "Failed to load custom attributes from method %s due to %s\n", name, mono_error_get_message (&error)); g_free (name); } @@ -4425,7 +4429,13 @@ method_has_type_vars (MonoMethod *method) static gboolean mono_aot_mode_is_full (MonoAotOptions *opts) { - return opts->mode == MONO_AOT_MODE_FULL; + return opts->mode == MONO_AOT_MODE_FULL || opts->mode == MONO_AOT_MODE_INTERP; +} + +static +gboolean mono_aot_mode_is_interp (MonoAotOptions *opts) +{ + return opts->mode == MONO_AOT_MODE_INTERP; } static @@ -5743,7 +5753,8 @@ encode_patch (MonoAotCompile *acfg, MonoJumpInfo *patch_info, guint8 *buf, guint encode_value (patch_info->data.index, p, &p); 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 = strlen (patch_info->data.name); encode_value (len, p, &p); @@ -5809,6 +5820,8 @@ encode_patch (MonoAotCompile *acfg, MonoJumpInfo *patch_info, guint8 *buf, guint break; case MONO_PATCH_INFO_INTERRUPTION_REQUEST_FLAG: break; + case MONO_PATCH_INFO_PROFILER_ALLOCATION_COUNT: + break; case MONO_PATCH_INFO_RGCTX_FETCH: case MONO_PATCH_INFO_RGCTX_SLOT_INDEX: { MonoJumpInfoRgctxEntry *entry = patch_info->data.rgctx_entry; @@ -6130,11 +6143,23 @@ emit_exception_debug_info (MonoAotCompile *acfg, MonoCompile *cfg, gboolean stor clause = &header->clauses [k]; encode_value (clause->flags, p, &p); - if (clause->data.catch_class) { - encode_value (1, p, &p); - encode_klass_ref (acfg, clause->data.catch_class, p, &p); - } else { - encode_value (0, p, &p); + if (!(clause->flags == MONO_EXCEPTION_CLAUSE_FILTER || clause->flags == MONO_EXCEPTION_CLAUSE_FINALLY)) { + if (clause->data.catch_class) { + guint8 *buf2, *p2; + int len; + + buf2 = (guint8 *)g_malloc (4096); + p2 = buf2; + encode_klass_ref (acfg, clause->data.catch_class, p2, &p2); + len = p2 - buf2; + g_assert (len < 4096); + encode_value (len, p, &p); + memcpy (p, buf2, len); + p += p2 - buf2; + g_free (buf2); + } else { + encode_value (0, p, &p); + } } /* Emit the IL ranges too, since they might not be available at runtime */ @@ -6716,10 +6741,6 @@ emit_trampolines (MonoAotCompile *acfg) #ifdef DISABLE_REMOTING if (tramp_type == MONO_TRAMPOLINE_GENERIC_VIRTUAL_REMOTING) continue; -#endif -#ifndef MONO_ARCH_HAVE_HANDLER_BLOCK_GUARD - if (tramp_type == MONO_TRAMPOLINE_HANDLER_BLOCK_GUARD) - continue; #endif mono_arch_create_generic_trampoline ((MonoTrampolineType)tramp_type, &info, acfg->aot_opts.use_trampolines_page? 2: TRUE); emit_trampoline (acfg, acfg->got_offset, info); @@ -6800,10 +6821,10 @@ emit_trampolines (MonoAotCompile *acfg) } } -#ifdef MONO_ARCH_HAVE_HANDLER_BLOCK_GUARD_AOT - mono_arch_create_handler_block_trampoline (&info, TRUE); - emit_trampoline (acfg, acfg->got_offset, info); -#endif + if (mono_aot_mode_is_interp (&acfg->aot_opts)) { + mono_arch_get_enter_icall_trampoline (&info); + emit_trampoline (acfg, acfg->got_offset, info); + } #endif /* #ifdef MONO_ARCH_HAVE_FULL_AOT_TRAMPOLINES */ @@ -7147,6 +7168,8 @@ mono_aot_parse_options (const char *aot_options, MonoAotOptions *opts) opts->mode = MONO_AOT_MODE_FULL; } else if (str_begins_with (arg, "hybrid")) { opts->mode = MONO_AOT_MODE_HYBRID; + } else if (str_begins_with (arg, "interp")) { + opts->mode = MONO_AOT_MODE_INTERP; } else if (str_begins_with (arg, "threads=")) { opts->nthreads = atoi (arg + strlen ("threads=")); } else if (str_begins_with (arg, "static")) { @@ -7613,11 +7636,9 @@ compile_method (MonoAotCompile *acfg, MonoMethod *method) return; } if (cfg->exception_type != MONO_EXCEPTION_NONE) { - if (acfg->aot_opts.print_skipped_methods) { - printf ("Skip (JIT failure): %s\n", mono_method_get_full_name (method)); - if (cfg->exception_message) - printf ("Caused by: %s\n", cfg->exception_message); - } + /* Some instances cannot be JITted due to constraints etc. */ + if (!method->is_inflated) + report_loader_error (acfg, &cfg->error, FALSE, "Unable to compile method '%s' due to: '%s'.\n", mono_method_get_full_name (method), mono_error_get_message (&cfg->error)); /* Let the exception happen at runtime */ return; } @@ -7896,6 +7917,7 @@ compile_method (MonoAotCompile *acfg, MonoMethod *method) g_hash_table_insert (acfg->method_to_cfg, cfg->orig_method, cfg); + /* Update global stats while holding a lock. */ mono_update_jit_stats (cfg); /* @@ -7917,7 +7939,9 @@ compile_thread_main (gpointer user_data) MonoError error; MonoInternalThread *internal = mono_thread_internal_current (); - mono_thread_set_name_internal (internal, mono_string_new (mono_domain_get (), "AOT compiler"), TRUE, FALSE, &error); + MonoString *str = mono_string_new_checked (mono_domain_get (), "AOT compiler", &error); + mono_error_assert_ok (&error); + mono_thread_set_name_internal (internal, str, TRUE, FALSE, &error); mono_error_assert_ok (&error); for (i = 0; i < methods->len; ++i) @@ -8623,7 +8647,7 @@ execute_system (const char * command) { int status = 0; -#if defined(HOST_WIN32) && defined(HAVE_SYSTEM) +#if defined(HOST_WIN32) // We need an extra set of quotes around the whole command to properly handle commands // with spaces since internally the command is called through "cmd /c. char * quoted_command = g_strdup_printf ("\"%s\"", command); @@ -8740,7 +8764,7 @@ emit_llvm_file (MonoAotCompile *acfg) g_string_append_printf (acfg->llc_args, " -disable-tail-calls"); #endif -#if defined(TARGET_MACH) && defined(TARGET_ARM) +#if ( defined(TARGET_MACH) && defined(TARGET_ARM) ) || defined(TARGET_ORBIS) /* ios requires PIC code now */ g_string_append_printf (acfg->llc_args, " -relocation-model=pic"); #else @@ -10244,7 +10268,7 @@ collect_methods (MonoAotCompile *acfg) continue; method = mono_get_method_checked (acfg->image, token, NULL, NULL, &error); - report_loader_error (acfg, &error, "Failed to load method token 0x%x due to %s\n", i, mono_error_get_message (&error)); + report_loader_error (acfg, &error, TRUE, "Failed to load method token 0x%x due to %s\n", i, mono_error_get_message (&error)); if (method->is_generic || mono_class_is_gtd (method->klass)) { MonoMethod *gshared; @@ -10345,19 +10369,13 @@ compile_asm (MonoAotCompile *acfg) #define AS_OPTIONS "-a64 -mppc64" #elif defined(sparc) && SIZEOF_VOID_P == 8 #define AS_OPTIONS "-xarch=v9" -#elif defined(TARGET_X86) && defined(TARGET_MACH) && !defined(__native_client_codegen__) +#elif defined(TARGET_X86) && defined(TARGET_MACH) #define AS_OPTIONS "-arch i386" #else #define AS_OPTIONS "" #endif -#ifdef __native_client_codegen__ -#if defined(TARGET_AMD64) -#define AS_NAME "nacl64-as" -#else -#define AS_NAME "nacl-as" -#endif -#elif defined(TARGET_OSX) +#if defined(TARGET_OSX) #define AS_NAME "clang" #elif defined(TARGET_WIN32_MSVC) #define AS_NAME "clang.exe" @@ -10386,7 +10404,7 @@ compile_asm (MonoAotCompile *acfg) #elif defined(TARGET_WIN32) && !defined(TARGET_ANDROID) #define LD_NAME "gcc" #define LD_OPTIONS "-shared" -#elif defined(TARGET_X86) && defined(TARGET_MACH) && !defined(__native_client_codegen__) +#elif defined(TARGET_X86) && defined(TARGET_MACH) #define LD_NAME "clang" #define LD_OPTIONS "-m32 -dynamiclib" #elif defined(TARGET_ARM) && !defined(TARGET_ANDROID) @@ -11352,6 +11370,13 @@ add_preinit_got_slots (MonoAotCompile *acfg) get_got_offset (acfg, FALSE, ji); get_got_offset (acfg, TRUE, ji); + /* Called by native-to-managed wrappers on possibly unattached threads */ + ji = (MonoJumpInfo *)mono_mempool_alloc0 (acfg->mempool, sizeof (MonoJumpInfo)); + ji->type = MONO_PATCH_INFO_JIT_ICALL_ADDR_NOCALL; + ji->data.name = "mono_threads_attach_coop"; + get_got_offset (acfg, FALSE, ji); + get_got_offset (acfg, TRUE, ji); + for (i = 0; i < sizeof (preinited_jit_icalls) / sizeof (char*); ++i) { ji = (MonoJumpInfo *)mono_mempool_alloc0 (acfg->mempool, sizeof (MonoAotCompile)); ji->type = MONO_PATCH_INFO_INTERNAL_METHOD; @@ -11485,8 +11510,10 @@ mono_compile_assembly (MonoAssembly *ass, guint32 opts, const char *aot_options) } } - if (mono_aot_mode_is_full (&acfg->aot_opts)) + if (mono_aot_mode_is_full (&acfg->aot_opts)) { acfg->flags = (MonoAotFileFlags)(acfg->flags | MONO_AOT_FILE_FLAG_FULL_AOT); + acfg->is_full_aot = TRUE; + } if (mono_threads_is_coop_enabled ()) acfg->flags = (MonoAotFileFlags)(acfg->flags | MONO_AOT_FILE_FLAG_SAFEPOINTS); @@ -11507,7 +11534,7 @@ mono_compile_assembly (MonoAssembly *ass, guint32 opts, const char *aot_options) } } - { + if (!mono_aot_mode_is_interp (&acfg->aot_opts)) { int method_index; for (method_index = 0; method_index < acfg->image->tables [MONO_TABLE_METHOD].rows; ++method_index) { @@ -11570,9 +11597,12 @@ mono_compile_assembly (MonoAssembly *ass, guint32 opts, const char *aot_options) if (mono_aot_mode_is_full (&acfg->aot_opts) || mono_aot_mode_is_hybrid (&acfg->aot_opts)) mono_set_partial_sharing_supported (TRUE); - res = collect_methods (acfg); - if (!res) - return 1; + if (!mono_aot_mode_is_interp (&acfg->aot_opts)) { + res = collect_methods (acfg); + + if (!res) + return 1; + } { GList *l; @@ -11593,10 +11623,30 @@ mono_compile_assembly (MonoAssembly *ass, guint32 opts, const char *aot_options) #ifdef ENABLE_LLVM if (acfg->llvm) { llvm_acfg = acfg; - mono_llvm_create_aot_module (acfg->image->assembly, acfg->global_prefix, TRUE, acfg->aot_opts.static_link, acfg->aot_opts.llvm_only); + mono_llvm_create_aot_module (acfg->image->assembly, acfg->global_prefix, acfg->nshared_got_entries, TRUE, acfg->aot_opts.static_link, acfg->aot_opts.llvm_only); } #endif + if (mono_aot_mode_is_interp (&acfg->aot_opts)) { + MonoMethod *wrapper; + MonoMethodSignature *sig; + + /* object object:interp_in_static (object,intptr,intptr,intptr) */ + sig = mono_create_icall_signature ("object object ptr ptr ptr"); + wrapper = mini_get_interp_in_wrapper (sig); + add_method (acfg, wrapper); + + /* int object:interp_in_static (intptr,int,intptr) */ + sig = mono_create_icall_signature ("int32 ptr int32 ptr"); + wrapper = mini_get_interp_in_wrapper (sig); + add_method (acfg, wrapper); + + /* void object:interp_in_static (object,intptr,intptr,intptr) */ + sig = mono_create_icall_signature ("void object ptr ptr ptr"); + wrapper = mini_get_interp_in_wrapper (sig); + add_method (acfg, wrapper); + } + TV_GETTIME (atv); compile_methods (acfg); @@ -11642,8 +11692,14 @@ mono_compile_assembly (MonoAssembly *ass, guint32 opts, const char *aot_options) acfg->tmpfname = g_strdup_printf ("%s.s", acfg->image->name); acfg->fp = fopen (acfg->tmpfname, "w+"); } else { - int i = g_file_open_tmp ("mono_aot_XXXXXX", &acfg->tmpfname, NULL); - acfg->fp = fdopen (i, "w+"); + if (strcmp (acfg->aot_opts.temp_path, "") == 0) { + int i = g_file_open_tmp ("mono_aot_XXXXXX", &acfg->tmpfname, NULL); + acfg->fp = fdopen (i, "w+"); + } else { + acfg->tmpbasename = g_build_filename (acfg->aot_opts.temp_path, "temp", NULL); + acfg->tmpfname = g_strdup_printf ("%s.s", acfg->tmpbasename); + acfg->fp = fopen (acfg->tmpfname, "w+"); + } } if (acfg->fp == 0 && !acfg->aot_opts.llvm_only) { aot_printerrf (acfg, "Unable to open file '%s': %s\n", acfg->tmpfname, strerror (errno));