PR159: Exception handler blocks / register mixup
[cacao.git] / src / vm / jit / codegen-common.cpp
index 6408466d760f4477f118fa81ef8e2484b7890c43..81c3c75c8894580314da9387624ef9c7796fe74b 100644 (file)
@@ -1,6 +1,6 @@
 /* src/vm/jit/codegen-common.cpp - architecture independent code generator stuff
 
-   Copyright (C) 1996-2005, 2006, 2007, 2008, 2009, 2010
+   Copyright (C) 1996-2011
    CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
    Copyright (C) 2009 Theobroma Systems Ltd.
 
@@ -989,6 +989,21 @@ s4 codegen_reg_of_dst(jitdata *jd, instruction *iptr, s4 tempregnum)
        return codegen_reg_of_var(iptr->opc, VAROP(iptr->dst), tempregnum);
 }
 
+/**
+ * Fix up register locations in the case where control is transferred to an
+ * exception handler block via normal control flow (no exception).
+ */
+static void fixup_exc_handler_interface(jitdata *jd, basicblock *bptr)
+{
+       // Exception handlers have exactly 1 in-slot
+       assert(bptr->indepth == 1);
+       varinfo *var = VAR(bptr->invars[0]);
+       int32_t d = codegen_reg_of_var(0, var, REG_ITMP1_XPTR);
+       emit_load(jd, NULL, var, d);
+       // Copy the interface variable to ITMP1 (XPTR) because that's where
+       // the handler expects it.
+       emit_imove(jd->cd, d, REG_ITMP1_XPTR);
+}
 
 /**
  * Generates machine code.
@@ -996,7 +1011,7 @@ s4 codegen_reg_of_dst(jitdata *jd, instruction *iptr, s4 tempregnum)
 bool codegen_emit(jitdata *jd)
 {
        varinfo*            var;
-       builtintable_entry* bte;
+       builtintable_entry* bte = 0;
        methoddesc*         md;
        int32_t             s1, s2, /*s3,*/ d;
        int32_t             fieldtype;
@@ -1518,6 +1533,8 @@ bool codegen_emit(jitdata *jd)
                                        disp      = dseg_add_unique_address(cd, 0);
 
                                        pr = patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, disp);
+
+                                       fi = NULL;              /* Silence compiler warning */
                                }
                                else {
                                        fi        = iptr->sx.s23.s3.fmiref->p.field;
@@ -1529,6 +1546,8 @@ bool codegen_emit(jitdata *jd)
                                                patcher_add_patch_ref(jd, PATCHER_initialize_class, fi->clazz, 0);
                                                PROFILE_CYCLE_START;
                                        }
+
+                                       pr = NULL;              /* Silence compiler warning */
                                }
 
 #if defined(USES_PATCHABLE_MEMORY_BARRIER)
@@ -1570,6 +1589,9 @@ bool codegen_emit(jitdata *jd)
                                        M_DLD(d, REG_ITMP1, 0);
                                        break;
 #endif
+                               default:
+                                       // Silence compiler warning.
+                                       d = 0;
                                }
                                emit_store_dst(jd, iptr, d);
                                break;
@@ -1593,6 +1615,8 @@ bool codegen_emit(jitdata *jd)
                                        disp      = dseg_add_unique_address(cd, 0);
 
                                        pr = patcher_add_patch_ref(jd, PATCHER_get_putstatic, uf, disp);
+
+                                       fi = NULL;              /* Silence compiler warning */
                                }
                                else {
                                        fi = iptr->sx.s23.s3.fmiref->p.field;
@@ -1604,6 +1628,8 @@ bool codegen_emit(jitdata *jd)
                                                patcher_add_patch_ref(jd, PATCHER_initialize_class, fi->clazz, 0);
                                                PROFILE_CYCLE_START;
                                        }
+
+                                       pr = NULL;              /* Silence compiler warning */
                                }
 
                                // XXX X86_64: Here We had this:
@@ -1684,12 +1710,15 @@ bool codegen_emit(jitdata *jd)
                                        codegen_emit_phi_moves(jd, bptr);
                                }
 #endif
