X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmini%2Fmini.c;h=8f7772f061c59122749d858f932f804c045f139d;hb=086141c0bd604eae185495c95a88ee67edb1ed1f;hp=9ccfb86c19d8ce7f8231d88fdb6d47cf5b0dfc67;hpb=3555ee6b163086734f4139162f5869912002df1a;p=mono.git diff --git a/mono/mini/mini.c b/mono/mini/mini.c index 9ccfb86c19d..8f7772f061c 100644 --- a/mono/mini/mini.c +++ b/mono/mini/mini.c @@ -21,9 +21,7 @@ #include #endif -#ifdef HAVE_VALGRIND_MEMCHECK_H -#include -#endif +#include #include #include @@ -163,17 +161,13 @@ gboolean mono_dont_free_global_codeman; gboolean mono_running_on_valgrind (void) { -#ifdef HAVE_VALGRIND_MEMCHECK_H - if (RUNNING_ON_VALGRIND){ + if (RUNNING_ON_VALGRIND){ #ifdef VALGRIND_JIT_REGISTER_MAP - valgrind_register = TRUE; + valgrind_register = TRUE; #endif - return TRUE; - } else - return FALSE; -#else + return TRUE; + } else return FALSE; -#endif } typedef struct { @@ -655,7 +649,9 @@ mono_type_to_load_membase (MonoCompile *cfg, MonoType *type) if (type->byref) return OP_LOAD_MEMBASE; - switch (mono_type_get_underlying_type (type)->type) { + type = mono_type_get_underlying_type (type); + + switch (type->type) { case MONO_TYPE_I1: return OP_LOADI1_MEMBASE; case MONO_TYPE_U1: @@ -1301,6 +1297,23 @@ mini_method_verify (MonoCompile *cfg, MonoMethod *method) return FALSE; } +/*Returns true is something went wrong*/ +static gboolean +mono_compile_is_broken (MonoCompile *cfg) +{ + MonoMethod *method = cfg->method; + MonoMethod *method_definition = method; + gboolean dont_verify = mini_assembly_can_skip_verification (cfg->domain, method); + dont_verify |= method->klass->image->assembly->corlib_internal; + + while (method_definition->is_inflated) { + MonoMethodInflated *imethod = (MonoMethodInflated *) method_definition; + method_definition = imethod->declaring; + } + + return !dont_verify && mini_method_verify (cfg, method_definition); +} + static void create_helper_signature (void) { @@ -2841,6 +2854,15 @@ mono_resolve_patch_target (MonoMethod *method, MonoDomain *domain, guint8 *code, return (gpointer)target; } +void +mono_add_seq_point (MonoCompile *cfg, MonoBasicBlock *bb, MonoInst *ins, int native_offset) +{ + ins->inst_offset = native_offset; + g_ptr_array_add (cfg->seq_points, ins); + bb->seq_points = g_slist_prepend_mempool (cfg->mempool, bb->seq_points, ins); + bb->last_seq_point = ins; +} + static void mono_compile_create_vars (MonoCompile *cfg) { @@ -3006,6 +3028,93 @@ mono_postprocess_patches (MonoCompile *cfg) } } +static void +mono_save_seq_point_info (MonoCompile *cfg) +{ + MonoBasicBlock *bb, *in_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 - MONO_ZERO_LEN_ARRAY) * 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; + + /* 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->flags & MONO_INST_SINGLE_STEP_LOC)) + 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 */ + /* + * FIXME: What if the prev bb doesn't have a seq point, but + * one of its predecessors has ? + */ + for (i = 0; i < bb->in_count; ++i) { + in_bb = bb->in_bb [i]; + + if (in_bb->last_seq_point) + next [in_bb->last_seq_point->backend.size] = g_slist_append (next [in_bb->last_seq_point->backend.size], GUINT_TO_POINTER (ins->backend.size)); + } + } + + last = ins; + } + } + + for (i = 0; i < cfg->seq_points->len; ++i) { + SeqPoint *sp = &info->seq_points [i]; + GSList *l; + int j; + + sp->next_len = g_slist_length (next [i]); + sp->next = g_new (int, sp->next_len); + j = 0; + for (l = next [i]; l; l = l->next) + sp->next [j ++] = GPOINTER_TO_UINT (l->data); + g_slist_free (next [i]); + } + g_free (next); + + cfg->seq_point_info = info; + + // FIXME: dynamic methods + mono_domain_lock (domain); + 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) { @@ -3260,6 +3369,9 @@ mini_method_compile (MonoMethod *method, guint32 opts, MonoDomain *domain, gbool cfg->compile_llvm = try_llvm; cfg->token_info_hash = g_hash_table_new (NULL, NULL); + if (cfg->gen_seq_points) + cfg->seq_points = g_ptr_array_new (); + if (cfg->compile_aot && !try_generic_shared && (method->is_generic || method->klass->generic_container)) { cfg->exception_type = MONO_EXCEPTION_GENERIC_SHARING_FAILED; return cfg; @@ -3275,21 +3387,23 @@ mini_method_compile (MonoMethod *method, guint32 opts, MonoDomain *domain, gbool } cfg->method_to_register = method_to_register; - /* No way to obtain the location info for 'this' */ - if (try_generic_shared) { - cfg->exception_message = g_strdup ("gshared"); - cfg->disable_llvm = TRUE; - } + if (cfg->compile_llvm) { + /* No way to obtain the location info for 'this' */ + if (try_generic_shared) { + cfg->exception_message = g_strdup ("gshared"); + cfg->disable_llvm = TRUE; + } - if (cfg->method->save_lmf) { - cfg->exception_message = g_strdup ("lmf"); - cfg->disable_llvm = TRUE; - } + if (cfg->method->save_lmf) { + cfg->exception_message = g_strdup ("lmf"); + cfg->disable_llvm = TRUE; + } - /* FIXME: */ - if (cfg->method->dynamic) { - cfg->exception_message = g_strdup ("dynamic."); - cfg->disable_llvm = TRUE; + /* FIXME: */ + if (cfg->method->dynamic) { + cfg->exception_message = g_strdup ("dynamic."); + cfg->disable_llvm = TRUE; + } } header = mono_method_get_header (method_to_compile); @@ -3474,6 +3588,10 @@ mini_method_compile (MonoMethod *method, guint32 opts, MonoDomain *domain, gbool */ //cfg->enable_extended_bblocks = TRUE; + /*We must verify the method before doing any IR generation as mono_compile_create_vars can assert.*/ + if (mono_compile_is_broken (cfg)) + return cfg; + /* * create MonoInst* which represents arguments and local variables */ @@ -4051,12 +4169,7 @@ mini_method_compile (MonoMethod *method, guint32 opts, MonoDomain *domain, gbool mini_gc_create_gc_map (cfg); - if (cfg->seq_points) { - // FIXME: dynamic methods - mono_domain_lock (domain); - g_hash_table_insert (domain_jit_info (domain)->seq_points, method_to_register, cfg->seq_points); - mono_domain_unlock (domain); - } + mono_save_seq_point_info (cfg); if (!cfg->compile_aot) { mono_domain_lock (cfg->domain); @@ -4991,6 +5104,8 @@ mini_parse_debug_options (void) debug_options.gdb = TRUE; 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; else { fprintf (stderr, "Invalid option for the MONO_DEBUG env variable: %s\n", arg); fprintf (stderr, "Available options: 'handle-sigint', 'keep-delegates', 'collect-pagefault-stats', 'break-on-unverified', 'no-gdb-backtrace', 'dont-free-domains', 'suspend-on-sigsegv', 'dyn-runtime-invoke', 'gdb', 'explicit-null-checks'\n"); @@ -5057,7 +5172,7 @@ mini_create_jit_domain_info (MonoDomain *domain) info->delegate_trampoline_hash = g_hash_table_new (mono_aligned_addr_hash, NULL); info->llvm_vcall_trampoline_hash = g_hash_table_new (mono_aligned_addr_hash, NULL); info->runtime_invoke_hash = g_hash_table_new_full (mono_aligned_addr_hash, NULL, NULL, runtime_invoke_info_free); - info->seq_points = g_hash_table_new (mono_aligned_addr_hash, NULL); + info->seq_points = g_hash_table_new_full (mono_aligned_addr_hash, NULL, NULL, g_free); info->arch_seq_points = g_hash_table_new (mono_aligned_addr_hash, NULL); domain->runtime_info = info; @@ -5116,6 +5231,8 @@ mini_free_jit_domain_info (MonoDomain *domain) g_hash_table_destroy (info->static_rgctx_trampoline_hash); g_hash_table_destroy (info->llvm_vcall_trampoline_hash); g_hash_table_destroy (info->runtime_invoke_hash); + g_hash_table_destroy (info->seq_points); + g_hash_table_destroy (info->arch_seq_points); if (info->agent_info) mono_debugger_agent_free_domain_info (domain); @@ -5694,9 +5811,9 @@ char* mono_get_runtime_build_info (void) { if (mono_build_date) - return g_strdup_printf ("%s %s", FULL_VERSION, mono_build_date); + return g_strdup_printf ("%s (%s %s)", VERSION, FULL_VERSION, mono_build_date); else - return g_strdup_printf ("%s", FULL_VERSION); + return g_strdup_printf ("%s (%s)", VERSION, FULL_VERSION); } static void