Made Self Verification mode's memory interface less intrusive.
diff --git a/vm/compiler/codegen/arm/CodegenDriver.c b/vm/compiler/codegen/arm/CodegenDriver.c
index b0e16b8..1bf80cb 100644
--- a/vm/compiler/codegen/arm/CodegenDriver.c
+++ b/vm/compiler/codegen/arm/CodegenDriver.c
@@ -208,411 +208,37 @@
 }
 
 #if defined(WITH_SELF_VERIFICATION)
-/*
- * The following are used to keep compiled loads and stores from modifying
- * memory during self verification mode.
- *
- * Stores do not modify memory. Instead, the address and value pair are stored
- * into heapSpace. Addresses within heapSpace are unique. For accesses smaller
- * than a word, the word containing the address is loaded first before being
- * updated.
- *
- * Loads check heapSpace first and return data from there if an entry exists.
- * Otherwise, data is loaded from memory as usual.
- */
-
-/* Decode contents of heapArgSpace to determine addr to load from */
-static void selfVerificationLoadDecode(HeapArgSpace* heapArgSpace, int* addr)
+static void selfVerificationBranchInsert(LIR *currentLIR, ArmOpCode opCode,
+                          int dest, int src1)
 {
-    int reg = heapArgSpace->regMap & 0xFF;
-    if (!FPREG(reg)) {
-        assert(reg < 16);
-        *addr = heapArgSpace->coreRegs[reg];
-    } else {
-        assert(!DOUBLEREG(reg));
-        *addr = heapArgSpace->fpRegs[(reg & FP_REG_MASK)];
-    }
+     ArmLIR *insn = dvmCompilerNew(sizeof(ArmLIR), true);
+     insn->opCode = opCode;
+     insn->operands[0] = dest;
+     insn->operands[1] = src1;
+     setupResourceMasks(insn);
+     dvmCompilerInsertLIRBefore(currentLIR, (LIR *) insn);
 }
 
-/* Decode contents of heapArgSpace to determine reg to load into */
-static void selfVerificationLoadDecodeData(HeapArgSpace* heapArgSpace,
-                                           int data, int reg)
+static void selfVerificationBranchInsertPass(CompilationUnit *cUnit)
 {
-    if (!FPREG(reg)) {
-        assert(reg < 16);
-        heapArgSpace->coreRegs[reg] = data;
-    } else {
-        assert(!DOUBLEREG(reg));
-        heapArgSpace->fpRegs[(reg & FP_REG_MASK)] = data;
-    }
-}
+    ArmLIR *thisLIR;
+    ArmLIR *branchLIR = dvmCompilerNew(sizeof(ArmLIR), true);
+    TemplateOpCode opCode = TEMPLATE_MEM_OP_DECODE;
 