+                               if (iptr->dst.block->type == BBTYPE_EXH)
+                                       fixup_exc_handler_interface(jd, iptr->dst.block);
                                emit_br(cd, iptr->dst.block);
                                ALIGNCODENOP;
                                break;
 
                        case ICMD_JSR:        /* ... ==> ...                              */
 
+                               assert(iptr->sx.s23.s3.jsrtarget.block->type != BBTYPE_EXH);
                                emit_br(cd, iptr->sx.s23.s3.jsrtarget.block);
                                ALIGNCODENOP;
                                break;
@@ -1697,6 +1726,7 @@ bool codegen_emit(jitdata *jd)
                        case ICMD_IFNULL:     /* ..., value ==> ...                       */
                        case ICMD_IFNONNULL:
 
+                               assert(iptr->dst.block->type != BBTYPE_EXH);
                                s1 = emit_load_s1(jd, iptr, REG_ITMP1);
 #if SUPPORT_BRANCH_CONDITIONAL_ONE_INTEGER_REGISTER
                                emit_bccz(cd, iptr->dst.block, iptr->opc - ICMD_IFNULL, s1, BRANCH_OPT_NONE);
@@ -1719,6 +1749,8 @@ bool codegen_emit(jitdata *jd)
                                // register directly. Reason is, that register content is
                                // not 32-bit clean. Fix this!
 
+                               assert(iptr->dst.block->type != BBTYPE_EXH);
+
 #if SUPPORT_BRANCH_CONDITIONAL_ONE_INTEGER_REGISTER
                                if (iptr->sx.val.i == 0) {
                                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
@@ -1743,6 +1775,8 @@ bool codegen_emit(jitdata *jd)
                        case ICMD_IF_LGT:
                        case ICMD_IF_LLE:
 
+                               assert(iptr->dst.block->type != BBTYPE_EXH);
+
                                // Generate architecture specific instructions.
                                codegen_emit_instruction(jd, iptr);
                                break;
@@ -1750,6 +1784,8 @@ bool codegen_emit(jitdata *jd)
                        case ICMD_IF_ACMPEQ:  /* ..., value, value ==> ...                */
                        case ICMD_IF_ACMPNE:  /* op1 = target JavaVM pc                   */
 
+                               assert(iptr->dst.block->type != BBTYPE_EXH);
+
                                s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                                s2 = emit_load_s2(jd, iptr, REG_ITMP2);
 #if SUPPORT_BRANCH_CONDITIONAL_TWO_INTEGER_REGISTERS
@@ -1782,6 +1818,8 @@ bool codegen_emit(jitdata *jd)
                        case ICMD_IF_ICMPEQ:  /* ..., value, value ==> ...                */
                        case ICMD_IF_ICMPNE:  /* op1 = target JavaVM pc                   */
 
+                               assert(iptr->dst.block->type != BBTYPE_EXH);
+
 #if SUPPORT_BRANCH_CONDITIONAL_TWO_INTEGER_REGISTERS
                                s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                                s2 = emit_load_s2(jd, iptr, REG_ITMP2);
@@ -1803,6 +1841,8 @@ bool codegen_emit(jitdata *jd)
                        case ICMD_IF_ICMPLE:
                        case ICMD_IF_ICMPGE:
 
+                               assert(iptr->dst.block->type != BBTYPE_EXH);
+
                                s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                                s2 = emit_load_s2(jd, iptr, REG_ITMP2);
 #if SUPPORT_BRANCH_CONDITIONAL_CONDITION_REGISTER
@@ -1828,6 +1868,8 @@ bool codegen_emit(jitdata *jd)
                        case ICMD_IF_LCMPLE:
                        case ICMD_IF_LCMPGE:
 
+                               assert(iptr->dst.block->type != BBTYPE_EXH);
+
                                // Generate architecture specific instructions.
                                codegen_emit_instruction(jd, iptr);
                                break;
@@ -2263,6 +2305,9 @@ gen_method:
                }
 #endif
 
+               if (bptr->next && bptr->next->type == BBTYPE_EXH)
+                       fixup_exc_handler_interface(jd, bptr->next);
+
        } // for all basic blocks
 
        // Generate traps.