X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmini%2Fmini.c;h=f876ce3ea5c5e30c9eff8506e15d0c87eca36806;hb=5664e72b7c4e8e9ca5c89813b5213db2c8c78042;hp=b5e13dc592ba44c8149e99b8e1489ceca119a77f;hpb=7cfd463841a4875af614ce104e030ac91aa4f185;p=mono.git diff --git a/mono/mini/mini.c b/mono/mini/mini.c index b5e13dc592b..f876ce3ea5c 100755 --- a/mono/mini/mini.c +++ b/mono/mini/mini.c @@ -53,6 +53,7 @@ #include #include #include +#include #include #include #include @@ -63,6 +64,7 @@ #include #include "mini.h" +#include "seq-points.h" #include "mini-llvm.h" #include "tasklets.h" #include @@ -75,6 +77,7 @@ #include "mini-gc.h" #include "debugger-agent.h" +#include "seq-points.h" static gpointer mono_jit_compile_method_with_opt (MonoMethod *method, guint32 opt, MonoException **ex); @@ -710,18 +713,24 @@ G_GNUC_UNUSED gboolean mono_debug_count (void) { static int count = 0; + static gboolean inited; + static const char *value; + count ++; - if (!g_getenv ("COUNT")) + if (!inited) { + value = g_getenv ("COUNT"); + inited = TRUE; + } + + if (!value) return TRUE; - if (count == atoi (g_getenv ("COUNT"))) { + if (count == atoi (value)) break_count (); - } - if (count > atoi (g_getenv ("COUNT"))) { + if (count > atoi (value)) return FALSE; - } return TRUE; } @@ -1241,7 +1250,7 @@ mono_compile_create_var_for_vreg (MonoCompile *cfg, MonoType *type, int opcode, if ((num + 1) >= cfg->varinfo_count) { int orig_count = cfg->varinfo_count; - cfg->varinfo_count = cfg->varinfo_count ? (cfg->varinfo_count * 2) : 64; + cfg->varinfo_count = cfg->varinfo_count ? (cfg->varinfo_count * 2) : 32; cfg->varinfo = (MonoInst **)g_realloc (cfg->varinfo, sizeof (MonoInst*) * cfg->varinfo_count); cfg->vars = (MonoMethodVar *)g_realloc (cfg->vars, sizeof (MonoMethodVar) * cfg->varinfo_count); memset (&cfg->vars [orig_count], 0, (cfg->varinfo_count - orig_count) * sizeof (MonoMethodVar)); @@ -3914,159 +3923,6 @@ mono_postprocess_patches (MonoCompile *cfg) } } -static void -collect_pred_seq_points (MonoBasicBlock *bb, MonoInst *ins, GSList **next, int depth) -{ - int i; - MonoBasicBlock *in_bb; - GSList *l; - - for (i = 0; i < bb->in_count; ++i) { - in_bb = bb->in_bb [i]; - - if (in_bb->last_seq_point) { - int src_index = in_bb->last_seq_point->backend.size; - int dst_index = ins->backend.size; - - /* bb->in_bb might contain duplicates */ - for (l = next [src_index]; l; l = l->next) - if (GPOINTER_TO_UINT (l->data) == dst_index) - break; - if (!l) - next [src_index] = g_slist_append (next [src_index], GUINT_TO_POINTER (dst_index)); - } else { - /* Have to look at its predecessors */ - if (depth < 5) - collect_pred_seq_points (in_bb, ins, next, depth + 1); - } - } -} - -static void -mono_save_seq_point_info (MonoCompile *cfg) -{ - MonoBasicBlock *bb; - GSList *bb_seq_points, *l; - MonoInst *last; - MonoDomain *domain = cfg->domain; - int i; - MonoSeqPointInfo *info; - GSList **next; - - if (!cfg->seq_points) - return; - - info = g_malloc0 (sizeof (MonoSeqPointInfo) + (cfg->seq_points->len * sizeof (SeqPoint))); - info->len = cfg->seq_points->len; - for (i = 0; i < cfg->seq_points->len; ++i) { - SeqPoint *sp = &info->seq_points [i]; - MonoInst *ins = g_ptr_array_index (cfg->seq_points, i); - - sp->il_offset = ins->inst_imm; - sp->native_offset = ins->inst_offset; - if (ins->flags & MONO_INST_NONEMPTY_STACK) - sp->flags |= MONO_SEQ_POINT_FLAG_NONEMPTY_STACK; - - /* Used below */ - ins->backend.size = i; - } - - /* - * For each sequence point, compute the list of sequence points immediately - * following it, this is needed to implement 'step over' in the debugger agent. - */ - next = g_new0 (GSList*, cfg->seq_points->len); - for (bb = cfg->bb_entry; bb; bb = bb->next_bb) { - bb_seq_points = g_slist_reverse (bb->seq_points); - last = NULL; - for (l = bb_seq_points; l; l = l->next) { - MonoInst *ins = l->data; - - if (ins->inst_imm == METHOD_ENTRY_IL_OFFSET || ins->inst_imm == METHOD_EXIT_IL_OFFSET) - /* Used to implement method entry/exit events */ - continue; - if (ins->inst_offset == SEQ_POINT_NATIVE_OFFSET_DEAD_CODE) - continue; - - if (last != NULL) { - /* Link with the previous seq point in the same bb */ - next [last->backend.size] = g_slist_append (next [last->backend.size], GUINT_TO_POINTER (ins->backend.size)); - } else { - /* Link with the last bb in the previous bblocks */ - collect_pred_seq_points (bb, ins, next, 0); - } - - last = ins; - } - - if (bb->last_ins && bb->last_ins->opcode == OP_ENDFINALLY && bb->seq_points) { - MonoBasicBlock *bb2; - MonoInst *endfinally_seq_point = NULL; - - /* - * The ENDFINALLY branches are not represented in the cfg, so link it with all seq points starting bbs. - */ - l = g_slist_last (bb->seq_points); - if (l) { - endfinally_seq_point = l->data; - - for (bb2 = cfg->bb_entry; bb2; bb2 = bb2->next_bb) { - GSList *l = g_slist_last (bb2->seq_points); - - if (l) { - MonoInst *ins = l->data; - - if (!(ins->inst_imm == METHOD_ENTRY_IL_OFFSET || ins->inst_imm == METHOD_EXIT_IL_OFFSET) && ins != endfinally_seq_point) - next [endfinally_seq_point->backend.size] = g_slist_append (next [endfinally_seq_point->backend.size], GUINT_TO_POINTER (ins->backend.size)); - } - } - } - } - } - - if (cfg->verbose_level > 2) { - printf ("\nSEQ POINT MAP: \n"); - } - - for (i = 0; i < cfg->seq_points->len; ++i) { - SeqPoint *sp = &info->seq_points [i]; - GSList *l; - int j, next_index; - - sp->next_len = g_slist_length (next [i]); - sp->next = g_new (int, sp->next_len); - j = 0; - if (cfg->verbose_level > 2 && next [i]) { - printf ("\tIL0x%x ->", sp->il_offset); - for (l = next [i]; l; l = l->next) { - next_index = GPOINTER_TO_UINT (l->data); - printf (" IL0x%x", info->seq_points [next_index].il_offset); - } - printf ("\n"); - } - for (l = next [i]; l; l = l->next) { - next_index = GPOINTER_TO_UINT (l->data); - sp->next [j ++] = next_index; - } - g_slist_free (next [i]); - } - g_free (next); - - cfg->seq_point_info = info; - - // FIXME: dynamic methods - if (!cfg->compile_aot) { - mono_domain_lock (domain); - // FIXME: How can the lookup succeed ? - if (!g_hash_table_lookup (domain_jit_info (domain)->seq_points, cfg->method_to_register)) - g_hash_table_insert (domain_jit_info (domain)->seq_points, cfg->method_to_register, info); - mono_domain_unlock (domain); - } - - g_ptr_array_free (cfg->seq_points, TRUE); - cfg->seq_points = NULL; -} - void mono_codegen (MonoCompile *cfg) { @@ -4118,6 +3974,8 @@ mono_codegen (MonoCompile *cfg) cfg->code_len = code - cfg->native_code; cfg->prolog_end = cfg->code_len; + cfg->cfa_reg = cfg->cur_cfa_reg; + cfg->cfa_offset = cfg->cur_cfa_offset; mono_debug_open_method (cfg); @@ -4132,6 +3990,7 @@ mono_codegen (MonoCompile *cfg) if (bb == cfg->bb_exit) { cfg->epilog_begin = cfg->code_len; mono_arch_emit_epilog (cfg); + cfg->epilog_end = cfg->code_len; } } @@ -4640,7 +4499,7 @@ create_jit_info (MonoCompile *cfg, MonoMethod *method_to_compile) info = mono_jit_info_get_arch_eh_info (jinfo); g_assert (info); - info->epilog_size = cfg->code_size - cfg->epilog_begin; + info->epilog_size = cfg->code_len - cfg->epilog_begin; } jinfo->unwind_info = unwind_desc; g_free (unwind_info); @@ -4920,6 +4779,8 @@ mini_method_compile (MonoMethod *method, guint32 opts, MonoDomain *domain, JitFl #ifdef ENABLE_LLVM gboolean llvm = (flags & JIT_FLAG_LLVM) ? 1 : 0; #endif + static gboolean verbose_method_inited; + static const char *verbose_method_name; InterlockedIncrement (&mono_jit_stats.methods_compiled); if (mono_profiler_get_events () & MONO_PROFILE_JIT_COMPILATION) @@ -4989,7 +4850,9 @@ mini_method_compile (MonoMethod *method, guint32 opts, MonoDomain *domain, JitFl cfg->full_aot = full_aot; cfg->skip_visibility = method->skip_visibility; cfg->orig_method = method; - cfg->gen_seq_points = debug_options.gen_seq_points; + cfg->gen_seq_points = TRUE; + cfg->gen_seq_points_debug_data = debug_options.gen_seq_points_debug_data; + cfg->explicit_null_checks = debug_options.explicit_null_checks; cfg->soft_breakpoints = debug_options.soft_breakpoints; cfg->check_pinvoke_callconv = debug_options.check_pinvoke_callconv; @@ -5000,6 +4863,7 @@ mini_method_compile (MonoMethod *method, guint32 opts, MonoDomain *domain, JitFl if (cfg->gen_seq_points) cfg->seq_points = g_ptr_array_new (); + mono_error_init (&cfg->error); if (cfg->compile_aot && !try_generic_shared && (method->is_generic || method->klass->generic_container || method_is_gshared)) { cfg->exception_type = MONO_EXCEPTION_GENERIC_SHARING_FAILED; @@ -5033,6 +4897,7 @@ mini_method_compile (MonoMethod *method, guint32 opts, MonoDomain *domain, JitFl if (cfg->generic_sharing_context) { method_to_register = method_to_compile; + cfg->gshared = TRUE; } else { g_assert (method == method_to_compile); method_to_register = method; @@ -5069,9 +4934,8 @@ mini_method_compile (MonoMethod *method, guint32 opts, MonoDomain *domain, JitFl { static gboolean inited; - if (!inited) { + if (!inited) inited = TRUE; - } /* * Check for methods which cannot be compiled by LLVM early, to avoid @@ -5147,8 +5011,12 @@ mini_method_compile (MonoMethod *method, guint32 opts, MonoDomain *domain, JitFl cfg->opt |= MONO_OPT_ABCREM; } - if (g_getenv ("MONO_VERBOSE_METHOD")) { - const char *name = g_getenv ("MONO_VERBOSE_METHOD"); + if (!verbose_method_inited) { + verbose_method_name = g_getenv ("MONO_VERBOSE_METHOD"); + verbose_method_inited = TRUE; + } + if (verbose_method_name) { + const char *name = verbose_method_name; if ((strchr (name, '.') > name) || strchr (name, ':')) { MonoMethodDesc *desc; @@ -5159,7 +5027,7 @@ mini_method_compile (MonoMethod *method, guint32 opts, MonoDomain *domain, JitFl } mono_method_desc_free (desc); } else { - if (strcmp (cfg->method->name, g_getenv ("MONO_VERBOSE_METHOD")) == 0) + if (strcmp (cfg->method->name, name) == 0) cfg->verbose_level = 4; } } @@ -5266,7 +5134,7 @@ mini_method_compile (MonoMethod *method, guint32 opts, MonoDomain *domain, JitFl /* SSAPRE is not supported on linear IR */ cfg->opt &= ~MONO_OPT_SSAPRE; - i = mono_method_to_ir (cfg, method_to_compile, NULL, NULL, NULL, NULL, NULL, 0, FALSE); + i = mono_method_to_ir (cfg, method_to_compile, NULL, NULL, NULL, NULL, 0, FALSE); if (i < 0) { if (try_generic_shared && cfg->exception_type == MONO_EXCEPTION_GENERIC_SHARING_FAILED) { @@ -5417,7 +5285,7 @@ mini_method_compile (MonoMethod *method, guint32 opts, MonoDomain *domain, JitFl */ //#define DEBUGSSA "logic_run" -#define DEBUGSSA_CLASS "Tests" +//#define DEBUGSSA_CLASS "Tests" #ifdef DEBUGSSA if (!cfg->disable_ssa) { @@ -6086,6 +5954,10 @@ mono_jit_compile_method_inner (MonoMethod *method, MonoDomain *target_domain, in case MONO_EXCEPTION_OUT_OF_MEMORY: ex = mono_domain_get ()->out_of_memory_ex; break; + case MONO_EXCEPTION_MONO_ERROR: + g_assert (!mono_error_ok (&cfg->error)); + ex = mono_error_convert_to_exception (&cfg->error); + break; default: g_assert_not_reached (); } @@ -6723,14 +6595,12 @@ mono_jit_runtime_invoke (MonoMethod *method, void *obj, void **params, MonoObjec return runtime_invoke (obj, params, exc, info->compiled_method); } -SIG_HANDLER_FUNC (, mono_sigfpe_signal_handler) +MONO_SIG_HANDLER_FUNC (, mono_sigfpe_signal_handler) { MonoException *exc = NULL; MonoJitInfo *ji; -#if !(defined(MONO_ARCH_USE_SIGACTION) || defined(HOST_WIN32)) - void *info = NULL; -#endif - GET_CONTEXT; + void *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)); @@ -6748,12 +6618,12 @@ SIG_HANDLER_FUNC (, mono_sigfpe_signal_handler) #endif if (!ji) { - if (!mono_do_crash_chaining && mono_chain_signal (SIG_HANDLER_PARAMS)) + if (!mono_do_crash_chaining && mono_chain_signal (MONO_SIG_HANDLER_PARAMS)) return; mono_handle_native_sigsegv (SIGSEGV, ctx); if (mono_do_crash_chaining) { - mono_chain_signal (SIG_HANDLER_PARAMS); + mono_chain_signal (MONO_SIG_HANDLER_PARAMS); return; } } @@ -6761,10 +6631,10 @@ SIG_HANDLER_FUNC (, mono_sigfpe_signal_handler) mono_arch_handle_exception (ctx, exc); } -SIG_HANDLER_FUNC (, mono_sigill_signal_handler) +MONO_SIG_HANDLER_FUNC (, mono_sigill_signal_handler) { MonoException *exc; - GET_CONTEXT; + MONO_SIG_HANDLER_GET_CONTEXT; exc = mono_get_exception_execution_engine ("SIGILL"); @@ -6775,13 +6645,15 @@ SIG_HANDLER_FUNC (, mono_sigill_signal_handler) #define HAVE_SIG_INFO #endif -SIG_HANDLER_FUNC (, mono_sigsegv_signal_handler) +MONO_SIG_HANDLER_FUNC (, mono_sigsegv_signal_handler) { MonoJitInfo *ji; MonoJitTlsData *jit_tls = mono_native_tls_get_value (mono_jit_tls_id); gpointer fault_addr = NULL; - - GET_CONTEXT; +#ifdef HAVE_SIG_INFO + MONO_SIG_HANDLER_INFO_TYPE *info = MONO_SIG_HANDLER_GET_INFO (); +#endif + MONO_SIG_HANDLER_GET_CONTEXT; #if defined(MONO_ARCH_SOFT_DEBUG_SUPPORTED) && defined(HAVE_SIG_INFO) if (mono_arch_is_single_step_event (info, ctx)) { @@ -6803,11 +6675,11 @@ SIG_HANDLER_FUNC (, mono_sigsegv_signal_handler) /* The thread might no be registered with the runtime */ if (!mono_domain_get () || !jit_tls) { - if (!mono_do_crash_chaining && mono_chain_signal (SIG_HANDLER_PARAMS)) + if (!mono_do_crash_chaining && mono_chain_signal (MONO_SIG_HANDLER_PARAMS)) return; mono_handle_native_sigsegv (SIGSEGV, ctx); if (mono_do_crash_chaining) { - mono_chain_signal (SIG_HANDLER_PARAMS); + mono_chain_signal (MONO_SIG_HANDLER_PARAMS); return; } } @@ -6824,7 +6696,7 @@ SIG_HANDLER_FUNC (, mono_sigsegv_signal_handler) if (fault_addr == NULL) { MonoContext mctx; - mono_arch_sigctx_to_monoctx (ctx, &mctx); + mono_sigctx_to_monoctx (ctx, &mctx); fault_addr = MONO_CONTEXT_GET_SP (&mctx); } @@ -6840,7 +6712,7 @@ SIG_HANDLER_FUNC (, mono_sigsegv_signal_handler) g_assert_not_reached (); } else { /* The original handler might not like that it is executed on an altstack... */ - if (!ji && mono_chain_signal (SIG_HANDLER_PARAMS)) + if (!ji && mono_chain_signal (MONO_SIG_HANDLER_PARAMS)) return; mono_arch_handle_altstack_exception (ctx, info->si_addr, FALSE); @@ -6848,13 +6720,13 @@ SIG_HANDLER_FUNC (, mono_sigsegv_signal_handler) #else if (!ji) { - if (!mono_do_crash_chaining && mono_chain_signal (SIG_HANDLER_PARAMS)) + if (!mono_do_crash_chaining && mono_chain_signal (MONO_SIG_HANDLER_PARAMS)) return; mono_handle_native_sigsegv (SIGSEGV, ctx); if (mono_do_crash_chaining) { - mono_chain_signal (SIG_HANDLER_PARAMS); + mono_chain_signal (MONO_SIG_HANDLER_PARAMS); return; } } @@ -6863,10 +6735,10 @@ SIG_HANDLER_FUNC (, mono_sigsegv_signal_handler) #endif } -SIG_HANDLER_FUNC (, mono_sigint_signal_handler) +MONO_SIG_HANDLER_FUNC (, mono_sigint_signal_handler) { MonoException *exc; - GET_CONTEXT; + MONO_SIG_HANDLER_GET_CONTEXT; exc = mono_get_exception_execution_engine ("Interrupted (SIGINT)."); @@ -7043,7 +6915,7 @@ mini_parse_debug_options (void) else if (!strcmp (arg, "explicit-null-checks")) debug_options.explicit_null_checks = TRUE; else if (!strcmp (arg, "gen-seq-points")) - debug_options.gen_seq_points = TRUE; + debug_options.gen_seq_points_debug_data = TRUE; else if (!strcmp (arg, "init-stacks")) debug_options.init_stacks = TRUE; else if (!strcmp (arg, "casts")) @@ -7073,10 +6945,9 @@ mini_get_debug_options (void) static gpointer mini_create_ftnptr (MonoDomain *domain, gpointer addr) { -#if !defined(__ia64__) && !defined(__ppc64__) && !defined(__powerpc64__) +#if !defined(__ia64__) && (!defined(__ppc64__) && !defined(__powerpc64__) || _CALL_ELF == 2) return addr; #else - gpointer* desc = NULL; if ((desc = g_hash_table_lookup (domain->ftnptrs_hash, addr))) @@ -7102,7 +6973,7 @@ mini_create_ftnptr (MonoDomain *domain, gpointer addr) static gpointer mini_get_addr_from_ftnptr (gpointer descr) { -#if defined(__ia64__) || defined(__ppc64__) || defined(__powerpc64__) +#if defined(__ia64__) || ((defined(__ppc64__) || defined(__powerpc64__)) && _CALL_ELF != 2) return *(gpointer*)descr; #else return descr; @@ -7122,6 +6993,7 @@ register_jit_stats (void) mono_counters_register ("Allocated vars", MONO_COUNTER_JIT | MONO_COUNTER_INT, &mono_jit_stats.allocate_var); mono_counters_register ("Code reallocs", MONO_COUNTER_JIT | MONO_COUNTER_INT, &mono_jit_stats.code_reallocs); mono_counters_register ("Allocated code size", MONO_COUNTER_JIT | MONO_COUNTER_INT, &mono_jit_stats.allocated_code_size); + mono_counters_register ("Allocated seq points size", MONO_COUNTER_JIT | MONO_COUNTER_INT, &mono_jit_stats.allocated_seq_points_size); mono_counters_register ("Inlineable methods", MONO_COUNTER_JIT | MONO_COUNTER_INT, &mono_jit_stats.inlineable_methods); mono_counters_register ("Inlined methods", MONO_COUNTER_JIT | MONO_COUNTER_INT, &mono_jit_stats.inlined_methods); mono_counters_register ("Regvars", MONO_COUNTER_JIT | MONO_COUNTER_INT, &mono_jit_stats.regvars); @@ -7136,7 +7008,6 @@ register_jit_stats (void) } static void runtime_invoke_info_free (gpointer value); -static void seq_point_info_free (gpointer value); static gint class_method_pair_equal (gconstpointer ka, gconstpointer kb) @@ -7207,19 +7078,6 @@ runtime_invoke_info_free (gpointer value) g_free (info); } -static void seq_point_info_free (gpointer value) -{ - int i = 0; - MonoSeqPointInfo* info = (MonoSeqPointInfo*)value; - - for (i = 0; i < info->len; ++i) { - SeqPoint *sp = &info->seq_points [i]; - g_free (sp->next); - } - - g_free (info); -} - static void mini_free_jit_domain_info (MonoDomain *domain) { @@ -7954,6 +7812,8 @@ mono_precompile_assembly (MonoAssembly *ass, void *user_data) method = mono_get_method (image, MONO_TOKEN_METHOD_DEF | (i + 1), NULL); if (method->flags & METHOD_ATTRIBUTE_ABSTRACT) continue; + if (method->is_generic || method->klass->generic_container) + continue; count++; if (mini_verbose > 1) {