-static void selfVerificationLoad(InterpState* interpState)
-{
-    Thread *self = dvmThreadSelf();
-    ShadowHeap *heapSpacePtr;
-    ShadowSpace *shadowSpace = self->shadowSpace;
-    HeapArgSpace *heapArgSpace = &(interpState->heapArgSpace);
-
-    int addr, data;
-    selfVerificationLoadDecode(heapArgSpace, &addr);
-
-    for (heapSpacePtr = shadowSpace->heapSpace;
-         heapSpacePtr != shadowSpace->heapSpaceTail; heapSpacePtr++) {
-        if (heapSpacePtr->addr == addr) {
-            data = heapSpacePtr->data;
-            break;
+    for (thisLIR = (ArmLIR *) cUnit->firstLIRInsn;
+         thisLIR != (ArmLIR *) cUnit->lastLIRInsn;
+         thisLIR = NEXT_LIR(thisLIR)) {
+        if (thisLIR->branchInsertSV) {
+            /* Branch to mem op decode template */
+            selfVerificationBranchInsert((LIR *) thisLIR, kThumbBlx1,
+                       (int) gDvmJit.codeCache + templateEntryOffsets[opCode],
+                       (int) gDvmJit.codeCache + templateEntryOffsets[opCode]);
+            selfVerificationBranchInsert((LIR *) thisLIR, kThumbBlx2,
+                       (int) gDvmJit.codeCache + templateEntryOffsets[opCode],
+                       (int) gDvmJit.codeCache + templateEntryOffsets[opCode]);
         }
     }
-
-    if (heapSpacePtr == shadowSpace->heapSpaceTail)
-        data = *((unsigned int*) addr);
-
-    int reg = (heapArgSpace->regMap >> 8) & 0xFF;
-
-    // LOGD("*** HEAP LOAD: Reg:%d Addr: 0x%x Data: 0x%x", reg, addr, data);
-
-    selfVerificationLoadDecodeData(heapArgSpace, data, reg);
 }
-
-static void selfVerificationLoadByte(InterpState* interpState)
-{
-    Thread *self = dvmThreadSelf();
-    ShadowHeap *heapSpacePtr;
-    ShadowSpace *shadowSpace = self->shadowSpace;
-    HeapArgSpace *heapArgSpace = &(interpState->heapArgSpace);
-
-    int addr, data;
-    selfVerificationLoadDecode(heapArgSpace, &addr);
-
-    int maskedAddr = addr & 0xFFFFFFFC;
-    int alignment = addr & 0x3;
-
-    for (heapSpacePtr = shadowSpace->heapSpace;
-         heapSpacePtr != shadowSpace->heapSpaceTail; heapSpacePtr++) {
-        if (heapSpacePtr->addr == maskedAddr) {
-            addr = ((unsigned int) &(heapSpacePtr->data)) | alignment;
-            data = *((unsigned char*) addr);
-            break;
-        }
-    }
-
-    if (heapSpacePtr == shadowSpace->heapSpaceTail)
-        data = *((unsigned char*) addr);
-
-    //LOGD("*** HEAP LOAD BYTE: Addr: 0x%x Data: 0x%x", addr, data);
-
-    int reg = (heapArgSpace->regMap >> 8) & 0xFF;
-    selfVerificationLoadDecodeData(heapArgSpace, data, reg);
-}
-
-static void selfVerificationLoadHalfword(InterpState* interpState)
-{
-    Thread *self = dvmThreadSelf();
-    ShadowHeap *heapSpacePtr;
-    ShadowSpace *shadowSpace = self->shadowSpace;
-    HeapArgSpace *heapArgSpace = &(interpState->heapArgSpace);
-
-    int addr, data;
-    selfVerificationLoadDecode(heapArgSpace, &addr);
-
-    int maskedAddr = addr & 0xFFFFFFFC;
-    int alignment = addr & 0x2;
-
-    for (heapSpacePtr = shadowSpace->heapSpace;
-         heapSpacePtr != shadowSpace->heapSpaceTail; heapSpacePtr++) {
-        if (heapSpacePtr->addr == maskedAddr) {
-            addr = ((unsigned int) &(heapSpacePtr->data)) | alignment;
-            data = *((unsigned short*) addr);
-            break;
-        }
-    }
-
-    if (heapSpacePtr == shadowSpace->heapSpaceTail)
-        data = *((unsigned short*) addr);
-
-    //LOGD("*** HEAP LOAD kHalfWord: Addr: 0x%x Data: 0x%x", addr, data);
-
-    int reg = (heapArgSpace->regMap >> 8) & 0xFF;
-    selfVerificationLoadDecodeData(heapArgSpace, data, reg);
-}
-
-static void selfVerificationLoadSignedByte(InterpState* interpState)
-{
-    Thread *self = dvmThreadSelf();
-    ShadowHeap* heapSpacePtr;
-    ShadowSpace* shadowSpace = self->shadowSpace;
-    HeapArgSpace *heapArgSpace = &(interpState->heapArgSpace);
-
-    int addr, data;
-    selfVerificationLoadDecode(heapArgSpace, &addr);
-
-    int maskedAddr = addr & 0xFFFFFFFC;
-    int alignment = addr & 0x3;
-
-    for (heapSpacePtr = shadowSpace->heapSpace;
-         heapSpacePtr != shadowSpace->heapSpaceTail; heapSpacePtr++) {
-        if (heapSpacePtr->addr == maskedAddr) {
-            addr = ((unsigned int) &(heapSpacePtr->data)) | alignment;
-            data = *((signed char*) addr);
-            break;
-        }
-    }
-
-    if (heapSpacePtr == shadowSpace->heapSpaceTail)
-        data = *((signed char*) addr);
-
-    //LOGD("*** HEAP LOAD SIGNED BYTE: Addr: 0x%x Data: 0x%x", addr, data);
-
-    int reg = (heapArgSpace->regMap >> 8) & 0xFF;
-    selfVerificationLoadDecodeData(heapArgSpace, data, reg);
-}
-
-static void selfVerificationLoadSignedHalfword(InterpState* interpState)
-{
-    Thread *self = dvmThreadSelf();
-    ShadowHeap* heapSpacePtr;
-    ShadowSpace* shadowSpace = self->shadowSpace;
-    HeapArgSpace *heapArgSpace = &(interpState->heapArgSpace);
-
-    int addr, data;
-    selfVerificationLoadDecode(heapArgSpace, &addr);
-
-    int maskedAddr = addr & 0xFFFFFFFC;
-    int alignment = addr & 0x2;
-
-    for (heapSpacePtr = shadowSpace->heapSpace;
-         heapSpacePtr != shadowSpace->heapSpaceTail; heapSpacePtr++) {
-        if (heapSpacePtr->addr == maskedAddr) {
-            addr = ((unsigned int) &(heapSpacePtr->data)) | alignment;
-            data = *((signed short*) addr);
-            break;
-        }
-    }
-
-    if (heapSpacePtr == shadowSpace->heapSpaceTail)
-        data = *((signed short*) addr);
-
-    //LOGD("*** HEAP LOAD SIGNED kHalfWord: Addr: 0x%x Data: 0x%x", addr, data);
-
-    int reg = (heapArgSpace->regMap >> 8) & 0xFF;
-    selfVerificationLoadDecodeData(heapArgSpace, data, reg);
-}
-
-static void selfVerificationLoadDoubleword(InterpState* interpState)
-{
-    Thread *self = dvmThreadSelf();
-    ShadowHeap* heapSpacePtr;
-    ShadowSpace* shadowSpace = self->shadowSpace;
-    HeapArgSpace *heapArgSpace = &(interpState->heapArgSpace);
-
-    int addr;
-    selfVerificationLoadDecode(heapArgSpace, &addr);
-
-    int addr2 = addr+4;
-    unsigned int data = *((unsigned int*) addr);
-    unsigned int data2 = *((unsigned int*) addr2);
-
-    for (heapSpacePtr = shadowSpace->heapSpace;
-         heapSpacePtr != shadowSpace->heapSpaceTail; heapSpacePtr++) {
-        if (heapSpacePtr->addr == addr) {
-            data = heapSpacePtr->data;
-        } else if (heapSpacePtr->addr == addr2) {
-            data2 = heapSpacePtr->data;
-        }
-    }
-
-    // LOGD("*** HEAP LOAD DOUBLEWORD: Addr: 0x%x Data: 0x%x Data2: 0x%x",
-    //    addr, data, data2);
-
-    int reg = (heapArgSpace->regMap >> 8) & 0xFF;
-    int reg2 = (heapArgSpace->regMap >> 16) & 0xFF;
-    selfVerificationLoadDecodeData(heapArgSpace, data, reg);
-    selfVerificationLoadDecodeData(heapArgSpace, data2, reg2);
-}
-
-/* Decode contents of heapArgSpace to determine arguments to store. */
-static void selfVerificationStoreDecode(HeapArgSpace* heapArgSpace,
-                                        int* value, int reg)
-{
-    if (!FPREG(reg)) {
-        assert(reg < 16);
-        *value = heapArgSpace->coreRegs[reg];
-    } else {
-        assert(!DOUBLEREG(reg));
-        *value = heapArgSpace->fpRegs[(reg & FP_REG_MASK)];
-    }
-}
-
-static void selfVerificationStore(InterpState* interpState)
-{
-    Thread *self = dvmThreadSelf();
-    ShadowHeap *heapSpacePtr;
-    ShadowSpace *shadowSpace = self->shadowSpace;
-    HeapArgSpace *heapArgSpace = &(interpState->heapArgSpace);
-
-    int addr, data;
-    int reg0 = heapArgSpace->regMap & 0xFF;
-    int reg1 = (heapArgSpace->regMap >> 8) & 0xFF;
-    selfVerificationStoreDecode(heapArgSpace, &addr, reg0);
-    selfVerificationStoreDecode(heapArgSpace, &data, reg1);
-
-    //LOGD("*** HEAP STORE: Addr: 0x%x Data: 0x%x", addr, data);
-
-    for (heapSpacePtr = shadowSpace->heapSpace;
-         heapSpacePtr != shadowSpace->heapSpaceTail; heapSpacePtr++) {
-        if (heapSpacePtr->addr == addr) break;
-    }
-
-    if (heapSpacePtr == shadowSpace->heapSpaceTail) {
-        heapSpacePtr->addr = addr;
-        shadowSpace->heapSpaceTail++;
-    }
-
-    heapSpacePtr->data = data;
-}
-
-static void selfVerificationStoreByte(InterpState* interpState)
-{
-    Thread *self = dvmThreadSelf();
-    ShadowHeap *heapSpacePtr;
-    ShadowSpace *shadowSpace = self->shadowSpace;
-    HeapArgSpace *heapArgSpace = &(interpState->heapArgSpace);
-
-    int addr, data;
-    int reg0 = heapArgSpace->regMap & 0xFF;
-    int reg1 = (heapArgSpace->regMap >> 8) & 0xFF;
-    selfVerificationStoreDecode(heapArgSpace, &addr, reg0);
-    selfVerificationStoreDecode(heapArgSpace, &data, reg1);
-
-    int maskedAddr = addr & 0xFFFFFFFC;
-    int alignment = addr & 0x3;
-
-    //LOGD("*** HEAP STORE BYTE: Addr: 0x%x Data: 0x%x", addr, data);
-
-    for (heapSpacePtr = shadowSpace->heapSpace;
-         heapSpacePtr != shadowSpace->heapSpaceTail; heapSpacePtr++) {
-        if (heapSpacePtr->addr == maskedAddr) break;
-    }
-
-    if (heapSpacePtr == shadowSpace->heapSpaceTail)  {
-        heapSpacePtr->addr = maskedAddr;
-        heapSpacePtr->data = *((unsigned int*) maskedAddr);
-        shadowSpace->heapSpaceTail++;
-    }
-
-    addr = ((unsigned int) &(heapSpacePtr->data)) | alignment;
-    *((unsigned char*) addr) = (char) data;
-
-    //LOGD("*** HEAP STORE BYTE: Addr: 0x%x Final Data: 0x%x",
-    //    addr, heapSpacePtr->data);
-}
-
-static void selfVerificationStoreHalfword(InterpState* interpState)
-{
-    Thread *self = dvmThreadSelf();
-    ShadowHeap *heapSpacePtr;
-    ShadowSpace *shadowSpace = self->shadowSpace;
-    HeapArgSpace *heapArgSpace = &(interpState->heapArgSpace);
-
-    int addr, data;
-    int reg0 = heapArgSpace->regMap & 0xFF;
-    int reg1 = (heapArgSpace->regMap >> 8) & 0xFF;
-    selfVerificationStoreDecode(heapArgSpace, &addr, reg0);
-    selfVerificationStoreDecode(heapArgSpace, &data, reg1);
-
-    int maskedAddr = addr & 0xFFFFFFFC;
-    int alignment = addr & 0x2;
-
-    //LOGD("*** HEAP STORE kHalfWord: Addr: 0x%x Data: 0x%x", addr, data);
-
-    for (heapSpacePtr = shadowSpace->heapSpace;
-         heapSpacePtr != shadowSpace->heapSpaceTail; heapSpacePtr++) {
-        if (heapSpacePtr->addr == maskedAddr) break;
-    }
-
-    if (heapSpacePtr == shadowSpace->heapSpaceTail)  {
-        heapSpacePtr->addr = maskedAddr;
-        heapSpacePtr->data = *((unsigned int*) maskedAddr);
-        shadowSpace->heapSpaceTail++;
-    }
-
-    addr = ((unsigned int) &(heapSpacePtr->data)) | alignment;
-    *((unsigned short*) addr) = (short) data;
-
-    //LOGD("*** HEAP STORE kHalfWord: Addr: 0x%x Final Data: 0x%x",
-    //    addr, heapSpacePtr->data);
-}
-
-static void selfVerificationStoreDoubleword(InterpState* interpState)
-{
-    Thread *self = dvmThreadSelf();
-    ShadowHeap *heapSpacePtr;
-    ShadowSpace *shadowSpace = self->shadowSpace;
-    HeapArgSpace *heapArgSpace = &(interpState->heapArgSpace);
-
-    int addr, data, data2;
-    int reg0 = heapArgSpace->regMap & 0xFF;
-    int reg1 = (heapArgSpace->regMap >> 8) & 0xFF;
-    int reg2 = (heapArgSpace->regMap >> 16) & 0xFF;
-    selfVerificationStoreDecode(heapArgSpace, &addr, reg0);
-    selfVerificationStoreDecode(heapArgSpace, &data, reg1);
-    selfVerificationStoreDecode(heapArgSpace, &data2, reg2);
-
-    int addr2 = addr+4;
-    bool store1 = false, store2 = false;
-
-    //LOGD("*** HEAP STORE DOUBLEWORD: Addr: 0x%x Data: 0x%x, Data2: 0x%x",
-    //    addr, data, data2);
-
-    for (heapSpacePtr = shadowSpace->heapSpace;
-         heapSpacePtr != shadowSpace->heapSpaceTail; heapSpacePtr++) {
-        if (heapSpacePtr->addr == addr) {
-            heapSpacePtr->data = data;
-            store1 = true;
-        } else if (heapSpacePtr->addr == addr2) {
-            heapSpacePtr->data = data2;
-            store2 = true;
-        }
-    }
-
-    if (!store1) {
-        shadowSpace->heapSpaceTail->addr = addr;
-        shadowSpace->heapSpaceTail->data = data;
-        shadowSpace->heapSpaceTail++;
-    }
-    if (!store2) {
-        shadowSpace->heapSpaceTail->addr = addr2;
-        shadowSpace->heapSpaceTail->data = data2;
-        shadowSpace->heapSpaceTail++;
-    }
-}
-
-/* Common wrapper function for all memory operations */
-static void selfVerificationMemOpWrapper(CompilationUnit *cUnit, int regMap,
-                                         void* funct)
-{
-    /* push r0 and r7 to give us a foothold */
-    newLIR1(cUnit, kThumbPush, (1 << r0) | (1 << r7));
-
-    /* Let the save handler know where the save record is */
-    loadConstant(cUnit, r0, offsetof(InterpState, heapArgSpace));
-
-    /* Load the regMap and call the save handler [note: handler pops r0/r7] */
-    loadConstant(cUnit, r7, regMap);
-    genDispatchToHandler(cUnit, TEMPLATE_SAVE_STATE);
-
-    /* Set function pointer, pass rGLUE and branch */
-    loadConstant(cUnit, r1, (int) funct);
-    newLIR2(cUnit, kThumbMovRR, r0, rGLUE);
-    newLIR1(cUnit, kThumbBlxR, r1);
-
-    /* Let the recover handler know where coreRegs[0] and restore regs */
-    loadConstant(cUnit, r0, offsetof(InterpState, heapArgSpace) +
-                            offsetof(HeapArgSpace, coreRegs));
-    genDispatchToHandler(cUnit, TEMPLATE_RESTORE_STATE);
-}
-
 #endif
 
 /* Generate a unconditional branch to go to the interpreter */
@@ -639,12 +265,12 @@
                  NULL);/* null object? */
     opRegRegImm(cUnit, kOpAdd, regPtr, rlObj.lowReg, fieldOffset);
     rlResult = evalLoc(cUnit, rlDest, kAnyReg, true);
-#if !defined(WITH_SELF_VERIFICATION)
+#if defined(WITH_SELF_VERIFICATION)
+    cUnit->heapMemOp = true;
+#endif
     loadPair(cUnit, regPtr, rlResult.lowReg, rlResult.highReg);
-#else
-    int regMap = rlResult.highReg << 16 | rlResult.lowReg << 8 | regPtr;
-    selfVerificationMemOpWrapper(cUnit, regMap,
-        &selfVerificationLoadDoubleword);
+#if defined(WITH_SELF_VERIFICATION)
+    cUnit->heapMemOp = false;
 #endif
     freeTemp(cUnit, regPtr);
     storeValueWide(cUnit, rlDest, rlResult);
@@ -663,12 +289,12 @@
                  NULL);/* null object? */
     regPtr = allocTemp(cUnit);
     opRegRegImm(cUnit, kOpAdd, regPtr, rlObj.lowReg, fieldOffset);
