Defer reporting of certain verifier failures.

The verifier currently reports all failures immediately.  Certain failures,
such as the failure to resolve a method, or the determination that access
to a field is not allowed, are supposed to deferred until the first time
that executing code does something that could cause the resolution.

With this change, several kinds of verification failures are deferred.
This is done by making a writable copy of the bytecode and replacing the
failing instruction with an "always throw" opcode.

Gory details:
- Added throw-verification-error instruction.  Implemented in "portable"
  and ARM interpreters.  x86 uses portable form through stub.
- Added a function that creates a copy of a DexCode area and makes the
  bytecodes writable.
- Added code that replaces a single instruction with an "always throw".
- Replaced runtime check for abstract/interface in new-instance with a
  check at verification time.
- Added a test to exercise the deferred error mechanism.
- Minor cleanups (replaced tab, bad valgrind command, ...).
diff --git a/vm/mterp/out/InterpAsm-armv4t.S b/vm/mterp/out/InterpAsm-armv4t.S
index af725de..b231a30 100644
--- a/vm/mterp/out/InterpAsm-armv4t.S
+++ b/vm/mterp/out/InterpAsm-armv4t.S
@@ -966,11 +966,9 @@
     cmp     r1, #CLASS_INITIALIZED      @ has class been initialized?
     bne     .LOP_NEW_INSTANCE_needinit        @ no, init class now
 .LOP_NEW_INSTANCE_initialized: @ r0=class
