X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmini%2Fmini-runtime.c;h=8b454087638bef15f630ffa4446e8e57391fc72f;hb=8ae7b6d6b950e5ee5fcd4a6625e0f467340dddee;hp=264a99cdc6934ca8c05d5d60694acc8829dddc0f;hpb=f2531ff08c19e14aad0202b8311218e7c1f27091;p=mono.git diff --git a/mono/mini/mini-runtime.c b/mono/mini/mini-runtime.c index 264a99cdc69..8b454087638 100644 --- a/mono/mini/mini-runtime.c +++ b/mono/mini/mini-runtime.c @@ -59,6 +59,7 @@ #include #include #include +#include #include #include "mini.h" @@ -118,12 +119,14 @@ static void register_icalls (void); gboolean mono_running_on_valgrind (void) { +#ifndef HOST_WIN32 if (RUNNING_ON_VALGRIND){ #ifdef VALGRIND_JIT_REGISTER_MAP valgrind_register = TRUE; #endif return TRUE; } else +#endif return FALSE; } @@ -155,7 +158,7 @@ get_method_from_ip (void *ip) if (!domain) domain = mono_get_root_domain (); - ji = mono_jit_info_table_find (domain, ip); + ji = mono_jit_info_table_find_internal (domain, ip, TRUE, TRUE); if (!ji) { user_data.ip = ip; user_data.method = NULL; @@ -170,7 +173,11 @@ get_method_from_ip (void *ip) } else return NULL; + } else if (ji->is_trampoline) { + res = g_strdup_printf ("<%p - %s trampoline>", ip, ((MonoTrampInfo*)ji->d.tramp_info)->name); + return res; } + method = mono_method_full_name (jinfo_get_method (ji), TRUE); /* FIXME: unused ? */ location = mono_debug_lookup_source_location (jinfo_get_method (ji), (guint32)((guint8*)ip - (guint8*)ji->code_start), domain); @@ -286,7 +293,7 @@ gboolean mono_method_same_domain (MonoJitInfo *caller, MonoJitInfo *callee) { MonoMethod *cmethod; - if (!caller || !callee) + if (!caller || caller->is_trampoline || !callee || callee->is_trampoline) return FALSE; /* @@ -460,14 +467,10 @@ mono_tramp_info_create (const char *name, guint8 *code, guint32 code_size, MonoJ void mono_tramp_info_free (MonoTrampInfo *info) { - GSList *l; - g_free (info->name); // FIXME: ji - for (l = info->unwind_ops; l; l = l->next) - g_free (l->data); - g_slist_free (info->unwind_ops); + mono_free_unwind_info (info->unwind_ops); g_free (info); } @@ -480,7 +483,8 @@ register_trampoline_jit_info (MonoDomain *domain, MonoTrampInfo *info) mono_jit_info_init (ji, NULL, info->code, info->code_size, 0, 0, 0); ji->d.tramp_info = info; ji->is_trampoline = TRUE; - // FIXME: Unwind info + + ji->unwind_info = mono_cache_unwind_info (info->uw_info, info->uw_info_len); mono_jit_info_table_add (domain, ji); } @@ -493,26 +497,38 @@ register_trampoline_jit_info (MonoDomain *domain, MonoTrampInfo *info) * Frees INFO. */ void -mono_tramp_info_register (MonoTrampInfo *info) +mono_tramp_info_register (MonoTrampInfo *info, MonoDomain *domain) { MonoTrampInfo *copy; if (!info) return; + if (!domain) + domain = mono_get_root_domain (); + copy = g_new0 (MonoTrampInfo, 1); copy->code = info->code; copy->code_size = info->code_size; copy->name = g_strdup (info->name); + if (info->unwind_ops) { + copy->uw_info = mono_unwind_ops_encode (info->unwind_ops, ©->uw_info_len); + } else { + /* Trampolines from aot have the unwind ops already encoded */ + copy->uw_info = info->uw_info; + copy->uw_info_len = info->uw_info_len; + } + mono_jit_lock (); tramp_infos = g_slist_prepend (tramp_infos, copy); mono_jit_unlock (); mono_save_trampoline_xdebug_info (info); - if (mono_get_root_domain ()) - register_trampoline_jit_info (mono_get_root_domain (), copy); + /* Only register trampolines that have unwind infos */ + if (mono_get_root_domain () && copy->uw_info) + register_trampoline_jit_info (domain, copy); if (mono_jit_map_is_enabled ()) mono_emit_jit_tramp (info->code, info->code_size, info->name); @@ -588,28 +604,14 @@ mono_icall_get_wrapper_full (MonoJitICallInfo* callinfo, gboolean do_compile) MonoMethod *wrapper; gconstpointer trampoline; MonoDomain *domain = mono_get_root_domain (); - gboolean check_exc = check_for_pending_exc; + gboolean check_exc = TRUE; - if (callinfo->wrapper) { + if (callinfo->wrapper) return callinfo->wrapper; - } if (callinfo->trampoline) return callinfo->trampoline; - /* - * We use the lock on the root domain instead of the JIT lock to protect - * callinfo->trampoline, since we do a lot of stuff inside the critical section. - */ - mono_loader_lock (); /*FIXME mono_compile_method requires the loader lock, by large.*/ - mono_domain_lock (domain); - - if (callinfo->trampoline) { - mono_domain_unlock (domain); - mono_loader_unlock (); - return callinfo->trampoline; - } - if (!strcmp (callinfo->name, "mono_thread_interruption_checkpoint")) /* This icall is used to check for exceptions, so don't check in the wrapper */ check_exc = FALSE; @@ -622,11 +624,12 @@ mono_icall_get_wrapper_full (MonoJitICallInfo* callinfo, gboolean do_compile) trampoline = mono_compile_method (wrapper); else trampoline = mono_create_ftnptr (domain, mono_create_jit_trampoline_in_domain (domain, wrapper)); - mono_register_jit_icall_wrapper (callinfo, trampoline); - - callinfo->trampoline = trampoline; - mono_domain_unlock (domain); + mono_loader_lock (); + if (!callinfo->trampoline) { + mono_register_jit_icall_wrapper (callinfo, trampoline); + callinfo->trampoline = trampoline; + } mono_loader_unlock (); return callinfo->trampoline; @@ -653,7 +656,9 @@ mono_dynamic_code_hash_lookup (MonoDomain *domain, MonoMethod *method) static void register_opcode_emulation (int opcode, const char *name, const char *sigstr, gpointer func, const char *symbol, gboolean no_throw) { - return mini_register_opcode_emulation (opcode, name, sigstr, func, symbol, no_throw); +#ifndef DISABLE_JIT + mini_register_opcode_emulation (opcode, name, sigstr, func, symbol, no_throw); +#endif } /* @@ -1030,6 +1035,7 @@ int mini_get_tls_offset (MonoTlsKey key) { int offset; + g_assert (MONO_ARCH_HAVE_TLS_GET); switch (key) { case TLS_KEY_THREAD: @@ -1173,7 +1179,6 @@ mono_patch_info_hash (gconstpointer data) case MONO_PATCH_INFO_CLASS: case MONO_PATCH_INFO_IID: case MONO_PATCH_INFO_ADJUSTED_IID: - case MONO_PATCH_INFO_CLASS_INIT: case MONO_PATCH_INFO_METHODCONST: case MONO_PATCH_INFO_METHOD: case MONO_PATCH_INFO_METHOD_JUMP: @@ -1199,9 +1204,6 @@ mono_patch_info_hash (gconstpointer data) case MONO_PATCH_INFO_GC_CARD_TABLE_ADDR: case MONO_PATCH_INFO_GC_NURSERY_START: case MONO_PATCH_INFO_JIT_TLS_ID: - case MONO_PATCH_INFO_MONITOR_ENTER: - case MONO_PATCH_INFO_MONITOR_ENTER_V4: - case MONO_PATCH_INFO_MONITOR_EXIT: case MONO_PATCH_INFO_GOT_OFFSET: case MONO_PATCH_INFO_GC_SAFE_POINT_FLAG: return (ji->type << 8); @@ -1458,13 +1460,6 @@ mono_resolve_patch_target (MonoMethod *method, MonoDomain *domain, guint8 *code, target = mono_class_vtable (domain, patch_info->data.klass); g_assert (target); break; - case MONO_PATCH_INFO_CLASS_INIT: { - MonoVTable *vtable = mono_class_vtable (domain, patch_info->data.klass); - - g_assert (vtable); - target = mono_create_class_init_trampoline (vtable); - break; - } case MONO_PATCH_INFO_DELEGATE_TRAMPOLINE: { MonoDelegateClassMethodPair *del_tramp = patch_info->data.del_tramp; @@ -1596,15 +1591,6 @@ mono_resolve_patch_target (MonoMethod *method, MonoDomain *domain, guint8 *code, target = mono_create_rgctx_lazy_fetch_trampoline (slot); break; } - case MONO_PATCH_INFO_MONITOR_ENTER: - target = mono_create_monitor_enter_trampoline (); - break; - case MONO_PATCH_INFO_MONITOR_ENTER_V4: - target = mono_create_monitor_enter_v4_trampoline (); - break; - case MONO_PATCH_INFO_MONITOR_EXIT: - target = mono_create_monitor_exit_trampoline (); - break; #ifdef MONO_ARCH_SOFT_DEBUG_SUPPORTED case MONO_PATCH_INFO_SEQ_POINT_INFO: if (!run_cctors) @@ -1976,6 +1962,8 @@ mono_jit_free_method (MonoDomain *domain, MonoMethod *method) mono_internal_hash_table_remove (&domain->jit_code_hash, method); mono_domain_jit_code_hash_unlock (domain); g_hash_table_remove (domain_jit_info (domain)->jump_trampoline_hash, method); + + /* requires the domain lock - took above */ mono_conc_hashtable_remove (domain_jit_info (domain)->runtime_invoke_hash, method); /* Remove jump targets in this method */ @@ -2174,10 +2162,11 @@ mono_jit_runtime_invoke (MonoMethod *method, void *obj, void **params, MonoObjec return NULL; } else { mono_raise_exception (jit_ex); + /* coverity[unreachable] */ } } - info->compiled_method = mini_add_method_trampoline (NULL, callee, info->compiled_method, mono_method_needs_static_rgctx_invoke (callee, FALSE), FALSE); + info->compiled_method = mini_add_method_trampoline (callee, info->compiled_method, mono_method_needs_static_rgctx_invoke (callee, TRUE), FALSE); } else { info->compiled_method = NULL; } @@ -2258,7 +2247,9 @@ mono_jit_runtime_invoke (MonoMethod *method, void *obj, void **params, MonoObjec if (!info->dyn_call_info) info->runtime_invoke = mono_jit_compile_method (invoke); + mono_domain_lock (domain); info2 = mono_conc_hashtable_insert (domain_info->runtime_invoke_hash, method, info); + mono_domain_unlock (domain); if (info2) { g_free (info); info = info2; @@ -2339,7 +2330,7 @@ MONO_SIG_HANDLER_FUNC (, mono_sigfpe_signal_handler) MONO_SIG_HANDLER_INFO_TYPE *info = MONO_SIG_HANDLER_GET_INFO (); MONO_SIG_HANDLER_GET_CONTEXT; - ji = mono_jit_info_table_find (mono_domain_get (), mono_arch_ip_from_context (ctx)); + ji = mono_jit_info_table_find_internal (mono_domain_get (), mono_arch_ip_from_context (ctx), TRUE, TRUE); #if defined(MONO_ARCH_HAVE_IS_INT_OVERFLOW) if (mono_arch_is_int_overflow (ctx, info)) @@ -2425,7 +2416,7 @@ MONO_SIG_HANDLER_FUNC (, mono_sigsegv_signal_handler) } #endif - ji = mono_jit_info_table_find (mono_domain_get (), mono_arch_ip_from_context (ctx)); + ji = mono_jit_info_table_find_internal (mono_domain_get (), mono_arch_ip_from_context (ctx), TRUE, TRUE); #ifdef MONO_ARCH_SIGSEGV_ON_ALTSTACK if (mono_handle_soft_stack_ovf (jit_tls, ji, ctx, info, (guint8*)info->si_addr)) @@ -2605,8 +2596,10 @@ mono_get_delegate_virtual_invoke_impl (MonoMethodSignature *sig, MonoMethod *met /* FIXME Support more cases */ if (mono_aot_only) { char tramp_name [256]; + const char *imt = load_imt_reg ? "_imt" : ""; + int ind = (load_imt_reg ? (-offset) : offset) / SIZEOF_VOID_P; - sprintf (tramp_name, "delegate_virtual_invoke%s_%d", load_imt_reg ? "_imt" : "", offset / SIZEOF_VOID_P); + sprintf (tramp_name, "delegate_virtual_invoke%s_%d", imt, ind); cache [idx] = mono_aot_get_trampoline (tramp_name); g_assert (cache [idx]); } else { @@ -2665,6 +2658,8 @@ mini_parse_debug_options (void) debug_options.gen_sdb_seq_points = TRUE; else if (!strcmp (arg, "gen-compact-seq-points")) debug_options.gen_seq_points_compact_data = TRUE; + else if (!strcmp (arg, "single-imm-size")) + debug_options.single_imm_size = TRUE; else if (!strcmp (arg, "init-stacks")) debug_options.init_stacks = TRUE; else if (!strcmp (arg, "casts")) @@ -2673,6 +2668,8 @@ mini_parse_debug_options (void) debug_options.soft_breakpoints = TRUE; else if (!strcmp (arg, "check-pinvoke-callconv")) debug_options.check_pinvoke_callconv = TRUE; + else if (!strcmp (arg, "arm-use-fallback-tls")) + debug_options.arm_use_fallback_tls = TRUE; else if (!strcmp (arg, "debug-domain-unload")) mono_enable_debug_domain_unload (TRUE); else if (!strcmp (arg, "partial-sharing")) @@ -2681,7 +2678,7 @@ mini_parse_debug_options (void) mono_align_small_structs = TRUE; else { fprintf (stderr, "Invalid option for the MONO_DEBUG env variable: %s\n", arg); - fprintf (stderr, "Available options: 'handle-sigint', 'keep-delegates', 'reverse-pinvoke-exceptions', 'collect-pagefault-stats', 'break-on-unverified', 'no-gdb-backtrace', 'dont-free-domains', 'suspend-on-sigsegv', 'suspend-on-exception', 'suspend-on-unhandled', 'dyn-runtime-invoke', 'gdb', 'explicit-null-checks', 'init-stacks', 'check-pinvoke-callconv', 'debug-domain-unload', 'partial-sharing', 'align-small-structs'\n"); + fprintf (stderr, "Available options: 'handle-sigint', 'keep-delegates', 'reverse-pinvoke-exceptions', 'collect-pagefault-stats', 'break-on-unverified', 'no-gdb-backtrace', 'dont-free-domains', 'suspend-on-sigsegv', 'suspend-on-exception', 'suspend-on-unhandled', 'dyn-runtime-invoke', 'gdb', 'explicit-null-checks', 'init-stacks', 'check-pinvoke-callconv', 'arm-use-fallback-tls', 'debug-domain-unload', 'partial-sharing', 'align-small-structs'\n"); exit (1); } } @@ -2784,12 +2781,11 @@ mini_create_jit_domain_info (MonoDomain *domain) { MonoJitDomainInfo *info = g_new0 (MonoJitDomainInfo, 1); - info->class_init_trampoline_hash = g_hash_table_new (mono_aligned_addr_hash, NULL); info->jump_trampoline_hash = g_hash_table_new (mono_aligned_addr_hash, NULL); info->jit_trampoline_hash = g_hash_table_new (mono_aligned_addr_hash, NULL); info->delegate_trampoline_hash = g_hash_table_new (class_method_pair_hash, class_method_pair_equal); info->llvm_vcall_trampoline_hash = g_hash_table_new (mono_aligned_addr_hash, NULL); - info->runtime_invoke_hash = mono_conc_hashtable_new_full (&domain->lock, mono_aligned_addr_hash, NULL, NULL, runtime_invoke_info_free); + info->runtime_invoke_hash = mono_conc_hashtable_new_full (mono_aligned_addr_hash, NULL, NULL, runtime_invoke_info_free); info->seq_points = g_hash_table_new_full (mono_aligned_addr_hash, NULL, NULL, mono_seq_point_info_free); info->arch_seq_points = g_hash_table_new (mono_aligned_addr_hash, NULL); info->jump_target_hash = g_hash_table_new (NULL, NULL); @@ -2848,7 +2844,6 @@ mini_free_jit_domain_info (MonoDomain *domain) } if (info->method_code_hash) g_hash_table_destroy (info->method_code_hash); - g_hash_table_destroy (info->class_init_trampoline_hash); g_hash_table_destroy (info->jump_trampoline_hash); g_hash_table_destroy (info->jit_trampoline_hash); g_hash_table_destroy (info->delegate_trampoline_hash); @@ -2916,6 +2911,8 @@ mini_init (const char *filename, const char *runtime_version) MONO_VES_INIT_BEGIN (); + CHECKED_MONO_INIT (); + #if defined(__linux__) && !defined(__native_client__) if (access ("/proc/self/maps", F_OK) != 0) { g_print ("Mono requires /proc to be mounted.\n"); @@ -2969,6 +2966,7 @@ mini_init (const char *filename, const char *runtime_version) ticallbacks.setup_async_callback = mono_setup_async_callback; ticallbacks.thread_state_init_from_sigctx = mono_thread_state_init_from_sigctx; ticallbacks.thread_state_init_from_handle = mono_thread_state_init_from_handle; + ticallbacks.thread_state_init = mono_thread_state_init; mono_counters_init (); @@ -3030,11 +3028,6 @@ mini_init (const char *filename, const char *runtime_version) #endif mono_threads_install_cleanup (mini_thread_cleanup); -#ifdef MONO_ARCH_HAVE_NOTIFY_PENDING_EXC - check_for_pending_exc = FALSE; - mono_threads_install_notify_pending_exc ((MonoThreadNotifyPendingExcFunc)mono_arch_notify_pending_exc); -#endif - #define JIT_TRAMPOLINES_WORK #ifdef JIT_TRAMPOLINES_WORK mono_install_compile_method (mono_jit_compile_method); @@ -3142,8 +3135,6 @@ register_icalls (void) ves_icall_get_frame_info); mono_add_internal_call ("System.Diagnostics.StackTrace::get_trace", ves_icall_get_trace); - mono_add_internal_call ("System.Exception::get_trace", - ves_icall_System_Exception_get_trace); mono_add_internal_call ("Mono.Runtime::mono_runtime_install_handlers", mono_runtime_install_handlers); @@ -3229,16 +3220,19 @@ register_icalls (void) #endif register_opcode_emulation (OP_FCONV_TO_U8, "__emul_fconv_to_u8", "ulong double", mono_fconv_u8, "mono_fconv_u8", FALSE); + register_opcode_emulation (OP_RCONV_TO_U8, "__emul_rconv_to_u8", "ulong float", mono_rconv_u8, "mono_rconv_u8", FALSE); register_opcode_emulation (OP_FCONV_TO_U4, "__emul_fconv_to_u4", "uint32 double", mono_fconv_u4, "mono_fconv_u4", FALSE); register_opcode_emulation (OP_FCONV_TO_OVF_I8, "__emul_fconv_to_ovf_i8", "long double", mono_fconv_ovf_i8, "mono_fconv_ovf_i8", FALSE); register_opcode_emulation (OP_FCONV_TO_OVF_U8, "__emul_fconv_to_ovf_u8", "ulong double", mono_fconv_ovf_u8, "mono_fconv_ovf_u8", FALSE); register_opcode_emulation (OP_RCONV_TO_OVF_I8, "__emul_rconv_to_ovf_i8", "long float", mono_rconv_ovf_i8, "mono_rconv_ovf_i8", FALSE); register_opcode_emulation (OP_RCONV_TO_OVF_U8, "__emul_rconv_to_ovf_u8", "ulong float", mono_rconv_ovf_u8, "mono_rconv_ovf_u8", FALSE); + #ifdef MONO_ARCH_EMULATE_FCONV_TO_I8 register_opcode_emulation (OP_FCONV_TO_I8, "__emul_fconv_to_i8", "long double", mono_fconv_i8, "mono_fconv_i8", FALSE); register_opcode_emulation (OP_RCONV_TO_I8, "__emul_rconv_to_i8", "long float", mono_rconv_i8, "mono_rconv_i8", FALSE); #endif + #ifdef MONO_ARCH_EMULATE_CONV_R8_UN register_opcode_emulation (OP_ICONV_TO_R_UN, "__emul_iconv_to_r_un", "double int32", mono_conv_to_r8_un, "mono_conv_to_r8_un", FALSE); #endif @@ -3359,8 +3353,6 @@ register_icalls (void) register_icall (mono_fill_method_rgctx, "mono_method_fill_rgctx", "ptr ptr int", FALSE); register_icall (mono_debugger_agent_user_break, "mono_debugger_agent_user_break", "void", FALSE); - register_dyn_icall (mono_create_specific_trampoline (NULL, MONO_TRAMPOLINE_GENERIC_CLASS_INIT, mono_get_root_domain (), NULL), - "specific_trampoline_generic_class_init", "void", TRUE); #ifdef TARGET_IOS register_icall (pthread_getspecific, "pthread_getspecific", "ptr ptr", TRUE); @@ -3451,6 +3443,7 @@ mini_cleanup (MonoDomain *domain) #ifndef MONO_CROSS_COMPILE mono_domain_free (domain, TRUE); + mono_gc_mutex_cleanup (); #endif #ifdef ENABLE_LLVM @@ -3488,8 +3481,6 @@ mini_cleanup (MonoDomain *domain) mono_mutex_destroy (&jit_mutex); - mono_mutex_destroy (&mono_delegate_section); - mono_code_manager_cleanup (); #ifdef USE_JUMP_TABLES @@ -3601,6 +3592,17 @@ void mono_precompile_assemblies () g_hash_table_destroy (assemblies); } +/* + * Used by LLVM. + * Have to export this for AOT. + */ +void +mono_personality (void) +{ + /* Not used */ + g_assert_not_reached (); +} + #ifdef USE_JUMP_TABLES #define DEFAULT_JUMPTABLE_CHUNK_ELEMENTS 128