-#if !defined(WITH_SELF_VERIFICATION)
+#if defined(WITH_SELF_VERIFICATION)
+    cUnit->heapMemOp = true;
+#endif
     storePair(cUnit, regPtr, rlSrc.lowReg, rlSrc.highReg);
-#else
-    int regMap = rlSrc.highReg << 16 | rlSrc.lowReg << 8 | regPtr;
-    selfVerificationMemOpWrapper(cUnit, regMap,
-        &selfVerificationStoreDoubleword);
+#if defined(WITH_SELF_VERIFICATION)
+    cUnit->heapMemOp = false;
 #endif
     freeTemp(cUnit, regPtr);
 }
@@ -689,17 +315,13 @@
     rlResult = evalLoc(cUnit, rlDest, kAnyReg, true);
     genNullCheck(cUnit, rlObj.sRegLow, rlObj.lowReg, mir->offset,
                  NULL);/* null object? */
-#if !defined(WITH_SELF_VERIFICATION)
+#if defined(WITH_SELF_VERIFICATION)
+    cUnit->heapMemOp = true;
+#endif
     loadBaseDisp(cUnit, mir, rlObj.lowReg, fieldOffset, rlResult.lowReg,
                  size, rlObj.sRegLow);
-#else
-    /* Combine address and offset */
-    regPtr = allocTemp(cUnit);
-    opRegRegImm(cUnit, kOpAdd, regPtr, rlObj.lowReg, fieldOffset);
-
-    int regMap = rlResult.lowReg << 8 | regPtr;
-    selfVerificationMemOpWrapper(cUnit, regMap, &selfVerificationLoad);
-    freeTemp(cUnit, regPtr);
+#if defined(WITH_SELF_VERIFICATION)
+    cUnit->heapMemOp = false;
 #endif
     storeValue(cUnit, rlDest, rlResult);
 }
