Tue Oct 4 20:23:25 CEST 2005 Paolo Molaro <lupus@ximian.com>
[mono.git] / mono / mini / mini.c
index a534be78af872524606246da0b386a424259597b..1e0dfc46dedcc1314e1e522d3baff3251ea016d8 100644 (file)
@@ -1802,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;
@@ -1835,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;
        }
@@ -1869,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
@@ -3336,15 +3350,24 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b
                        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));
@@ -6549,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);
@@ -7666,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;
        }
 }