X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmini%2Fmini-runtime.c;h=2eeb5f34d6e3de1fb09db5496e922816efd868ad;hb=919a03d17d36604f05e1d99c3f9f26a1509e9655;hp=b6ecda34d603b0f4e07a7d91e111bd30c4bdf19d;hpb=0279b08ccbab97f6af20dcad088333541a36949e;p=mono.git diff --git a/mono/mini/mini-runtime.c b/mono/mini/mini-runtime.c index b6ecda34d60..2eeb5f34d6e 100644 --- a/mono/mini/mini-runtime.c +++ b/mono/mini/mini-runtime.c @@ -39,7 +39,6 @@ #include #include #include -#include "mono/metadata/profiler.h" #include #include #include @@ -65,6 +64,7 @@ #include #include #include +#include #include #include #include @@ -131,16 +131,12 @@ int valgrind_register; #endif GList* mono_aot_paths; -static gboolean mini_enable_profiler = FALSE; -static char* mini_profiler_options = NULL; +static GPtrArray *profile_options; static GSList *tramp_infos; static void register_icalls (void); -static gboolean mini_profiler_enabled (void) { return mini_enable_profiler; } -static const char* mini_profiler_get_options (void) { return mini_profiler_options; } - gboolean mono_running_on_valgrind (void) { @@ -574,7 +570,7 @@ G_GNUC_UNUSED gboolean mono_debug_count (void) { static int count = 0, int_val = 0; - static gboolean inited; + static gboolean inited, has_value = FALSE; count ++; @@ -583,11 +579,12 @@ mono_debug_count (void) if (value) { int_val = atoi (value); g_free (value); + has_value = TRUE; } inited = TRUE; } - if (!int_val) + if (!has_value) return TRUE; if (count == int_val) @@ -893,7 +890,9 @@ mono_thread_abort (MonoObject *obj) g_free (jit_tls);*/ if ((mono_runtime_unhandled_exception_policy_get () == MONO_UNHANDLED_POLICY_LEGACY) || - (obj->vtable->klass == mono_defaults.threadabortexception_class)) { + (obj->vtable->klass == mono_defaults.threadabortexception_class) || + ((obj->vtable->klass) == mono_class_get_appdomain_unloaded_exception_class () && + mono_thread_info_current ()->runtime_thread)) { mono_thread_exit (); } else { mono_invoke_unhandled_exception_hook (obj); @@ -1217,6 +1216,7 @@ mono_patch_info_hash (gconstpointer data) case MONO_PATCH_INFO_GC_SAFE_POINT_FLAG: case MONO_PATCH_INFO_AOT_MODULE: case MONO_PATCH_INFO_JIT_THREAD_ATTACH: + case MONO_PATCH_INFO_PROFILER_ALLOCATION_COUNT: return (ji->type << 8); case MONO_PATCH_INFO_CASTCLASS_CACHE: return (ji->type << 8) | (ji->data.index); @@ -1647,6 +1647,10 @@ mono_resolve_patch_target (MonoMethod *method, MonoDomain *domain, guint8 *code, target = mi->func; break; } + case MONO_PATCH_INFO_PROFILER_ALLOCATION_COUNT: { + target = (gpointer) &mono_profiler_state.gc_allocation_count; + break; + } default: g_assert_not_reached (); } @@ -1734,12 +1738,6 @@ lookup_method (MonoDomain *domain, MonoMethod *method) return ji; } -MonoJitInfo * -mono_get_jit_info_from_method (MonoDomain *domain, MonoMethod *method) -{ - return lookup_method (domain, method); -} - MonoClass* mini_get_class (MonoMethod *method, guint32 token, MonoGenericContext *context) { @@ -2053,7 +2051,7 @@ lookup_start: if (! ((domain != target_domain) && !info->domain_neutral)) { MonoVTable *vtable; - mono_jit_stats.methods_lookups++; + InterlockedIncrement (&mono_jit_stats.methods_lookups); vtable = mono_class_vtable_full (domain, method->klass, error); if (!is_ok (error)) return NULL; @@ -2298,7 +2296,7 @@ mono_jit_find_compiled_method_with_jit_info (MonoDomain *domain, MonoMethod *met if (info) { /* We can't use a domain specific method in another domain */ if (! ((domain != target_domain) && !info->domain_neutral)) { - mono_jit_stats.methods_lookups++; + InterlockedIncrement (&mono_jit_stats.methods_lookups); if (ji) *ji = info; return info->code_start; @@ -2433,8 +2431,11 @@ create_runtime_invoke_info (MonoDomain *domain, MonoMethod *method, gpointer com if (mono_class_is_contextbound (method->klass) || !info->compiled_method) supported = FALSE; - if (supported) + if (supported) { info->dyn_call_info = mono_arch_dyn_call_prepare (sig); + if (debug_options.dyn_runtime_invoke) + g_assert (info->dyn_call_info); + } } #endif @@ -2626,6 +2627,8 @@ mono_jit_runtime_invoke (MonoMethod *method, void *obj, void **params, MonoObjec #endif error_init (error); + if (exc) + *exc = NULL; if (obj == NULL && !(method->flags & METHOD_ATTRIBUTE_STATIC) && !method->string_ctor && (method->wrapper_type == 0)) { g_warning ("Ignoring invocation of an instance method on a NULL instance.\n"); @@ -2734,8 +2737,8 @@ mono_jit_runtime_invoke (MonoMethod *method, void *obj, void **params, MonoObjec MonoMethodSignature *sig = mono_method_signature (method); gpointer *args; static RuntimeInvokeDynamicFunction dyn_runtime_invoke; - int i, pindex; - guint8 buf [512]; + int i, pindex, buf_size; + guint8 *buf; guint8 retval [256]; if (!dyn_runtime_invoke) { @@ -2764,7 +2767,11 @@ mono_jit_runtime_invoke (MonoMethod *method, void *obj, void **params, MonoObjec //printf ("M: %s\n", mono_method_full_name (method, TRUE)); - mono_arch_start_dyn_call (info->dyn_call_info, (gpointer**)args, retval, buf, sizeof (buf)); + buf_size = mono_arch_dyn_call_get_buf_size (info->dyn_call_info); + buf = g_alloca (buf_size); + g_assert (buf); + + mono_arch_start_dyn_call (info->dyn_call_info, (gpointer**)args, retval, buf); dyn_runtime_invoke (buf, exc, info->compiled_method); mono_arch_finish_dyn_call (info->dyn_call_info, buf); @@ -3304,12 +3311,13 @@ mini_get_delegate_arg (MonoMethod *method, gpointer method_ptr) void mini_init_delegate (MonoDelegate *del) { - if (mono_llvm_only) - del->extra_arg = mini_get_delegate_arg (del->method, del->method_ptr); #ifdef ENABLE_INTERPRETER if (mono_use_interpreter) mono_interp_init_delegate (del); + else #endif + if (mono_llvm_only) + del->extra_arg = mini_get_delegate_arg (del->method, del->method_ptr); } char* @@ -3759,10 +3767,12 @@ mini_llvm_init (void) } void -mini_profiler_enable_with_options (const char* profile_options) +mini_add_profiler_argument (const char *desc) { - mini_enable_profiler = TRUE; - mini_profiler_options = g_strdup (profile_options); + if (!profile_options) + profile_options = g_ptr_array_new (); + + g_ptr_array_add (profile_options, (gpointer) desc); } MonoDomain * @@ -3935,10 +3945,18 @@ mini_init (const char *filename, const char *runtime_version) mono_install_get_class_from_name (mono_aot_get_class_from_name); mono_install_jit_info_find_in_aot (mono_aot_find_jit_info); - if (mini_profiler_enabled ()) { - mono_profiler_load (mini_profiler_get_options ()); - mono_profiler_thread_name (MONO_NATIVE_THREAD_ID_TO_UINT (mono_native_thread_id_get ()), "Main"); - } + mono_profiler_state.context_enable = mini_profiler_context_enable; + mono_profiler_state.context_get_this = mini_profiler_context_get_this; + mono_profiler_state.context_get_argument = mini_profiler_context_get_argument; + mono_profiler_state.context_get_local = mini_profiler_context_get_local; + mono_profiler_state.context_get_result = mini_profiler_context_get_result; + mono_profiler_state.context_free_buffer = mini_profiler_context_free_buffer; + + if (profile_options) + for (guint i = 0; i < profile_options->len; i++) + mono_profiler_load ((const char *) g_ptr_array_index (profile_options, i)); + + mono_profiler_started (); if (debug_options.collect_pagefault_stats) mono_aot_set_make_unreadable (TRUE); @@ -4015,12 +4033,13 @@ mini_init (const char *filename, const char *runtime_version) mono_runtime_init_checked (domain, mono_thread_start_cb, mono_thread_attach_cb, &error); mono_error_assert_ok (&error); mono_thread_attach (domain); + MONO_PROFILER_RAISE (thread_name, (MONO_NATIVE_THREAD_ID_TO_UINT (mono_native_thread_id_get ()), "Main")); #endif - if (mono_profiler_get_events () & MONO_PROFILE_STATISTICAL) + if (mono_profiler_sampling_enabled ()) mono_runtime_setup_stat_profiler (); - mono_profiler_runtime_initialized (); + MONO_PROFILER_RAISE (runtime_initialized, ()); MONO_VES_INIT_END (); @@ -4039,7 +4058,7 @@ register_icalls (void) mono_add_internal_call ("Mono.Runtime::mono_runtime_cleanup_handlers", mono_runtime_cleanup_handlers); -#if defined(PLATFORM_ANDROID) || defined(TARGET_ANDROID) +#if defined(HOST_ANDROID) || defined(TARGET_ANDROID) mono_add_internal_call ("System.Diagnostics.Debugger::Mono_UnhandledException_internal", mono_debugger_agent_unhandled_exception); #endif @@ -4051,8 +4070,9 @@ register_icalls (void) * the wrapper would call the icall which would call the wrapper and * so on. */ - register_icall (mono_profiler_method_enter, "mono_profiler_method_enter", "void ptr", TRUE); - register_icall (mono_profiler_method_leave, "mono_profiler_method_leave", "void ptr", TRUE); + register_icall (mono_profiler_raise_method_enter, "mono_profiler_raise_method_enter", "void ptr ptr", TRUE); + register_icall (mono_profiler_raise_method_leave, "mono_profiler_raise_method_leave", "void ptr ptr", TRUE); + register_icall (mono_profiler_raise_method_tail_call, "mono_profiler_raise_method_tail_call", "void ptr ptr", TRUE); register_icall (mono_trace_enter_method, "mono_trace_enter_method", NULL, TRUE); register_icall (mono_trace_leave_method, "mono_trace_leave_method", NULL, TRUE); @@ -4079,6 +4099,7 @@ register_icalls (void) register_dyn_icall (mono_get_rethrow_exception (), "mono_arch_rethrow_exception", "void object", TRUE); register_dyn_icall (mono_get_throw_corlib_exception (), "mono_arch_throw_corlib_exception", "void ptr", TRUE); register_icall (mono_thread_get_undeniable_exception, "mono_thread_get_undeniable_exception", "object", FALSE); + register_icall (mono_thread_self_abort, "mono_thread_self_abort", "void", FALSE); register_icall (mono_thread_interruption_checkpoint, "mono_thread_interruption_checkpoint", "object", FALSE); register_icall (mono_thread_force_interruption_checkpoint_noraise, "mono_thread_force_interruption_checkpoint_noraise", "object", FALSE); @@ -4245,7 +4266,8 @@ register_icalls (void) register_icall (mono_gsharedvt_constrained_call, "mono_gsharedvt_constrained_call", "object ptr ptr ptr ptr ptr", FALSE); register_icall (mono_gsharedvt_value_copy, "mono_gsharedvt_value_copy", "void ptr ptr ptr", TRUE); - register_icall_no_wrapper (mono_gc_get_range_copy_func (), "mono_gc_range_copy", "void ptr ptr int"); + //WARNING We do runtime selection here but the string *MUST* be to a fallback function that has same signature and behavior + register_icall_no_wrapper (mono_gc_get_range_copy_func (), "mono_gc_wbarrier_range_copy", "void ptr ptr int"); register_icall (mono_object_castclass_with_cache, "mono_object_castclass_with_cache", "object object ptr ptr", FALSE); register_icall (mono_object_isinst_with_cache, "mono_object_isinst_with_cache", "object object ptr ptr", FALSE); @@ -4296,46 +4318,51 @@ register_icalls (void) MonoJitStats mono_jit_stats = {0}; +/** + * Counters of mono_stats and mono_jit_stats can be read without locking here. + * MONO_NO_SANITIZE_THREAD tells Clang's ThreadSanitizer to hide all reports of these (known) races. + */ +MONO_NO_SANITIZE_THREAD static void print_jit_stats (void) { if (mono_jit_stats.enabled) { g_print ("Mono Jit statistics\n"); - g_print ("Max code size ratio: %.2f (%s)\n", mono_jit_stats.max_code_size_ratio/100.0, + g_print ("Max code size ratio: %.2f (%s)\n", mono_jit_stats.max_code_size_ratio / 100.0, mono_jit_stats.max_ratio_method); - g_print ("Biggest method: %ld (%s)\n", mono_jit_stats.biggest_method_size, + g_print ("Biggest method: %" G_GINT32_FORMAT " (%s)\n", mono_jit_stats.biggest_method_size, mono_jit_stats.biggest_method); - g_print ("Delegates created: %ld\n", mono_stats.delegate_creations); - g_print ("Initialized classes: %ld\n", mono_stats.initialized_class_count); - g_print ("Used classes: %ld\n", mono_stats.used_class_count); - g_print ("Generic vtables: %ld\n", mono_stats.generic_vtable_count); - g_print ("Methods: %ld\n", mono_stats.method_count); - g_print ("Static data size: %ld\n", mono_stats.class_static_data_size); - g_print ("VTable data size: %ld\n", mono_stats.class_vtable_size); + g_print ("Delegates created: %" G_GINT32_FORMAT "\n", mono_stats.delegate_creations); + g_print ("Initialized classes: %" G_GINT32_FORMAT "\n", mono_stats.initialized_class_count); + g_print ("Used classes: %" G_GINT32_FORMAT "\n", mono_stats.used_class_count); + g_print ("Generic vtables: %" G_GINT32_FORMAT "\n", mono_stats.generic_vtable_count); + g_print ("Methods: %" G_GINT32_FORMAT "\n", mono_stats.method_count); + g_print ("Static data size: %" G_GINT32_FORMAT "\n", mono_stats.class_static_data_size); + g_print ("VTable data size: %" G_GINT32_FORMAT "\n", mono_stats.class_vtable_size); g_print ("Mscorlib mempool size: %d\n", mono_mempool_get_allocated (mono_defaults.corlib->mempool)); - g_print ("\nInitialized classes: %ld\n", mono_stats.generic_class_count); - g_print ("Inflated types: %ld\n", mono_stats.inflated_type_count); + g_print ("\nInitialized classes: %" G_GINT32_FORMAT "\n", mono_stats.generic_class_count); + g_print ("Inflated types: %" G_GINT32_FORMAT "\n", mono_stats.inflated_type_count); g_print ("Generics virtual invokes: %ld\n", mono_jit_stats.generic_virtual_invocations); - g_print ("Sharable generic methods: %ld\n", mono_stats.generics_sharable_methods); - g_print ("Unsharable generic methods: %ld\n", mono_stats.generics_unsharable_methods); - g_print ("Shared generic methods: %ld\n", mono_stats.generics_shared_methods); - g_print ("Shared vtype generic methods: %ld\n", mono_stats.gsharedvt_methods); + g_print ("Sharable generic methods: %" G_GINT32_FORMAT "\n", mono_stats.generics_sharable_methods); + g_print ("Unsharable generic methods: %" G_GINT32_FORMAT "\n", mono_stats.generics_unsharable_methods); + g_print ("Shared generic methods: %" G_GINT32_FORMAT "\n", mono_stats.generics_shared_methods); + g_print ("Shared vtype generic methods: %" G_GINT32_FORMAT "\n", mono_stats.gsharedvt_methods); - g_print ("IMT tables size: %ld\n", mono_stats.imt_tables_size); - g_print ("IMT number of tables: %ld\n", mono_stats.imt_number_of_tables); - g_print ("IMT number of methods: %ld\n", mono_stats.imt_number_of_methods); - g_print ("IMT used slots: %ld\n", mono_stats.imt_used_slots); - g_print ("IMT colliding slots: %ld\n", mono_stats.imt_slots_with_collisions); - g_print ("IMT max collisions: %ld\n", mono_stats.imt_max_collisions_in_slot); - g_print ("IMT methods at max col: %ld\n", mono_stats.imt_method_count_when_max_collisions); - g_print ("IMT trampolines size: %ld\n", mono_stats.imt_trampolines_size); + g_print ("IMT tables size: %" G_GINT32_FORMAT "\n", mono_stats.imt_tables_size); + g_print ("IMT number of tables: %" G_GINT32_FORMAT "\n", mono_stats.imt_number_of_tables); + g_print ("IMT number of methods: %" G_GINT32_FORMAT "\n", mono_stats.imt_number_of_methods); + g_print ("IMT used slots: %" G_GINT32_FORMAT "\n", mono_stats.imt_used_slots); + g_print ("IMT colliding slots: %" G_GINT32_FORMAT "\n", mono_stats.imt_slots_with_collisions); + g_print ("IMT max collisions: %" G_GINT32_FORMAT "\n", mono_stats.imt_max_collisions_in_slot); + g_print ("IMT methods at max col: %" G_GINT32_FORMAT "\n", mono_stats.imt_method_count_when_max_collisions); + g_print ("IMT trampolines size: %" G_GINT32_FORMAT "\n", mono_stats.imt_trampolines_size); - g_print ("JIT info table inserts: %ld\n", mono_stats.jit_info_table_insert_count); - g_print ("JIT info table removes: %ld\n", mono_stats.jit_info_table_remove_count); - g_print ("JIT info table lookups: %ld\n", mono_stats.jit_info_table_lookup_count); + g_print ("JIT info table inserts: %" G_GINT32_FORMAT "\n", mono_stats.jit_info_table_insert_count); + g_print ("JIT info table removes: %" G_GINT32_FORMAT "\n", mono_stats.jit_info_table_remove_count); + g_print ("JIT info table lookups: %" G_GINT32_FORMAT "\n", mono_stats.jit_info_table_lookup_count); g_free (mono_jit_stats.max_ratio_method); mono_jit_stats.max_ratio_method = NULL; @@ -4347,9 +4374,11 @@ print_jit_stats (void) void mini_cleanup (MonoDomain *domain) { - if (mono_profiler_get_events () & MONO_PROFILE_STATISTICAL) + if (mono_profiler_sampling_enabled ()) mono_runtime_shutdown_stat_profiler (); + MONO_PROFILER_RAISE (runtime_shutdown_begin, ()); + #ifndef DISABLE_COM cominterop_release_all_rcws (); #endif @@ -4371,7 +4400,12 @@ mini_cleanup (MonoDomain *domain) mono_threadpool_cleanup (); - mono_profiler_shutdown (); + MONO_PROFILER_RAISE (runtime_shutdown_end, ()); + + mono_profiler_cleanup (); + + if (profile_options) + g_ptr_array_free (profile_options, TRUE); free_jit_tls_data ((MonoJitTlsData *)mono_tls_get_jit_tls ());