@@ -719,15 +341,12 @@
     int regPtr;
     genNullCheck(cUnit, rlObj.sRegLow, rlObj.lowReg, mir->offset,
                  NULL);/* null object? */
-#if !defined(WITH_SELF_VERIFICATION)
+#if defined(WITH_SELF_VERIFICATION)
+    cUnit->heapMemOp = true;
+#endif
     storeBaseDisp(cUnit, rlObj.lowReg, fieldOffset, rlSrc.lowReg, size);
-#else
-    /* Combine address and offset */
-    regPtr = allocTemp(cUnit);
-    opRegRegImm(cUnit, kOpAdd, regPtr, rlObj.lowReg, fieldOffset);
-
-    int regMap = rlSrc.lowReg << 8 | regPtr;
-    selfVerificationMemOpWrapper(cUnit, regMap, &selfVerificationStore);
+#if defined(WITH_SELF_VERIFICATION)
+    cUnit->heapMemOp = false;
 #endif
 }
 
@@ -769,7 +388,6 @@
         /* regPtr -> array data */
         opRegRegImm(cUnit, kOpAdd, regPtr, rlArray.lowReg, dataOffset);
     }
-#if !defined(WITH_SELF_VERIFICATION)
     if ((size == kLong) || (size == kDouble)) {
         if (scale) {
             int rNewIndex = allocTemp(cUnit);
@@ -780,63 +398,28 @@
             opRegReg(cUnit, kOpAdd, regPtr, rlIndex.lowReg);
         }
         rlResult = evalLoc(cUnit, rlDest, kAnyReg, true);
+#if defined(WITH_SELF_VERIFICATION)
+        cUnit->heapMemOp = true;
+#endif
         loadPair(cUnit, regPtr, rlResult.lowReg, rlResult.highReg);
+#if defined(WITH_SELF_VERIFICATION)
+        cUnit->heapMemOp = false;
+#endif
         freeTemp(cUnit, regPtr);
         storeValueWide(cUnit, rlDest, rlResult);
     } else {
         rlResult = evalLoc(cUnit, rlDest, kAnyReg, true);
+#if defined(WITH_SELF_VERIFICATION)
+        cUnit->heapMemOp = true;
+#endif
         loadBaseIndexed(cUnit, regPtr, rlIndex.lowReg, rlResult.lowReg,
                         scale, size);
+#if defined(WITH_SELF_VERIFICATION)
+        cUnit->heapMemOp = false;
+#endif
         freeTemp(cUnit, regPtr);
         storeValue(cUnit, rlDest, rlResult);
     }
