#include <mono/metadata/monitor.h>
#include <mono/metadata/security-manager.h>
#include <mono/metadata/threads-types.h>
+#include <mono/metadata/rawbuffer.h>
#include <mono/utils/mono-math.h>
#include <mono/utils/mono-compiler.h>
#include <mono/os/gc_wrapper.h>
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;
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;
}
}
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;
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;
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;
}
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
MonoMethodSignature *res;
int i;
- EnterCriticalSection (&jit_mutex);
+ mono_jit_lock ();
if (!sighash) {
sighash = g_hash_table_new (NULL, NULL);
}
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;
}
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;
}
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;
}
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;
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);
}
/* 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));
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);
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);
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;
}
{
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;
}
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;
}
}
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 ();
#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 &&
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);
}
}
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 ();
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 ());
+ }
}
}