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())) {