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
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));
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);
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;
}
}