-#else
-    //TODO: probably want to move this into loadBaseIndexed
-    void *funct = NULL;
-    switch(size) {
-        case kLong:
-        case kDouble:
-            funct = (void*) &selfVerificationLoadDoubleword;
-            break;
-        case kWord:
-            funct = (void*) &selfVerificationLoad;
-            break;
-        case kUnsignedHalf:
-            funct = (void*) &selfVerificationLoadHalfword;
-            break;
-        case kSignedHalf:
-            funct = (void*) &selfVerificationLoadSignedHalfword;
-            break;
-        case kUnsignedByte:
-            funct = (void*) &selfVerificationLoadByte;
-            break;
-        case kSignedByte:
-            funct = (void*) &selfVerificationLoadSignedByte;
-            break;
-        default:
-            assert(0);
-            dvmAbort();
-    }
-    /* Combine address and index */
-    if (scale) {
-        int regTmp = allocTemp(cUnit);
-        opRegRegImm(cUnit, kOpLsl, regTmp, rlIndex.lowReg, scale);
-        opRegReg(cUnit, kOpAdd, regPtr, regTmp);
-        freeTemp(cUnit, regTmp);
-    } else {
-        opRegReg(cUnit, kOpAdd, regPtr, rlIndex.lowReg);
-    }
-
-    rlResult = evalLoc(cUnit, rlDest, kAnyReg, true);
-    int regMap = rlResult.highReg << 16 | rlResult.lowReg << 8 | regPtr;
-    selfVerificationMemOpWrapper(cUnit, regMap, funct);
-
-    freeTemp(cUnit, regPtr);
-    if ((size == kLong) || (size == kDouble))
-        storeValueWide(cUnit, rlDest, rlResult);
-    else
-        storeValue(cUnit, rlDest, rlResult);
-#endif
 }
 
 /*
@@ -885,7 +468,6 @@
         opRegImm(cUnit, kOpAdd, regPtr, dataOffset);
     }
     /* at this point, regPtr points to array, 2 live temps */