-    ldr     r3, [r0, #offClassObject_accessFlags]   @ r3<- clazz->accessFlags
-    tst     r3, #(ACC_INTERFACE|ACC_ABSTRACT)   @ abstract or interface?
     mov     r1, #ALLOC_DONT_TRACK       @ flags for alloc call
-    beq     .LOP_NEW_INSTANCE_finish          @ concrete class, continue
-    b       .LOP_NEW_INSTANCE_abstract        @ fail
+    bl      dvmAllocObject              @ r0<- new object
+    b       .LOP_NEW_INSTANCE_finish          @ continue
 
 /* ------------------------------ */
     .balign 64
@@ -7453,8 +7451,9 @@
      * exception is indicated by AA, with some detail provided by BBBB.
      */
     /* op AA, ref@BBBB */
-    ldr     r0, [rGLUE, #offGlue_methodClassDex]    @ r0<- glue->methodClassDex
+    ldr     r0, [rGLUE, #offGlue_method]    @ r0<- glue->method
     FETCH(r2, 1)                        @ r2<- BBBB
+    EXPORT_PC()                         @ export the PC
     mov     r1, rINST, lsr #8           @ r1<- AA
     bl      dvmThrowVerificationError   @ always throws
     b       common_exceptionThrown      @ handle exception
@@ -7971,8 +7970,7 @@
 /* continuation for OP_NEW_INSTANCE */
 
     .balign 32                          @ minimize cache lines
-.LOP_NEW_INSTANCE_finish: @ r0=class
-    bl      dvmAllocObject              @ r0<- new object
+.LOP_NEW_INSTANCE_finish: @ r0=new object
     mov     r3, rINST, lsr #8           @ r3<- AA
     cmp     r0, #0                      @ failed?
     beq     common_exceptionThrown      @ yes, handle the exception
@@ -8008,18 +8006,6 @@
     bne     .LOP_NEW_INSTANCE_resolved        @ no, continue
     b       common_exceptionThrown      @ yes, handle exception
 
-    /*
-     * We can't instantiate an abstract class or interface, so throw an
-     * InstantiationError with the class descriptor as the message.
-     *
-     *  r0 holds class object
-     */
-.LOP_NEW_INSTANCE_abstract:
-    ldr     r1, [r0, #offClassObject_descriptor]
-    ldr     r0, .LstrInstantiationErrorPtr
-    bl      dvmThrowExceptionWithClassMessage
-    b       common_exceptionThrown
-
 .LstrInstantiationErrorPtr:
     .word   .LstrInstantiationError
 
diff --git a/vm/mterp/out/InterpAsm-armv5te.S b/vm/mterp/out/InterpAsm-armv5te.S
index 3475fbf..e7efe25 100644
--- a/vm/mterp/out/InterpAsm-armv5te.S
+++ b/vm/mterp/out/InterpAsm-armv5te.S
@@ -966,11 +966,9 @@
     cmp     r1, #CLASS_INITIALIZED      @ has class been initialized?
     bne     .LOP_NEW_INSTANCE_needinit        @ no, init class now
 .LOP_NEW_INSTANCE_initialized: @ r0=class
-    ldr     r3, [r0, #offClassObject_accessFlags]   @ r3<- clazz->accessFlags
-    tst     r3, #(ACC_INTERFACE|ACC_ABSTRACT)   @ abstract or interface?
     mov     r1, #ALLOC_DONT_TRACK       @ flags for alloc call
-    beq     .LOP_NEW_INSTANCE_finish          @ concrete class, continue
-    b       .LOP_NEW_INSTANCE_abstract        @ fail
+    bl      dvmAllocObject              @ r0<- new object
+    b       .LOP_NEW_INSTANCE_finish          @ continue
 
 /* ------------------------------ */
     .balign 64
@@ -7453,8 +7451,9 @@
      * exception is indicated by AA, with some detail provided by BBBB.
      */
     /* op AA, ref@BBBB */
-    ldr     r0, [rGLUE, #offGlue_methodClassDex]    @ r0<- glue->methodClassDex
+    ldr     r0, [rGLUE, #offGlue_method]    @ r0<- glue->method
     FETCH(r2, 1)                        @ r2<- BBBB
+    EXPORT_PC()                         @ export the PC
     mov     r1, rINST, lsr #8           @ r1<- AA
     bl      dvmThrowVerificationError   @ always throws
     b       common_exceptionThrown      @ handle exception
@@ -7969,8 +7968,7 @@
 /* continuation for OP_NEW_INSTANCE */
 
     .balign 32                          @ minimize cache lines
-.LOP_NEW_INSTANCE_finish: @ r0=class
-    bl      dvmAllocObject              @ r0<- new object
+.LOP_NEW_INSTANCE_finish: @ r0=new object
     mov     r3, rINST, lsr #8           @ r3<- AA
     cmp     r0, #0                      @ failed?
     beq     common_exceptionThrown      @ yes, handle the exception
@@ -8006,18 +8004,6 @@
     bne     .LOP_NEW_INSTANCE_resolved        @ no, continue
     b       common_exceptionThrown      @ yes, handle exception
 
-    /*
-     * We can't instantiate an abstract class or interface, so throw an
-     * InstantiationError with the class descriptor as the message.
-     *
-     *  r0 holds class object
-     */
-.LOP_NEW_INSTANCE_abstract:
-    ldr     r1, [r0, #offClassObject_descriptor]
-    ldr     r0, .LstrInstantiationErrorPtr
-    bl      dvmThrowExceptionWithClassMessage
-    b       common_exceptionThrown
-
 .LstrInstantiationErrorPtr:
     .word   .LstrInstantiationError
 
diff --git a/vm/mterp/out/InterpAsm-x86.S b/vm/mterp/out/InterpAsm-x86.S
index a6f88b4..2df6c20 100644
--- a/vm/mterp/out/InterpAsm-x86.S
+++ b/vm/mterp/out/InterpAsm-x86.S
@@ -5806,11 +5806,17 @@
 /* ------------------------------ */
     .balign 64
 .L_OP_THROW_VERIFICATION_ERROR: /* 0xed */
-/* File: x86/OP_THROW_VERIFICATION_ERROR.S */
-    /* TODO */
-    call    dvmAbort
-
-
+    /* (stub) */
+    GET_GLUE(%ecx)
+    SAVE_PC_TO_GLUE(%ecx)            # only need to export these two
+    SAVE_FP_TO_GLUE(%ecx)            # only need to export these two
+    movl %ecx,OUT_ARG0(%esp)         # glue is first arg to function
+    call      dvmMterp_OP_THROW_VERIFICATION_ERROR     # do the real work
+    GET_GLUE(%ecx)
+    LOAD_PC_FROM_GLUE(%ecx)          # retrieve updated values
+    LOAD_FP_FROM_GLUE(%ecx)          # retrieve updated values
+    FETCH_INST()
+    GOTO_NEXT
 /* ------------------------------ */
     .balign 64
 .L_OP_EXECUTE_INLINE: /* 0xee */
@@ -6391,6 +6397,7 @@
 /* continuation for OP_NEW_INSTANCE */
 
 .LOP_NEW_INSTANCE_initialized:  # on entry, ecx<- class
+    /* TODO: remove test for interface/abstract, now done in verifier */
     testl     $(ACC_INTERFACE|ACC_ABSTRACT),offClassObject_accessFlags(%ecx)
     movl      $ALLOC_DONT_TRACK,OUT_ARG1(%esp)
     jne       .LOP_NEW_INSTANCE_abstract
@@ -6441,6 +6448,7 @@
     jmp     common_exceptionThrown      # no, handle exception
 
     /*
+     * TODO: remove this
      * We can't instantiate an abstract class or interface, so throw an
      * InstantiationError with the class descriptor as the message.
      *
diff --git a/vm/mterp/out/InterpC-allstubs.c b/vm/mterp/out/InterpC-allstubs.c
index a37893a..420873e 100644
--- a/vm/mterp/out/InterpC-allstubs.c
+++ b/vm/mterp/out/InterpC-allstubs.c
@@ -1693,21 +1693,13 @@
             GOTO_exceptionThrown();
 
         /*
-         * Note: the verifier can ensure that this never happens, allowing us
-         * to remove the check.  However, the spec requires we throw the
-         * exception at runtime, not verify time, so the verifier would
-         * need to replace the new-instance call with a magic "throw
-         * InstantiationError" instruction.
-         *
-         * Since this relies on the verifier, which is optional, we would
-         * also need a "new-instance-quick" instruction to identify instances
-         * that don't require the check.
+         * Verifier now tests for interface/abstract class.
          */
-        if (dvmIsInterfaceClass(clazz) || dvmIsAbstractClass(clazz)) {
-            dvmThrowExceptionWithClassMessage("Ljava/lang/InstantiationError;",
-                clazz->descriptor);
-            GOTO_exceptionThrown();
-        }
+        //if (dvmIsInterfaceClass(clazz) || dvmIsAbstractClass(clazz)) {
+        //    dvmThrowExceptionWithClassMessage("Ljava/lang/InstantiationError;",
+        //        clazz->descriptor);
+        //    GOTO_exceptionThrown();
+        //}
         newObj = dvmAllocObject(clazz, ALLOC_DONT_TRACK);
         if (newObj == NULL)
             GOTO_exceptionThrown();
@@ -2805,9 +2797,10 @@
 
 /* File: c/OP_THROW_VERIFICATION_ERROR.c */
 HANDLE_OPCODE(OP_THROW_VERIFICATION_ERROR)
+    EXPORT_PC();
     vsrc1 = INST_AA(inst);
     ref = FETCH(1);             /* class/field/method ref */
-    dvmThrowVerificationError(methodClassDex, vsrc1, ref);
+    dvmThrowVerificationError(curMethod, vsrc1, ref);
     GOTO_exceptionThrown();
 OP_END
 
diff --git a/vm/mterp/out/InterpC-portdbg.c b/vm/mterp/out/InterpC-portdbg.c
index 60a146f..188639c 100644
--- a/vm/mterp/out/InterpC-portdbg.c
+++ b/vm/mterp/out/InterpC-portdbg.c
@@ -2037,21 +2037,13 @@
             GOTO_exceptionThrown();
 
         /*
-         * Note: the verifier can ensure that this never happens, allowing us
-         * to remove the check.  However, the spec requires we throw the
-         * exception at runtime, not verify time, so the verifier would
-         * need to replace the new-instance call with a magic "throw
-         * InstantiationError" instruction.
-         *
-         * Since this relies on the verifier, which is optional, we would
-         * also need a "new-instance-quick" instruction to identify instances
-         * that don't require the check.
+         * Verifier now tests for interface/abstract class.
          */
-        if (dvmIsInterfaceClass(clazz) || dvmIsAbstractClass(clazz)) {
-            dvmThrowExceptionWithClassMessage("Ljava/lang/InstantiationError;",
-                clazz->descriptor);
-            GOTO_exceptionThrown();
-        }
+        //if (dvmIsInterfaceClass(clazz) || dvmIsAbstractClass(clazz)) {
+        //    dvmThrowExceptionWithClassMessage("Ljava/lang/InstantiationError;",
+        //        clazz->descriptor);
+        //    GOTO_exceptionThrown();
+        //}
         newObj = dvmAllocObject(clazz, ALLOC_DONT_TRACK);
         if (newObj == NULL)
             GOTO_exceptionThrown();
@@ -3149,9 +3141,10 @@
 
 /* File: c/OP_THROW_VERIFICATION_ERROR.c */
 HANDLE_OPCODE(OP_THROW_VERIFICATION_ERROR)
+    EXPORT_PC();
     vsrc1 = INST_AA(inst);
     ref = FETCH(1);             /* class/field/method ref */
-    dvmThrowVerificationError(methodClassDex, vsrc1, ref);
+    dvmThrowVerificationError(curMethod, vsrc1, ref);
     GOTO_exceptionThrown();
 OP_END
 
diff --git a/vm/mterp/out/InterpC-portstd.c b/vm/mterp/out/InterpC-portstd.c
index 60f85b9..90d4ab4 100644
--- a/vm/mterp/out/InterpC-portstd.c
+++ b/vm/mterp/out/InterpC-portstd.c
@@ -1757,21 +1757,13 @@
             GOTO_exceptionThrown();
 
         /*
-         * Note: the verifier can ensure that this never happens, allowing us
-         * to remove the check.  However, the spec requires we throw the
-         * exception at runtime, not verify time, so the verifier would
-         * need to replace the new-instance call with a magic "throw
-         * InstantiationError" instruction.
-         *
-         * Since this relies on the verifier, which is optional, we would
-         * also need a "new-instance-quick" instruction to identify instances
-         * that don't require the check.
+         * Verifier now tests for interface/abstract class.
          */
-        if (dvmIsInterfaceClass(clazz) || dvmIsAbstractClass(clazz)) {
-            dvmThrowExceptionWithClassMessage("Ljava/lang/InstantiationError;",
-                clazz->descriptor);
-            GOTO_exceptionThrown();
-        }
+        //if (dvmIsInterfaceClass(clazz) || dvmIsAbstractClass(clazz)) {
+        //    dvmThrowExceptionWithClassMessage("Ljava/lang/InstantiationError;",
+        //        clazz->descriptor);
+        //    GOTO_exceptionThrown();
+        //}
         newObj = dvmAllocObject(clazz, ALLOC_DONT_TRACK);
         if (newObj == NULL)
             GOTO_exceptionThrown();
@@ -2869,9 +2861,10 @@
 
 /* File: c/OP_THROW_VERIFICATION_ERROR.c */
 HANDLE_OPCODE(OP_THROW_VERIFICATION_ERROR)
+    EXPORT_PC();
     vsrc1 = INST_AA(inst);
     ref = FETCH(1);             /* class/field/method ref */
-    dvmThrowVerificationError(methodClassDex, vsrc1, ref);
+    dvmThrowVerificationError(curMethod, vsrc1, ref);
     GOTO_exceptionThrown();
 OP_END
 
diff --git a/vm/mterp/out/InterpC-x86.c b/vm/mterp/out/InterpC-x86.c
index ac524f4..469b690 100644
--- a/vm/mterp/out/InterpC-x86.c
+++ b/vm/mterp/out/InterpC-x86.c
@@ -1193,6 +1193,15 @@
     FINISH(2);
 
 
+/* File: c/OP_THROW_VERIFICATION_ERROR.c */
+HANDLE_OPCODE(OP_THROW_VERIFICATION_ERROR)
+    EXPORT_PC();
+    vsrc1 = INST_AA(inst);
+    ref = FETCH(1);             /* class/field/method ref */
+    dvmThrowVerificationError(curMethod, vsrc1, ref);
+    GOTO_exceptionThrown();
+OP_END
+
 /* File: c/gotoTargets.c */
 /*
  * C footer.  This has some common code shared by the various targets.