X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmini%2Fmini.c;h=4e221b9d9e0e7808eb67a0d874c4f1c28af159b9;hb=83bc684f2d1e634e50ac3725cb70d93c655eed84;hp=1d29bf0ecd6202d77cef99443f77db151e04724e;hpb=1c4ffb7584d1d340fdebaf4a2265e779b56368d4;p=mono.git diff --git a/mono/mini/mini.c b/mono/mini/mini.c index 1d29bf0ecd6..4e221b9d9e0 100644 --- a/mono/mini/mini.c +++ b/mono/mini/mini.c @@ -6,7 +6,7 @@ * Dietmar Maurer (dietmar@ximian.com) * * Copyright 2002-2003 Ximian, Inc. - * Coprygith 2003-2010 Novell, Inc. + * Copyright 2003-2010 Novell, Inc. */ #define MONO_LLVM_IN_MINI 1 @@ -99,6 +99,10 @@ guint32 mono_jit_tls_id = -1; MINI_FAST_TLS_DECLARE(mono_jit_tls); #endif +#ifndef MONO_ARCH_MONITOR_ENTER_ADJUSTMENT +#define MONO_ARCH_MONITOR_ENTER_ADJUSTMENT 1 +#endif + MonoTraceSpec *mono_jit_trace_calls = NULL; gboolean mono_break_on_exc = FALSE; gboolean mono_compile_aot = FALSE; @@ -364,6 +368,10 @@ mono_pmip (void *ip) * output. Unlike mono_pmip which returns a string, this routine * prints the value on the standard output. */ +#ifdef __GNUC__ +/* Prevent the linker from optimizing this away in embedding setups to help debugging */ + __attribute__((used)) +#endif void mono_print_method_from_ip (void *ip) { @@ -1128,6 +1136,18 @@ mono_compile_create_var_for_vreg (MonoCompile *cfg, MonoType *type, int opcode, inst->backend.is_pinvoke = 0; inst->dreg = vreg; + if (cfg->compute_gc_maps) { + if (type->byref) { + mono_mark_vreg_as_mp (cfg, vreg); + } else { + MonoType *t = mini_type_get_underlying_type (NULL, type); + if ((MONO_TYPE_ISSTRUCT (t) && inst->klass->has_references) || MONO_TYPE_IS_REFERENCE (t)) { + inst->flags |= MONO_INST_GC_TRACK; + mono_mark_vreg_as_ref (cfg, vreg); + } + } + } + cfg->varinfo [num] = inst; MONO_INIT_VARINFO (&cfg->vars [num], num); @@ -1232,6 +1252,38 @@ mono_compile_make_var_load (MonoCompile *cfg, MonoInst *dest, gssize var_index) #endif +void +mono_mark_vreg_as_ref (MonoCompile *cfg, int vreg) +{ + if (vreg >= cfg->vreg_is_ref_len) { + gboolean *tmp = cfg->vreg_is_ref; + int size = cfg->vreg_is_ref_len; + + while (vreg >= cfg->vreg_is_ref_len) + cfg->vreg_is_ref_len = cfg->vreg_is_ref_len ? cfg->vreg_is_ref_len * 2 : 32; + cfg->vreg_is_ref = mono_mempool_alloc0 (cfg->mempool, sizeof (gboolean) * cfg->vreg_is_ref_len); + if (size) + memcpy (cfg->vreg_is_ref, tmp, size * sizeof (gboolean)); + } + cfg->vreg_is_ref [vreg] = TRUE; +} + +void +mono_mark_vreg_as_mp (MonoCompile *cfg, int vreg) +{ + if (vreg >= cfg->vreg_is_mp_len) { + gboolean *tmp = cfg->vreg_is_mp; + int size = cfg->vreg_is_mp_len; + + while (vreg >= cfg->vreg_is_mp_len) + cfg->vreg_is_mp_len = cfg->vreg_is_mp_len ? cfg->vreg_is_mp_len * 2 : 32; + cfg->vreg_is_mp = mono_mempool_alloc0 (cfg->mempool, sizeof (gboolean) * cfg->vreg_is_mp_len); + if (size) + memcpy (cfg->vreg_is_mp, tmp, size * sizeof (gboolean)); + } + cfg->vreg_is_mp [vreg] = TRUE; +} + static MonoType* type_from_stack_type (MonoInst *ins) { switch (ins->type) { @@ -2462,8 +2514,11 @@ mono_get_lmf (void) if ((jit_tls = TlsGetValue (mono_jit_tls_id))) return jit_tls->lmf; - - g_assert_not_reached (); + /* + * We do not assert here because this function can be called from + * mini-gc.c on a thread that has not executed any managed code, yet + * (the thread object allocation can trigger a collection). + */ return NULL; #endif } @@ -2805,10 +2860,11 @@ mono_patch_info_hash (gconstpointer data) switch (ji->type) { case MONO_PATCH_INFO_RVA: case MONO_PATCH_INFO_LDSTR: - case MONO_PATCH_INFO_TYPE_FROM_HANDLE: case MONO_PATCH_INFO_LDTOKEN: case MONO_PATCH_INFO_DECLSEC: return (ji->type << 8) | ji->data.token->token; + case MONO_PATCH_INFO_TYPE_FROM_HANDLE: + return (ji->type << 8) | ji->data.token->token | (ji->data.token->has_context ? (gsize)ji->data.token->context.class_inst : 0); case MONO_PATCH_INFO_INTERNAL_METHOD: return (ji->type << 8) | g_str_hash (ji->data.name); case MONO_PATCH_INFO_VTABLE: @@ -3175,6 +3231,10 @@ mono_resolve_patch_target (MonoMethod *method, MonoDomain *domain, guint8 *code, target = mono_gc_get_card_table (&card_table_shift_bits, &card_table_mask); break; } + case MONO_PATCH_INFO_CASTCLASS_CACHE: { + target = mono_domain_alloc0 (domain, sizeof (gpointer)); + break; + } default: g_assert_not_reached (); } @@ -3494,6 +3554,17 @@ mono_codegen (MonoCompile *cfg) MonoBasicBlock *bb; int max_epilog_size; guint8 *code; + MonoDomain *code_domain; + + if (mono_using_xdebug) + /* + * Recent gdb versions have trouble processing symbol files containing + * overlapping address ranges, so allocate all code from the code manager + * of the root domain. (#666152). + */ + code_domain = mono_get_root_domain (); + else + code_domain = cfg->domain; #if defined(__native_client_codegen__) && defined(__native_client__) void *code_dest; @@ -3537,6 +3608,7 @@ mono_codegen (MonoCompile *cfg) /* emit code all basic blocks */ for (bb = cfg->bb_entry; bb; bb = bb->next_bb) { bb->native_offset = cfg->code_len; + bb->real_native_offset = cfg->code_len; //if ((bb == cfg->bb_entry) || !(bb->region == -1 && !bb->dfn)) mono_arch_output_basic_block (cfg, bb); bb->native_length = cfg->code_len - bb->native_offset; @@ -3580,13 +3652,17 @@ mono_codegen (MonoCompile *cfg) mono_dynamic_code_hash_insert (cfg->domain, cfg->method, cfg->dynamic_info); mono_domain_unlock (cfg->domain); - code = mono_code_manager_reserve (cfg->dynamic_info->code_mp, cfg->code_size + unwindlen); + if (mono_using_xdebug) + /* See the comment for cfg->code_domain */ + code = mono_domain_code_reserve (code_domain, cfg->code_size + unwindlen); + else + code = mono_code_manager_reserve (cfg->dynamic_info->code_mp, cfg->code_size + unwindlen); } else { guint unwindlen = 0; #ifdef MONO_ARCH_HAVE_UNWIND_TABLE unwindlen = mono_arch_unwindinfo_get_size (cfg->arch.unwindinfo); #endif - code = mono_domain_code_reserve (cfg->domain, cfg->code_size + unwindlen); + code = mono_domain_code_reserve (code_domain, cfg->code_size + unwindlen); } #if defined(__native_client_codegen__) && defined(__native_client__) nacl_allow_target_modification (TRUE); @@ -3659,9 +3735,12 @@ if (valgrind_register){ mono_arch_patch_code (cfg->method, cfg->domain, cfg->native_code, cfg->patch_info, cfg->run_cctors); if (cfg->method->dynamic) { - mono_code_manager_commit (cfg->dynamic_info->code_mp, cfg->native_code, cfg->code_size, cfg->code_len); + if (mono_using_xdebug) + mono_domain_code_commit (code_domain, cfg->native_code, cfg->code_size, cfg->code_len); + else + mono_code_manager_commit (cfg->dynamic_info->code_mp, cfg->native_code, cfg->code_size, cfg->code_len); } else { - mono_domain_code_commit (cfg->domain, cfg->native_code, cfg->code_size, cfg->code_len); + mono_domain_code_commit (code_domain, cfg->native_code, cfg->code_size, cfg->code_len); } #if defined(__native_client_codegen__) && defined(__native_client__) cfg->native_code = code_dest; @@ -3881,9 +3960,8 @@ create_jit_info (MonoCompile *cfg, MonoMethod *method_to_compile) /* * Extend the try block backwards to include parts of the previous call * instruction. - * FIXME: This is arch specific. */ - ei->try_start = (guint8*)ei->try_start - 1; + ei->try_start = (guint8*)ei->try_start - MONO_ARCH_MONITOR_ENTER_ADJUSTMENT; } tblock = cfg->cil_offset_to_bb [ec->try_offset + ec->try_len]; g_assert (tblock); @@ -4781,12 +4859,6 @@ mini_method_compile (MonoMethod *method, guint32 opts, MonoDomain *domain, gbool else InterlockedIncrement (&mono_jit_stats.methods_without_llvm); - if (cfg->verbose_level >= 2) { - char *id = mono_method_full_name (cfg->method, FALSE); - mono_disassemble_code (cfg, cfg->native_code, cfg->code_len, id + 3); - g_free (id); - } - cfg->jit_info = create_jit_info (cfg, method_to_compile); #ifdef MONO_ARCH_HAVE_LIVERANGE_OPS @@ -4804,6 +4876,12 @@ mini_method_compile (MonoMethod *method, guint32 opts, MonoDomain *domain, gbool mono_save_seq_point_info (cfg); + if (cfg->verbose_level >= 2) { + char *id = mono_method_full_name (cfg->method, FALSE); + mono_disassemble_code (cfg, cfg->native_code, cfg->code_len, id + 3); + g_free (id); + } + if (!cfg->compile_aot) { mono_domain_lock (cfg->domain); mono_jit_info_table_add (cfg->domain, cfg->jit_info); @@ -5746,20 +5824,14 @@ SIG_HANDLER_SIGNATURE (mono_sigsegv_signal_handler) } #endif - /* The hard-guard page has been hit: there is not much we can do anymore - * Print a hopefully clear message and abort. - */ if (jit_tls->stack_size && ABS ((guint8*)fault_addr - ((guint8*)jit_tls->end_of_stack - jit_tls->stack_size)) < 8192 * sizeof (gpointer)) { - const char *method; - /* we don't do much now, but we can warn the user with a useful message */ - fprintf (stderr, "Stack overflow: IP: %p, fault addr: %p\n", mono_arch_ip_from_context (ctx), (gpointer)info->si_addr); - if (ji && ji->method) - method = mono_method_full_name (ji->method, TRUE); - else - method = "Unmanaged"; - fprintf (stderr, "At %s\n", method); - _exit (1); + /* + * The hard-guard page has been hit: there is not much we can do anymore + * Print a hopefully clear message and abort. + */ + mono_handle_hard_stack_ovf (jit_tls, ji, ctx, (guint8*)info->si_addr); + 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)) @@ -5889,6 +5961,8 @@ mini_parse_debug_options (void) debug_options.no_gdb_backtrace = TRUE; else if (!strcmp (arg, "suspend-on-sigsegv")) debug_options.suspend_on_sigsegv = TRUE; + else if (!strcmp (arg, "suspend-on-unhandled")) + debug_options.suspend_on_unhandled = TRUE; else if (!strcmp (arg, "dont-free-domains")) mono_dont_free_domains = TRUE; else if (!strcmp (arg, "dyn-runtime-invoke")) @@ -5905,7 +5979,7 @@ mini_parse_debug_options (void) debug_options.better_cast_details = 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', 'dyn-runtime-invoke', 'gdb', 'explicit-null-checks', 'init-stacks'\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-unhandled', 'dyn-runtime-invoke', 'gdb', 'explicit-null-checks', 'init-stacks'\n"); exit (1); } } @@ -6096,6 +6170,7 @@ mini_init (const char *filename, const char *runtime_version) callbacks.create_ftnptr = mini_create_ftnptr; callbacks.get_addr_from_ftnptr = mini_get_addr_from_ftnptr; callbacks.get_runtime_build_info = mono_get_runtime_build_info; + callbacks.set_cast_details = mono_set_cast_details; #ifdef MONO_ARCH_HAVE_IMT if (mono_use_imt) { @@ -6115,8 +6190,6 @@ mini_init (const char *filename, const char *runtime_version) mono_unwind_init (); - mini_gc_init (); - if (getenv ("MONO_XDEBUG")) { char *xdebug_opts = getenv ("MONO_XDEBUG"); mono_xdebug_init (xdebug_opts); @@ -6221,6 +6294,9 @@ mini_init (const char *filename, const char *runtime_version) mono_icall_init (); + /* This should come after mono_init () too */ + mini_gc_init (); + mono_add_internal_call ("System.Diagnostics.StackFrame::get_frame_info", ves_icall_get_frame_info); mono_add_internal_call ("System.Diagnostics.StackTrace::get_trace",