Merge "Improve consistency of units in logging." into dalvik-dev
diff --git a/src/class_linker.cc b/src/class_linker.cc
index dd8fc11..88016f4 100644
--- a/src/class_linker.cc
+++ b/src/class_linker.cc
@@ -2183,11 +2183,13 @@
   }
   // Verify
   if (super->IsFinal() || super->IsInterface()) {
-    Thread::Current()->ThrowNewExceptionF("Ljava/lang/IncompatibleClassChangeError;",
+    Thread* thread = Thread::Current();
+    thread->ThrowNewExceptionF("Ljava/lang/IncompatibleClassChangeError;",
         "Superclass %s of %s is %s",
         PrettyDescriptor(super).c_str(),
         PrettyDescriptor(klass.get()).c_str(),
         super->IsFinal() ? "declared final" : "an interface");
+    klass->SetVerifyErrorClass(thread->GetException()->GetClass());
     return false;
   }
   if (!klass->CanAccess(super)) {
@@ -2347,10 +2349,12 @@
     DCHECK(interface != NULL);
     if (!interface->IsInterface()) {
       ClassHelper ih(interface);
-      Thread::Current()->ThrowNewExceptionF("Ljava/lang/IncompatibleClassChangeError;",
+      Thread* thread = Thread::Current();
+      thread->ThrowNewExceptionF("Ljava/lang/IncompatibleClassChangeError;",
           "Class %s implements non-interface class %s",
           PrettyDescriptor(klass.get()).c_str(),
           PrettyDescriptor(ih.GetDescriptor()).c_str());
+      klass->SetVerifyErrorClass(thread->GetException()->GetClass());
       return false;
     }
     // Add this interface.
diff --git a/src/dex_verifier.cc b/src/dex_verifier.cc
index 9094067..9ba5d34 100644
--- a/src/dex_verifier.cc
+++ b/src/dex_verifier.cc
@@ -3085,8 +3085,8 @@
       (method_type == METHOD_STATIC && !res_method->IsStatic()) ||
       ((method_type == METHOD_VIRTUAL || method_type == METHOD_INTERFACE) && res_method->IsDirect())
       ) {
-    Fail(VERIFY_ERROR_GENERIC) << "invoke type does not match method type of "
-                               << PrettyMethod(res_method);
+    Fail(VERIFY_ERROR_CLASS_CHANGE) << "invoke type does not match method type of "
+                                    << PrettyMethod(res_method);
     return NULL;
   }
   // If we're using invoke-super(method), make sure that the executing method's class' superclass
@@ -3294,7 +3294,9 @@
               << " incompatible with aput of type " << insn_type;
         } else {
           // The instruction agrees with the type of array, confirm the value to be stored does too
-          work_line_->VerifyRegisterType(dec_insn.vA_, component_type);
+          // Note: we use the instruction type (rather than the component type) for aput-object as
+          // incompatible classes will be caught at runtime as an array store exception
+          work_line_->VerifyRegisterType(dec_insn.vA_, is_primitive ? component_type : insn_type);
         }
       }
     }
diff --git a/src/object.h b/src/object.h
index eb37987..80bb000 100644
--- a/src/object.h
+++ b/src/object.h
@@ -1681,7 +1681,7 @@
   }
 
   void SetVerifyErrorClass(Class* klass) {
-    klass->SetFieldObject(OFFSET_OF_OBJECT_MEMBER(Class, verify_error_class_), klass, false);
+    SetFieldObject(OFFSET_OF_OBJECT_MEMBER(Class, verify_error_class_), klass, false);
   }
 
   uint16_t GetDexTypeIndex() const {
diff --git a/src/runtime_support.cc b/src/runtime_support.cc
index 3a3eaf1..1222626 100644
--- a/src/runtime_support.cc
+++ b/src/runtime_support.cc
@@ -407,12 +407,19 @@
   // Resolve method filling in dex cache
   Method* called = linker->ResolveMethod(method_idx, *caller_sp, true);
   if (LIKELY(!thread->IsExceptionPending())) {
-    // Update CodeAndDirectMethod table
-    Method* caller = *caller_sp;
-    DexCache* dex_cache = caller->GetDeclaringClass()->GetDexCache();
-    dex_cache->GetCodeAndDirectMethods()->SetResolvedDirectMethod(method_idx, called);
-    // We got this far, ensure that the declaring class is initialized
-    linker->EnsureInitialized(called->GetDeclaringClass(), true);
+    if (LIKELY(called->IsDirect())) {
+      // Update CodeAndDirectMethod table
+      Method* caller = *caller_sp;
+      DexCache* dex_cache = caller->GetDeclaringClass()->GetDexCache();
+      dex_cache->GetCodeAndDirectMethods()->SetResolvedDirectMethod(method_idx, called);
+      // We got this far, ensure that the declaring class is initialized
+      linker->EnsureInitialized(called->GetDeclaringClass(), true);
+    } else {
+      // Direct method has been made virtual
+      thread->ThrowNewExceptionF("Ljava/lang/IncompatibleClassChangeError;",
+                                 "Expected direct method but found virtual: %s",
+                                 PrettyMethod(called, true).c_str());
+    }
   }
   void* code;
   if (UNLIKELY(thread->IsExceptionPending())) {