-#if !defined(WITH_SELF_VERIFICATION)
     if ((size == kLong) || (size == kDouble)) {
         //TODO: need specific wide routine that can handle fp regs
         if (scale) {
@@ -897,57 +479,25 @@
             opRegReg(cUnit, kOpAdd, regPtr, rlIndex.lowReg);
         }
         rlSrc = loadValueWide(cUnit, rlSrc, kAnyReg);
+#if defined(WITH_SELF_VERIFICATION)
+        cUnit->heapMemOp = true;
+#endif
         storePair(cUnit, regPtr, rlSrc.lowReg, rlSrc.highReg);
+#if defined(WITH_SELF_VERIFICATION)
+        cUnit->heapMemOp = false;
+#endif
         freeTemp(cUnit, regPtr);
     } else {
         rlSrc = loadValue(cUnit, rlSrc, kAnyReg);
+#if defined(WITH_SELF_VERIFICATION)
+        cUnit->heapMemOp = true;
+#endif
         storeBaseIndexed(cUnit, regPtr, rlIndex.lowReg, rlSrc.lowReg,
                          scale, size);
-    }
-#else
-    //TODO: probably want to move this into storeBaseIndexed
-    void *funct = NULL;
-    switch(size) {
-        case kLong:
-        case kDouble:
-            funct = (void*) &selfVerificationStoreDoubleword;
-            break;
-        case kWord:
-            funct = (void*) &selfVerificationStore;
-            break;
-        case kSignedHalf:
-        case kUnsignedHalf:
-            funct = (void*) &selfVerificationStoreHalfword;
-            break;
-        case kSignedByte:
-        case kUnsignedByte:
-            funct = (void*) &selfVerificationStoreByte;
-            break;
-        default:
-            assert(0);
-            dvmAbort();
-    }
-
-    if (scale) {
-        int regTmpIndex = allocTemp(cUnit);
-        // 3 live temps
-        opRegRegImm(cUnit, kOpLsl, regTmpIndex, rlIndex.lowReg, scale);
-        opRegReg(cUnit, kOpAdd, regPtr, regTmpIndex);
-        freeTemp(cUnit, regTmpIndex);
-    } else {
-        opRegReg(cUnit, kOpAdd, regPtr, rlIndex.lowReg);
-    }
-    /* Combine address and index */
-    if ((size == kLong) || (size == kDouble)) {
-        rlSrc = loadValueWide(cUnit, rlSrc, kAnyReg);
-    } else {
-        rlSrc = loadValue(cUnit, rlSrc, kAnyReg);
-    }
-
-    int regMap = rlSrc.highReg << 16 | rlSrc.lowReg << 8 | regPtr;
-    selfVerificationMemOpWrapper(cUnit, regMap, funct);
-
+#if defined(WITH_SELF_VERIFICATION)
+        cUnit->heapMemOp = false;
 #endif
