Forward progress on verifier.

Promoted VerifierData to a more prominent role in passing state around.
This will (a) allow us to pass fewer explicit arguments around in the
core of the verifier, and (b) make it easier to maintain some fancier
data structures that we will need shortly.

Made use of dexGetInstrOrTableWidthAbs() in a couple of places where
we were still explicitly calculating the sizes of NOP data chunks.

Converted some things from int to size_t.

Change-Id: I206f588bf1fc116a9d1f50fb631a9af33479b291
diff --git a/libdex/InstrUtils.c b/libdex/InstrUtils.c
index bab77ce..79095ae 100644
--- a/libdex/InstrUtils.c
+++ b/libdex/InstrUtils.c
@@ -1239,9 +1239,10 @@
  * works for special OP_NOP entries, including switch statement data tables
  * and array data.
  */
-int dexGetInstrOrTableWidthAbs(const InstructionWidth* widths, const u2* insns)
+size_t dexGetInstrOrTableWidthAbs(const InstructionWidth* widths,
+    const u2* insns)
 {
-    int width;
+    size_t width;
 
     if (*insns == kPackedSwitchSignature) {
         width = 4 + insns[1] * 2;
diff --git a/libdex/InstrUtils.h b/libdex/InstrUtils.h
index b41df49..ad2bc34 100644
--- a/libdex/InstrUtils.h
+++ b/libdex/InstrUtils.h
@@ -126,7 +126,8 @@
 /*
  * Return the width of the specified instruction, or 0 if not defined.
  */
-DEX_INLINE int dexGetInstrWidthAbs(const InstructionWidth* widths,OpCode opCode)
+DEX_INLINE size_t dexGetInstrWidthAbs(const InstructionWidth* widths,
+    OpCode opCode)
 {
     //assert(/*opCode >= 0 &&*/ opCode < kNumDalvikInstructions);
 
@@ -142,7 +143,8 @@
  * works for special OP_NOP entries, including switch statement data tables
  * and array data.
  */
-int dexGetInstrOrTableWidthAbs(const InstructionWidth* widths, const u2* insns);
+size_t dexGetInstrOrTableWidthAbs(const InstructionWidth* widths,
+    const u2* insns);
 
 
 /*
diff --git a/vm/analysis/CodeVerify.c b/vm/analysis/CodeVerify.c
index 74f2f02..30670ec 100644
--- a/vm/analysis/CodeVerify.c
+++ b/vm/analysis/CodeVerify.c
@@ -123,9 +123,9 @@
     VerifyError* pFailure);
 static void verifyRegisterType(const RegType* insnRegs, const int insnRegCount,\
     u4 vsrc, RegType checkType, VerifyError* pFailure);
-static bool doCodeVerification(Method* meth, InsnFlags* insnFlags,\
+static bool doCodeVerification(const Method* meth, InsnFlags* insnFlags,\
     RegisterTable* regTable, UninitInstanceMap* uninitMap);
-static bool verifyInstruction(Method* meth, InsnFlags* insnFlags,\
+static bool verifyInstruction(const Method* meth, InsnFlags* insnFlags,\
     RegisterTable* regTable, RegType* workRegs, int insnIdx,
     UninitInstanceMap* uninitMap, int* pStartGuess);
 static ClassObject* findCommonSuperclass(ClassObject* c1, ClassObject* c2);
@@ -2936,12 +2936,9 @@
  * The verifier explicitly locks out breakpoint activity, so there should
  * be no clashes with the debugger.
  *
- * IMPORTANT: this may replace meth->insns with a pointer to a new copy of
- * the instructions.
- *
  * Returns "true" on success.
  */
-static bool replaceFailingInstruction(Method* meth, InsnFlags* insnFlags,
+static bool replaceFailingInstruction(const Method* meth, InsnFlags* insnFlags,
     int insnIdx, VerifyError failure)
 {
     VerifyErrorRefType refType;
@@ -3062,7 +3059,7 @@
  * that the feature isn't disabled when verification is turned off.  At
  * some point we may need to revisit this choice.
  */
-static void replaceVolatileInstruction(Method* meth, InsnFlags* insnFlags,
+static void replaceVolatileInstruction(const Method* meth, InsnFlags* insnFlags,
     int insnIdx)
 {
     u2* oldInsns = (u2*)meth->insns + insnIdx;
@@ -3102,11 +3099,11 @@
 /*
  * Entry point for the detailed code-flow analysis.
  */
-bool dvmVerifyCodeFlow(Method* meth, InsnFlags* insnFlags,
-    UninitInstanceMap* uninitMap)
+bool dvmVerifyCodeFlow(VerifierData* vdata)
 {
     bool result = false;
-    const int insnsSize = dvmGetMethodInsnsSize(meth);
+    const Method* meth = vdata->method;
+    const int insnsSize = vdata->insnsSize;
     const bool generateRegisterMap = gDvm.generateRegisterMaps;
     RegisterTable regTable;
 
@@ -3150,37 +3147,32 @@
      * also going to create the register map, we need to retain the
      * register lists for a larger set of addresses.
      */
-    if (!initRegisterTable(meth, insnFlags, &regTable,
+    if (!initRegisterTable(meth, vdata->insnFlags, &regTable,
             generateRegisterMap ? kTrackRegsGcPoints : kTrackRegsBranches))
         goto bail;
 
+    vdata->addrRegs = NULL;     /* don't set this until we need it */
+
     /*
      * Initialize the types of the registers that correspond to the
      * method arguments.  We can determine this from the method signature.
      */
-    if (!setTypesFromSignature(meth, regTable.addrRegs[0], uninitMap))
+    if (!setTypesFromSignature(meth, regTable.addrRegs[0], vdata->uninitMap))
         goto bail;
 
     /*
      * Run the verifier.
      */
-    if (!doCodeVerification(meth, insnFlags, &regTable, uninitMap))
+    if (!doCodeVerification(meth, vdata->insnFlags, &regTable, vdata->uninitMap))
         goto bail;
 
     /*
      * Generate a register map.
      */
     if (generateRegisterMap) {
-        RegisterMap* pMap;
-        VerifierData vd;
+        vdata->addrRegs = regTable.addrRegs;
 
-        vd.method = meth;
-        vd.insnsSize = insnsSize;
-        vd.insnRegCount = meth->registersSize;
-        vd.insnFlags = insnFlags;
-        vd.addrRegs = regTable.addrRegs;
-
-        pMap = dvmGenerateRegisterMapV(&vd);
+        RegisterMap* pMap = dvmGenerateRegisterMapV(vdata);
         if (pMap != NULL) {
             /*
              * Tuck it into the Method struct.  It will either get used
@@ -3253,7 +3245,7 @@
  * instruction if a register contains an uninitialized instance created
  * by that same instrutcion.
  */
-static bool doCodeVerification(Method* meth, InsnFlags* insnFlags,
+static bool doCodeVerification(const Method* meth, InsnFlags* insnFlags,
     RegisterTable* regTable, UninitInstanceMap* uninitMap)
 {
     const int insnsSize = dvmGetMethodInsnsSize(meth);
@@ -3487,7 +3479,7 @@
  * This may alter meth->insns if we need to replace an instruction with
  * throw-verification-error.
  */
-static bool verifyInstruction(Method* meth, InsnFlags* insnFlags,
+static bool verifyInstruction(const Method* meth, InsnFlags* insnFlags,
     RegisterTable* regTable, RegType* workRegs, int insnIdx,
     UninitInstanceMap* uninitMap, int* pStartGuess)
 {
@@ -3506,13 +3498,12 @@
      *     and switch statements.
      * (3) Exception handlers.  Applies to any instruction that can
      *     throw an exception that is handled by an encompassing "try"
-     *     block.  (We simplify this to be any instruction that can
-     *     throw any exception.)
+     *     block.
      *
      * We can also return, in which case there is no successor instruction
      * from this point.
      *
-     * The behavior can be determined from the InstrFlags.
+     * The behavior can be determined from the InstructionFlags.
      */
 
     const DexFile* pDexFile = meth->clazz->pDvmDex->pDexFile;
diff --git a/vm/analysis/CodeVerify.h b/vm/analysis/CodeVerify.h
index d8959ce..a7ddc95 100644
--- a/vm/analysis/CodeVerify.h
+++ b/vm/analysis/CodeVerify.h
@@ -106,7 +106,65 @@
  */
 typedef u4 RegType;
 
-/* table with merge logic for primitive types */
+/*
+ * Table that maps uninitialized instances to classes, based on the
+ * address of the new-instance instruction.
+ */
+typedef struct UninitInstanceMap {
+    int numEntries;
+    struct {
+        int             addr;   /* code offset, or -1 for method arg ("this") */
+        ClassObject*    clazz;  /* class created at this address */
+    } map[1];
+} UninitInstanceMap;
+#define kUninitThisArgAddr  (-1)
+#define kUninitThisArgSlot  0
+
+/*
+ * Various bits of data generated by the verifier, wrapped up in a package
+ * for ease of use by the register map generator.
+ */
+typedef struct VerifierData {
+    /*
+     * The method we're working on.
+     */
+    const Method*   method;
+
+    /*
+     * Number of code units of instructions in the method.  A cache of the
+     * value calculated by dvmGetMethodInsnsSize().
+     */
+    u4              insnsSize;
+
+    /*
+     * Number of registers we track for each instruction.  This is equal
+     * to the method's declared "registersSize".  (Does not include the
+     * pending return value.)
+     */
+    u4              insnRegCount;
+
+    /*
+     * Instruction widths and flags, one entry per code unit.
+     */
+    InsnFlags*      insnFlags;
+
+    /*
+     * Uninitialized instance map, used for tracking the movement of
+     * objects that have been allocated but not initialized.
+     */
+    UninitInstanceMap* uninitMap;
+
+    /*
+     * Array of SRegType arrays, one entry per code unit.  We only need
+     * entries for code units that hold the start of an "interesting"
+     * instruction.  For register map generation, we're only interested
+     * in GC points.
+     */
+    RegType**       addrRegs;
+} VerifierData;
+
+
+/* table with static merge logic for primitive types */
 extern const char gDvmMergeTab[kRegTypeMAX][kRegTypeMAX];
 
 
@@ -209,20 +267,6 @@
 
 
 /*
- * Table that maps uninitialized instances to classes, based on the
- * address of the new-instance instruction.
- */
-typedef struct UninitInstanceMap {
-    int numEntries;
-    struct {
-        int             addr;   /* code offset, or -1 for method arg ("this") */
-        ClassObject*    clazz;  /* class created at this address */
-    } map[1];
-} UninitInstanceMap;
-#define kUninitThisArgAddr  (-1)
-#define kUninitThisArgSlot  0
-
-/*
  * Create a new UninitInstanceMap.
  */
 UninitInstanceMap* dvmCreateUninitInstanceMap(const Method* meth,
@@ -259,7 +303,6 @@
  * Verify bytecode in "meth".  "insnFlags" should be populated with
  * instruction widths and "in try" flags.
  */
-bool dvmVerifyCodeFlow(Method* meth, InsnFlags* insnFlags,
-    UninitInstanceMap* uninitMap);
+bool dvmVerifyCodeFlow(VerifierData* vdata);
 
 #endif /*_DALVIK_CODEVERIFY*/
diff --git a/vm/analysis/DexPrepare.c b/vm/analysis/DexPrepare.c
index 144354a..3e65594 100644
--- a/vm/analysis/DexPrepare.c
+++ b/vm/analysis/DexPrepare.c
@@ -943,7 +943,7 @@
             LOGD("DexOpt: not verifying '%s': multiple definitions\n",
                 classDescriptor);
         } else {
-            if (dvmVerifyClass(clazz, VERIFY_DEFAULT)) {
+            if (dvmVerifyClass(clazz)) {
                 /*
                  * Set the "is preverified" flag in the DexClassDef.  We
                  * do it here, rather than in the ClassObject structure,
@@ -951,8 +951,7 @@
                  */
                 assert((clazz->accessFlags & JAVA_FLAGS_MASK) ==
                     pClassDef->accessFlags);
-                ((DexClassDef*)pClassDef)->accessFlags |=
-                    CLASS_ISPREVERIFIED;
+                ((DexClassDef*)pClassDef)->accessFlags |= CLASS_ISPREVERIFIED;
                 verified = true;
             } else {
                 // TODO: log when in verbose mode
diff --git a/vm/analysis/DexVerify.c b/vm/analysis/DexVerify.c
index 4c4df8f..b934481 100644
--- a/vm/analysis/DexVerify.c
+++ b/vm/analysis/DexVerify.c
@@ -23,9 +23,8 @@
 
 
 /* fwd */
-static bool verifyMethod(Method* meth, int verifyFlags);
-static bool verifyInstructions(const Method* meth, InsnFlags* insnFlags,
-    int verifyFlags);
+static bool verifyMethod(Method* meth);
+static bool verifyInstructions(VerifierData* vdata);
 
 
 /*
@@ -66,7 +65,7 @@
  *
  * Returns "true" on success.
  */
-bool dvmVerifyClass(ClassObject* clazz, int verifyFlags)
+bool dvmVerifyClass(ClassObject* clazz)
 {
     int i;
 
@@ -75,16 +74,14 @@
         return true;
     }
 
-    // TODO - verify class structure in DEX?
-
     for (i = 0; i < clazz->directMethodCount; i++) {
-        if (!verifyMethod(&clazz->directMethods[i], verifyFlags)) {
+        if (!verifyMethod(&clazz->directMethods[i])) {
             LOG_VFY("Verifier rejected class %s\n", clazz->descriptor);
             return false;
         }
     }
     for (i = 0; i < clazz->virtualMethodCount; i++) {
-        if (!verifyMethod(&clazz->virtualMethods[i], verifyFlags)) {
+        if (!verifyMethod(&clazz->virtualMethods[i])) {
             LOG_VFY("Verifier rejected class %s\n", clazz->descriptor);
             return false;
         }
@@ -98,36 +95,53 @@
  * Perform verification on a single method.
  *
  * We do this in three passes:
- *  (1) Walk through all code units, determining instruction lengths.
- *  (2) Do static checks, including branch target and operand validation.
- *  (3) Do structural checks, including data-flow analysis.
+ *  (1) Walk through all code units, determining instruction locations,
+ *      widths, and other characteristics.
+ *  (2) Walk through all code units, performing static checks on
+ *      operands.
+ *  (3) Iterate through the method, checking type safety and looking
+ *      for code flow problems.
  *
  * Some checks may be bypassed depending on the verification mode.  We can't
  * turn this stuff off completely if we want to do "exact" GC.
  *
- * - operands of getfield, putfield, getstatic, putstatic must be valid
- * - operands of method invocation instructions must be valid
- *
+ * TODO: cite source?
+ * Confirmed here:
  * - code array must not be empty
  * - (N/A) code_length must be less than 65536
+ * Confirmed by dvmComputeCodeWidths():
  * - opcode of first instruction begins at index 0
  * - only documented instructions may appear
  * - each instruction follows the last
- * - (below) last byte of last instruction is at (code_length-1)
+ * - last byte of last instruction is at (code_length-1)
  */
-static bool verifyMethod(Method* meth, int verifyFlags)
+static bool verifyMethod(Method* meth)
 {
     bool result = false;
-    UninitInstanceMap* uninitMap = NULL;
-    InsnFlags* insnFlags = NULL;
     int newInstanceCount;
 
     /*
-     * If there aren't any instructions, make sure that's expected, then
-     * exit successfully. Note: meth->insns gets set to a native function
-     * pointer on first call.
+     * Verifier state blob.  Various values will be cached here so we
+     * can avoid expensive lookups and pass fewer arguments around.
      */
-    if (dvmGetMethodInsnsSize(meth) == 0) {
+    VerifierData vdata;
+#if 1   // ndef NDEBUG
+    memset(&vdata, 0x99, sizeof(vdata));
+#endif
+
+    vdata.method = meth;
+    vdata.insnsSize = dvmGetMethodInsnsSize(meth);
+    vdata.insnRegCount = meth->registersSize;
+    vdata.insnFlags = NULL;
+    vdata.uninitMap = NULL;
+
+    /*
+     * If there aren't any instructions, make sure that's expected, then
+     * exit successfully.  Note: for native methods, meth->insns gets set
+     * to a native function pointer on first call, so don't use that as
+     * an indicator.
+     */
+    if (vdata.insnsSize == 0) {
         if (!dvmIsNativeMethod(meth) && !dvmIsAbstractMethod(meth)) {
             LOG_VFY_METH(meth,
                 "VFY: zero-length code in concrete non-native method\n");
@@ -153,9 +167,9 @@
      * TODO: Consider keeping a reusable pre-allocated array sitting
      * around for smaller methods.
      */
-    insnFlags = (InsnFlags*)
+    vdata.insnFlags = (InsnFlags*)
         calloc(dvmGetMethodInsnsSize(meth), sizeof(InsnFlags));
-    if (insnFlags == NULL)
+    if (vdata.insnFlags == NULL)
         goto bail;
 
     /*
@@ -163,26 +177,27 @@
      * Count up the #of occurrences of new-instance instructions while we're
      * at it.
      */
-    if (!dvmComputeCodeWidths(meth, insnFlags, &newInstanceCount))
+    if (!dvmComputeCodeWidths(meth, vdata.insnFlags, &newInstanceCount))
         goto bail;
 
     /*
      * Allocate a map to hold the classes of uninitialized instances.
      */
-    uninitMap = dvmCreateUninitInstanceMap(meth, insnFlags, newInstanceCount);
-    if (uninitMap == NULL)
+    vdata.uninitMap = dvmCreateUninitInstanceMap(meth, vdata.insnFlags,
+        newInstanceCount);
+    if (vdata.uninitMap == NULL)
         goto bail;
 
     /*
      * Set the "in try" flags for all instructions guarded by a "try" block.
      */
-    if (!dvmSetTryFlags(meth, insnFlags))
+    if (!dvmSetTryFlags(meth, vdata.insnFlags))
         goto bail;
 
     /*
      * Perform static instruction verification.
      */
-    if (!verifyInstructions(meth, insnFlags, verifyFlags))
+    if (!verifyInstructions(&vdata))
         goto bail;
 
     /*
@@ -193,7 +208,7 @@
      * analysis, but we still need to verify that nothing actually tries
      * to use a register.
      */
-    if (!dvmVerifyCodeFlow(meth, insnFlags, uninitMap)) {
+    if (!dvmVerifyCodeFlow(&vdata)) {
         //LOGD("+++ %s failed code flow\n", meth->name);
         goto bail;
     }
@@ -202,8 +217,8 @@
     result = true;
 
 bail:
-    dvmFreeUninitInstanceMap(uninitMap);
-    free(insnFlags);
+    dvmFreeUninitInstanceMap(vdata.uninitMap);
+    free(vdata.insnFlags);
     return result;
 }
 
@@ -473,17 +488,18 @@
  * code-flow analysis sometimes has to process the same instruction several
  * times).
  */
-static bool verifyInstructions(const Method* meth, InsnFlags* insnFlags,
-    int verifyFlags)
+static bool verifyInstructions(VerifierData* vdata)
 {
-    const int insnCount = dvmGetMethodInsnsSize(meth);
+    const Method* meth = vdata->method;
+    InsnFlags* insnFlags = vdata->insnFlags;
+    const size_t insnCount = vdata->insnsSize;
     const u2* insns = meth->insns;
     int i;
 
     /* the start of the method is a "branch target" */
     dvmInsnSetBranchTarget(insnFlags, 0, true);
 
-    for (i = 0; i < insnCount; /**/) {
+    for (i = 0; i < (int) insnCount; /**/) {
         /*
          * These types of instructions can be GC points.  To support precise
          * GC, all such instructions must export the PC in the interpreter,
@@ -655,10 +671,8 @@
         case OP_INVOKE_VIRTUAL_QUICK_RANGE:
         case OP_INVOKE_SUPER_QUICK:
         case OP_INVOKE_SUPER_QUICK_RANGE:
-            if ((verifyFlags & VERIFY_ALLOW_OPT_INSTRS) == 0) {
-                LOG_VFY("VFY: not expecting optimized instructions\n");
-                return false;
-            }
+            LOG_VFY("VFY: not expecting optimized instructions\n");
+            return false;
             break;
 
         default:
@@ -672,7 +686,7 @@
     }
 
     /* make sure the last instruction ends at the end of the insn area */
-    if (i != insnCount) {
+    if (i != (int) insnCount) {
         LOG_VFY_METH(meth,
             "VFY: code did not end when expected (end at %d, count %d)\n",
             i, insnCount);
diff --git a/vm/analysis/DexVerify.h b/vm/analysis/DexVerify.h
index 9deaad9..ab2af52 100644
--- a/vm/analysis/DexVerify.h
+++ b/vm/analysis/DexVerify.h
@@ -32,30 +32,19 @@
     VERIFY_MODE_ALL
 } DexClassVerifyMode;
 
-/*
- * Bit values for dvmVerifyClass() "verifyFlags" arg.
- *
- * (Verification is currently a prerequisite for optimization, not an
- * after-effect, so we don't currently use VERIFY_ALLOW_OPT_INSTRS.)
- */
-enum {
-    VERIFY_DEFAULT              = 0,
-    VERIFY_ALLOW_OPT_INSTRS     = 1,    // allow instrs emitted by optimizer
-};
-
 bool dvmVerificationStartup(void);
 void dvmVerificationShutdown(void);
 
 /*
- * Perform verification on all classes loaded from this DEX file.  This
- * should be done before optimization.
+ * Perform verification on all classes loaded from this DEX file.  If
+ * enabled, it must happen before optimization.
  */
 bool dvmVerifyAllClasses(DexFile* pDexFile);
 
 /*
  * Verify a single class.
  */
-bool dvmVerifyClass(ClassObject* clazz, int verifyFlags);
+bool dvmVerifyClass(ClassObject* clazz);
 
 /*
  * Release the storage associated with a RegisterMap.
diff --git a/vm/analysis/Optimize.c b/vm/analysis/Optimize.c
index d334497..6703553 100644
--- a/vm/analysis/Optimize.c
+++ b/vm/analysis/Optimize.c
@@ -156,6 +156,8 @@
 /*
  * Optimize instructions in a method.
  *
+ * This does a single pass through the code, examining each instruction.
+ *
  * Returns "true" if all went well, "false" if we bailed out early when
  * something failed.
  */
@@ -253,17 +255,7 @@
             ;
         }
 
-        if (*insns == kPackedSwitchSignature) {
-            width = 4 + insns[1] * 2;
-        } else if (*insns == kSparseSwitchSignature) {
-            width = 2 + insns[1] * 4;
-        } else if (*insns == kArrayDataSignature) {
-            u2 elemWidth = insns[1];
-            u4 len = insns[2] | (((u4)insns[3]) << 16);
-            width = 4 + (elemWidth * len + 1) / 2;
-        } else {
-            width = dexGetInstrWidthAbs(gDvm.instrWidth, inst);
-        }
+        width = dexGetInstrOrTableWidthAbs(gDvm.instrWidth, insns);
         assert(width > 0);
 
         insns += width;
diff --git a/vm/analysis/RegisterMap.c b/vm/analysis/RegisterMap.c
index cb008c5..f7d92cd 100644
--- a/vm/analysis/RegisterMap.c
+++ b/vm/analysis/RegisterMap.c
@@ -224,7 +224,7 @@
      * since we don't count method entry as a GC point.
      */
     gcPointCount = 0;
-    for (i = 0; i < vdata->insnsSize; i++) {
+    for (i = 0; i < (int) vdata->insnsSize; i++) {
         if (dvmInsnIsGcPoint(vdata->insnFlags, i))
             gcPointCount++;
     }
@@ -254,7 +254,7 @@
      * Populate it.
      */
     mapData = pMap->data;
-    for (i = 0; i < vdata->insnsSize; i++) {
+    for (i = 0; i < (int) vdata->insnsSize; i++) {
         if (dvmInsnIsGcPoint(vdata->insnFlags, i)) {
             assert(vdata->addrRegs[i] != NULL);
             if (format == kRegMapFormatCompact8) {
diff --git a/vm/analysis/RegisterMap.h b/vm/analysis/RegisterMap.h
index dc17b1d..7897d45 100644
--- a/vm/analysis/RegisterMap.h
+++ b/vm/analysis/RegisterMap.h
@@ -228,50 +228,6 @@
  */
 void dvmFreeRegisterMapBuilder(RegisterMapBuilder* pBuilder);
 
-
-/*
- * Generate the register map for a previously-verified method.
- *
- * Returns a pointer to a newly-allocated RegisterMap.
- */
-//RegisterMap* dvmGenerateRegisterMap(const Method* meth);
-
-/*
- * Various bits of data generated by the verifier, wrapped up in a package
- * for ease of use by the register map generator.
- */
-typedef struct VerifierData {
-    /*
-     * The method we're working on.
-     */
-    const Method* method;
-
-    /*
-     * Number of instructions in the method.
-     */
-    int         insnsSize;
-
-    /*
-     * Number of registers we track for each instruction.  This is equal
-     * to the method's declared "registersSize".  (Does not include the
-     * pending return value.)
-     */
-    int         insnRegCount;
-
-    /*
-     * Instruction widths and flags, one entry per code unit.
-     */
-    InsnFlags*  insnFlags;
-
-    /*
-     * Array of SRegType arrays, one entry per code unit.  We only need
-     * entries for code units that hold the start of an "interesting"
-     * instruction.  For register map generation, we're only interested
-     * in GC points.
-     */
-    RegType**   addrRegs;
-} VerifierData;
-
 /*
  * Generate the register map for a method that has just been verified
  * (i.e. we're doing this as part of verification).
diff --git a/vm/analysis/VerifySubs.c b/vm/analysis/VerifySubs.c
index b01a8bc..2285aef 100644
--- a/vm/analysis/VerifySubs.c
+++ b/vm/analysis/VerifySubs.c
@@ -32,52 +32,35 @@
  * If "pNewInstanceCount" is not NULL, it will be set to the number of
  * new-instance instructions in the method.
  *
+ * Performs some static checks, notably:
+ * - opcode of first instruction begins at index 0
+ * - only documented instructions may appear
+ * - each instruction follows the last
+ * - last byte of last instruction is at (code_length-1)
+ *
  * Logs an error and returns "false" on failure.
  */
 bool dvmComputeCodeWidths(const Method* meth, InsnFlags* insnFlags,
     int* pNewInstanceCount)
 {
-    const int insnCount = dvmGetMethodInsnsSize(meth);
+    size_t insnCount = dvmGetMethodInsnsSize(meth);
     const u2* insns = meth->insns;
     bool result = false;
     int newInstanceCount = 0;
     int i;
 
 
-    for (i = 0; i < insnCount; /**/) {
-        int width;
-
-        /*
-         * Switch tables and array data tables are identified with
-         * "extended NOP" opcodes.  They contain no executable code,
-         * so we can just skip past them.
-         */
-        if (*insns == kPackedSwitchSignature) {
-            width = 4 + insns[1] * 2;
-        } else if (*insns == kSparseSwitchSignature) {
-            width = 2 + insns[1] * 4;
-        } else if (*insns == kArrayDataSignature) {
-            u4 size = insns[2] | (((u4)insns[3]) << 16);
-            width = 4 + (insns[1] * size + 1) / 2;
-        } else {
-            int instr = *insns & 0xff;
-            width = dexGetInstrWidthAbs(gDvm.instrWidth, instr);
-            if (width == 0) {
-                LOG_VFY_METH(meth,
-                    "VFY: invalid post-opt instruction (0x%x)\n", instr);
-                LOGI("### instr=%d width=%d table=%d\n",
-                    instr, width, dexGetInstrWidthAbs(gDvm.instrWidth, instr));
-                goto bail;
-            }
-            if (width < 0 || width > 5) {
-                LOGE("VFY: bizarre width value %d\n", width);
-                dvmAbort();
-            }
-
-            if (instr == OP_NEW_INSTANCE)
-                newInstanceCount++;
+    for (i = 0; i < (int) insnCount; /**/) {
+        size_t width = dexGetInstrOrTableWidthAbs(gDvm.instrWidth, insns);
+        if (width == 0) {
+            LOG_VFY_METH(meth,
+                "VFY: invalid post-opt instruction (0x%04x)\n", *insns);
+            goto bail;
         }
 
+        if ((*insns & 0xff) == OP_NEW_INSTANCE)
+            newInstanceCount++;
+
         if (width > 65535) {
             LOG_VFY_METH(meth, "VFY: insane width %d\n", width);
             goto bail;
diff --git a/vm/oo/Class.c b/vm/oo/Class.c
index 3888da7..db0ce7b 100644
--- a/vm/oo/Class.c
+++ b/vm/oo/Class.c
@@ -4271,7 +4271,7 @@
         }
 
         clazz->status = CLASS_VERIFYING;
-        if (!dvmVerifyClass(clazz, VERIFY_DEFAULT)) {
+        if (!dvmVerifyClass(clazz)) {
 verify_failed:
             dvmThrowExceptionWithClassMessage("Ljava/lang/VerifyError;",
                 clazz->descriptor);