X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmini%2Fmini.c;h=1e0dfc46dedcc1314e1e522d3baff3251ea016d8;hb=64421feaa7bf7703f7e44c554d3e355b8c5eeac6;hp=407b52b9c00f0600015c97e91ee232e017d9a84a;hpb=29f95a7d2392761ca8aa5a0d45f598241b40f947;p=mono.git diff --git a/mono/mini/mini.c b/mono/mini/mini.c index 407b52b9c00..1e0dfc46ded 100644 --- a/mono/mini/mini.c +++ b/mono/mini/mini.c @@ -49,6 +49,7 @@ #include #include #include +#include #include #include #include @@ -102,6 +103,8 @@ gboolean mono_use_security_manager = FALSE; static int mini_verbose = 0; +#define mono_jit_lock() EnterCriticalSection (&jit_mutex) +#define mono_jit_unlock() LeaveCriticalSection (&jit_mutex) static CRITICAL_SECTION jit_mutex; static GHashTable *class_init_hash_addr = NULL; @@ -255,9 +258,9 @@ void *mono_global_codeman_reserve (int size) return mono_code_manager_reserve (global_codeman, size); } else { - EnterCriticalSection (&jit_mutex); + mono_jit_lock (); ptr = mono_code_manager_reserve (global_codeman, size); - LeaveCriticalSection (&jit_mutex); + mono_jit_unlock (); return ptr; } } @@ -849,7 +852,7 @@ df_visit (MonoBasicBlock *start, int *dfn, MonoBasicBlock **array) int i; array [*dfn] = start; - /*g_print ("visit %d at %p\n", *dfn, start->cil_code);*/ + /*g_print ("visit %d at %p (BB%ld)\n", *dfn, start->cil_code, start->block_num);*/ for (i = 0; i < start->out_count; ++i) { if (start->out_bb [i]->dfn) continue; @@ -1799,6 +1802,9 @@ handle_stack_args (MonoCompile *cfg, MonoBasicBlock *bb, MonoInst **sp, int coun found = FALSE; for (i = 0; i < bb->out_count; ++i) { outb = bb->out_bb [i]; + /* exception handlers are linked, but they should not be considered for stack args */ + if (outb->flags & BB_EXCEPTION_HANDLER) + continue; //g_print (" %d", outb->block_num); if (outb->in_stack) { found = TRUE; @@ -1832,8 +1838,14 @@ handle_stack_args (MonoCompile *cfg, MonoBasicBlock *bb, MonoInst **sp, int coun for (i = 0; i < bb->out_count; ++i) { outb = bb->out_bb [i]; - if (outb->in_scount) + /* exception handlers are linked, but they should not be considered for stack args */ + if (outb->flags & BB_EXCEPTION_HANDLER) + continue; + if (outb->in_scount) { + if (outb->in_scount != bb->out_scount) + G_BREAKPOINT (); continue; /* check they are the same locals */ + } outb->in_scount = count; outb->in_stack = bb->out_stack; } @@ -1866,6 +1878,11 @@ handle_stack_args (MonoCompile *cfg, MonoBasicBlock *bb, MonoInst **sp, int coun found = FALSE; while (bindex < bb->out_count) { outb = bb->out_bb [bindex]; + /* exception handlers are linked, but they should not be considered for stack args */ + if (outb->flags & BB_EXCEPTION_HANDLER) { + bindex++; + continue; + } if (outb->in_stack != locals) { /* * Instead of storing sp [i] to locals [i], we need to store @@ -2338,7 +2355,7 @@ mono_get_element_address_signature (int arity) MonoMethodSignature *res; int i; - EnterCriticalSection (&jit_mutex); + mono_jit_lock (); if (!sighash) { sighash = g_hash_table_new (NULL, NULL); } @@ -2362,7 +2379,7 @@ mono_get_element_address_signature (int arity) res->ret = &mono_defaults.int_class->byval_arg; g_hash_table_insert (sighash, GINT_TO_POINTER (arity), res); - LeaveCriticalSection (&jit_mutex); + mono_jit_unlock (); return res; } @@ -2374,12 +2391,12 @@ mono_get_array_new_va_signature (int arity) MonoMethodSignature *res; int i; - EnterCriticalSection (&jit_mutex); + mono_jit_lock (); if (!sighash) { sighash = g_hash_table_new (NULL, NULL); } else if ((res = g_hash_table_lookup (sighash, GINT_TO_POINTER (arity)))) { - LeaveCriticalSection (&jit_mutex); + mono_jit_unlock (); return res; } @@ -2398,7 +2415,7 @@ mono_get_array_new_va_signature (int arity) res->ret = &mono_defaults.int_class->byval_arg; g_hash_table_insert (sighash, GINT_TO_POINTER (arity), res); - LeaveCriticalSection (&jit_mutex); + mono_jit_unlock (); return res; } @@ -2590,9 +2607,9 @@ handle_array_new (MonoCompile *cfg, MonoBasicBlock *bblock, int rank, MonoInst * name = g_strdup (icall_name); info = mono_register_jit_icall (mono_array_new_va, name, esig, FALSE); - EnterCriticalSection (&jit_mutex); + mono_jit_lock (); g_hash_table_insert (jit_icall_name_hash, name, name); - LeaveCriticalSection (&jit_mutex); + mono_jit_unlock (); } cfg->flags |= MONO_CFG_HAS_VARARGS; @@ -2778,9 +2795,9 @@ mini_get_ldelema_ins (MonoCompile *cfg, MonoBasicBlock *bblock, MonoMethod *cmet name = g_strdup (icall_name); info = mono_register_jit_icall (ves_array_element_address, name, esig, FALSE); - EnterCriticalSection (&jit_mutex); + mono_jit_lock (); g_hash_table_insert (jit_icall_name_hash, name, name); - LeaveCriticalSection (&jit_mutex); + mono_jit_unlock (); } temp = mono_emit_native_call (cfg, bblock, mono_icall_get_wrapper (info), info->sig, sp, ip, FALSE, FALSE); @@ -3327,19 +3344,30 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b } /* handle exception clauses */ for (i = 0; i < header->num_clauses; ++i) { - //unsigned char *p = ip; + MonoBasicBlock *try_bb; MonoExceptionClause *clause = &header->clauses [i]; - GET_BBLOCK (cfg, bbhash, tblock, ip + clause->try_offset); - tblock->real_offset = clause->try_offset; + GET_BBLOCK (cfg, bbhash, try_bb, ip + clause->try_offset); + try_bb->real_offset = clause->try_offset; GET_BBLOCK (cfg, bbhash, tblock, ip + clause->handler_offset); tblock->real_offset = clause->handler_offset; + tblock->flags |= BB_EXCEPTION_HANDLER; + + link_bblock (cfg, try_bb, tblock); + + if (*(ip + clause->handler_offset) == CEE_POP) + tblock->flags |= BB_EXCEPTION_DEAD_OBJ; if (clause->flags == MONO_EXCEPTION_CLAUSE_FINALLY || clause->flags == MONO_EXCEPTION_CLAUSE_FILTER) { MONO_INST_NEW (cfg, ins, OP_START_HANDLER); MONO_ADD_INS (tblock, ins); + + /* todo: is a fault block unsafe to optimize? */ + if (clause->flags == MONO_EXCEPTION_CLAUSE_FAULT) + tblock->flags |= BB_EXCEPTION_UNSAFE; } + /*g_print ("clause try IL_%04x to IL_%04x handler %d at IL_%04x to IL_%04x\n", clause->try_offset, clause->try_offset + clause->try_len, clause->flags, clause->handler_offset, clause->handler_offset + clause->handler_len); while (p < end) { g_print ("%s", mono_disasm_code_one (NULL, method, p, &p)); @@ -5138,6 +5166,7 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b ins->cil_code = ip - 1; MONO_ADD_INS (bblock, ins); sp = stack_start; + link_bblock (cfg, bblock, end_bblock); start_new_bblock = 1; mono_get_got_var (cfg); @@ -6543,6 +6572,8 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b handler_offset = clause->handler_offset; } + bblock->flags |= BB_EXCEPTION_UNSAFE; + g_assert (handler_offset != -1); NEW_TEMPLOAD (cfg, load, mono_find_exvar_for_offset (cfg, handler_offset)->inst_c0); @@ -6953,11 +6984,11 @@ mono_create_class_init_trampoline (MonoVTable *vtable) vtable, ptr); mono_domain_unlock (vtable->domain); - EnterCriticalSection (&jit_mutex); + mono_jit_lock (); if (!class_init_hash_addr) class_init_hash_addr = g_hash_table_new (NULL, NULL); g_hash_table_insert (class_init_hash_addr, ptr, vtable); - LeaveCriticalSection (&jit_mutex); + mono_jit_unlock (); return ptr; } @@ -7111,12 +7142,12 @@ mono_find_class_init_trampoline_by_addr (gconstpointer addr) { MonoVTable *res; - EnterCriticalSection (&jit_mutex); + mono_jit_lock (); if (class_init_hash_addr) res = g_hash_table_lookup (class_init_hash_addr, addr); else res = NULL; - LeaveCriticalSection (&jit_mutex); + mono_jit_unlock (); return res; } @@ -7660,13 +7691,13 @@ mini_thread_cleanup (MonoThread *thread) if (jit_tls) { mono_arch_free_jit_tls_data (jit_tls); - g_free (jit_tls->first_lmf); - g_free (jit_tls); - thread->jit_data = NULL; #ifdef MONO_ARCH_SIGSEGV_ON_ALTSTACK mono_free_altstack (jit_tls); #endif + g_free (jit_tls->first_lmf); + g_free (jit_tls); + thread->jit_data = NULL; } } @@ -9472,7 +9503,7 @@ mono_jit_compile_method_inner (MonoMethod *method, MonoDomain *target_domain) method = mono_get_inflated_method (method); #ifdef MONO_USE_AOT_COMPILER - if (!mono_compile_aot && (opt & MONO_OPT_AOT)) { + if (!mono_compile_aot && (opt & MONO_OPT_AOT) && !(mono_profiler_get_events () & MONO_PROFILE_JIT_COMPILATION)) { MonoJitInfo *info; MonoDomain *domain = mono_domain_get (); @@ -9820,6 +9851,19 @@ SIG_HANDLER_SIGNATURE (sigsegv_signal_handler) #endif GET_CONTEXT +#ifdef MONO_ARCH_USE_SIGACTION + if (debug_options.collect_pagefault_stats) { + if (mono_raw_buffer_is_pagefault (info->si_addr)) { + mono_raw_buffer_handle_pagefault (info->si_addr); + return; + } + if (mono_aot_is_pagefault (info->si_addr)) { + mono_aot_handle_pagefault (info->si_addr); + return; + } + } +#endif + #ifdef MONO_ARCH_SIGSEGV_ON_ALTSTACK /* Can't allocate memory using Boehm GC on altstack */ if (jit_tls->stack_size && @@ -10098,9 +10142,11 @@ mini_parse_debug_options (void) debug_options.keep_delegates = TRUE; else if (!strcmp (arg, "abort-on-sigsegv")) debug_options.abort_on_sigsegv = TRUE; + else if (!strcmp (arg, "collect-pagefault-stats")) + debug_options.collect_pagefault_stats = TRUE; else { fprintf (stderr, "Invalid option for the MONO_DEBUG env variable: %s\n", arg); - fprintf (stderr, "Available options: 'handle-sigint', 'keep-delegates', 'abort-on-sigsegv'\n"); + fprintf (stderr, "Available options: 'handle-sigint', 'keep-delegates', 'abort-on-sigsegv', 'collect-pagefault-stats'\n"); exit (1); } } @@ -10169,6 +10215,11 @@ mini_init (const char *filename) mono_install_get_cached_class_info (mono_aot_get_cached_class_info); mono_install_jit_info_find_in_aot (mono_aot_find_jit_info); + if (debug_options.collect_pagefault_stats) { + mono_raw_buffer_set_make_unreadable (TRUE); + mono_aot_set_make_unreadable (TRUE); + } + domain = mono_init_from_assembly (filename, filename); mono_icall_init (); @@ -10356,6 +10407,10 @@ print_jit_stats (void) g_print ("LinkDemand (aptc) : %ld\n", mono_jit_stats.cas_linkdemand_aptc); g_print ("Demand (code gen) : %ld\n", mono_jit_stats.cas_demand_generation); } + if (debug_options.collect_pagefault_stats) { + g_print ("Metadata pagefaults : %d\n", mono_raw_buffer_get_n_pagefaults ()); + g_print ("AOT pagefaults : %d\n", mono_aot_get_n_pagefaults ()); + } } }