+    }
 }
 
 static bool genShiftOpLong(CompilationUnit *cUnit, MIR *mir,
@@ -1881,12 +1431,12 @@
             rlDest = getDestLoc(cUnit, mir, 0);
             rlResult = evalLoc(cUnit, rlDest, kAnyReg, true);
             loadConstant(cUnit, tReg,  (int) fieldPtr + valOffset);
-#if !defined(WITH_SELF_VERIFICATION)
+#if defined(WITH_SELF_VERIFICATION)
+            cUnit->heapMemOp = true;
+#endif
             loadWordDisp(cUnit, tReg, 0, rlResult.lowReg);
-#else
-            int regMap = rlResult.lowReg << 8 | tReg;
-            selfVerificationMemOpWrapper(cUnit, regMap, &selfVerificationLoad);
-
+#if defined(WITH_SELF_VERIFICATION)
+            cUnit->heapMemOp = false;
 #endif
             storeValue(cUnit, rlDest, rlResult);
             break;
@@ -1900,14 +1450,12 @@
             rlDest = getDestLocWide(cUnit, mir, 0, 1);
             rlResult = evalLoc(cUnit, rlDest, kAnyReg, true);
             loadConstant(cUnit, tReg,  (int) fieldPtr + valOffset);
-#if !defined(WITH_SELF_VERIFICATION)
+#if defined(WITH_SELF_VERIFICATION)
+            cUnit->heapMemOp = true;
+#endif
             loadPair(cUnit, tReg, rlResult.lowReg, rlResult.highReg);
-#else
-            int regMap = rlResult.highReg << 16 |
-                         rlResult.lowReg << 8 | tReg;
-            selfVerificationMemOpWrapper(cUnit, regMap,
-                &selfVerificationLoadDoubleword);
-
+#if defined(WITH_SELF_VERIFICATION)
+            cUnit->heapMemOp = false;
 #endif
             storeValueWide(cUnit, rlDest, rlResult);
             break;
@@ -1927,11 +1475,12 @@
             rlSrc = getSrcLoc(cUnit, mir, 0);
             rlSrc = loadValue(cUnit, rlSrc, kAnyReg);
             loadConstant(cUnit, tReg,  (int) fieldPtr + valOffset);
-#if !defined(WITH_SELF_VERIFICATION)
+#if defined(WITH_SELF_VERIFICATION)
+            cUnit->heapMemOp = true;
+#endif
             storeWordDisp(cUnit, tReg, 0 ,rlSrc.lowReg);
-#else
-            int regMap = rlSrc.lowReg << 8 | tReg;
-            selfVerificationMemOpWrapper(cUnit, regMap, &selfVerificationStore);
+#if defined(WITH_SELF_VERIFICATION)
+            cUnit->heapMemOp = false;
 #endif
             break;
         }
@@ -1945,12 +1494,12 @@
             rlSrc = getSrcLocWide(cUnit, mir, 0, 1);
             rlSrc = loadValueWide(cUnit, rlSrc, kAnyReg);
             loadConstant(cUnit, tReg,  (int) fieldPtr + valOffset);
-#if !defined(WITH_SELF_VERIFICATION)
+#if defined(WITH_SELF_VERIFICATION)
+            cUnit->heapMemOp = true;
+#endif
             storePair(cUnit, tReg, rlSrc.lowReg, rlSrc.highReg);
-#else
-            int regMap = rlSrc.highReg << 16 | rlSrc.lowReg << 8 | tReg;
-            selfVerificationMemOpWrapper(cUnit, regMap,
-                &selfVerificationStoreDoubleword);
+#if defined(WITH_SELF_VERIFICATION)
+            cUnit->heapMemOp = false;
 #endif
             break;
         }
@@ -4114,6 +3663,10 @@
     }
 
     dvmCompilerApplyGlobalOptimizations(cUnit);
+
+#if defined(WITH_SELF_VERIFICATION)
+    selfVerificationBranchInsertPass(cUnit);
+#endif
 }
 
 /* Accept the work and start compiling */