Merge "Hide some JDWP logging behind -verbose:jdwp." into dalvik-dev
diff --git a/src/class_linker.cc b/src/class_linker.cc
index 17f80d4..14f4b7e 100644
--- a/src/class_linker.cc
+++ b/src/class_linker.cc
@@ -2012,6 +2012,7 @@
if (klass->GetStatus() == Class::kStatusResolved) {
VerifyClass(klass);
if (klass->GetStatus() != Class::kStatusVerified) {
+ CHECK(self->IsExceptionPending());
return false;
}
}
@@ -2019,8 +2020,9 @@
clinit = klass->FindDeclaredDirectMethod("<clinit>", "()V");
if (clinit != NULL && !can_run_clinit) {
// if the class has a <clinit> but we can't run it during compilation,
- // don't bother going to kStatusInitializing
- return false;
+ // don't bother going to kStatusInitializing. We return true to maintain
+ // the invariant that a false result implies there is a pending exception.
+ return true;
}
// If the class is kStatusInitializing, either this thread is
@@ -2039,6 +2041,7 @@
}
if (!ValidateSuperClassDescriptors(klass)) {
+ CHECK(self->IsExceptionPending());
klass->SetStatus(Class::kStatusError);
return false;
}
@@ -2052,6 +2055,7 @@
uint64_t t0 = NanoTime();
if (!InitializeSuperClass(klass, can_run_clinit)) {
+ CHECK(self->IsExceptionPending());
return false;
}
@@ -2128,12 +2132,10 @@
if (klass->HasSuperClass() &&
klass->GetClassLoader() != klass->GetSuperClass()->GetClassLoader()) {
const Class* super = klass->GetSuperClass();
- for (int i = super->NumVirtualMethods() - 1; i >= 0; --i) {
- const Method* method = super->GetVirtualMethod(i);
- if (method != super->GetVirtualMethod(i) &&
- !HasSameMethodDescriptorClasses(method, super, klass)) {
- klass->DumpClass(std::cerr, Class::kDumpClassFullDetail);
-
+ for (int i = super->GetVTable()->GetLength() - 1; i >= 0; --i) {
+ const Method* method = klass->GetVTable()->Get(i);
+ if (method != super->GetVTable()->Get(i) &&
+ !IsSameMethodSignatureInDifferentClassContexts(method, super, klass)) {
ThrowLinkageError("Class %s method %s resolves differently in superclass %s",
PrettyDescriptor(klass).c_str(), PrettyMethod(method).c_str(),
PrettyDescriptor(super).c_str());
@@ -2147,10 +2149,8 @@
if (klass->GetClassLoader() != interface->GetClassLoader()) {
for (size_t j = 0; j < interface->NumVirtualMethods(); ++j) {
const Method* method = interface_entry->GetMethodArray()->Get(j);
- if (!HasSameMethodDescriptorClasses(method, interface,
- method->GetDeclaringClass())) {
- klass->DumpClass(std::cerr, Class::kDumpClassFullDetail);
-
+ if (!IsSameMethodSignatureInDifferentClassContexts(method, interface,
+ method->GetDeclaringClass())) {
ThrowLinkageError("Class %s method %s resolves differently in interface %s",
PrettyDescriptor(method->GetDeclaringClass()).c_str(),
PrettyMethod(method).c_str(),
@@ -2163,9 +2163,11 @@
return true;
}
-bool ClassLinker::HasSameMethodDescriptorClasses(const Method* method,
- const Class* klass1,
- const Class* klass2) {
+// Returns true if classes referenced by the signature of the method are the
+// same classes in klass1 as they are in klass2.
+bool ClassLinker::IsSameMethodSignatureInDifferentClassContexts(const Method* method,
+ const Class* klass1,
+ const Class* klass2) {
if (klass1 == klass2) {
return true;
}
@@ -2179,7 +2181,7 @@
}
if (descriptor[0] == 'L' || descriptor[0] == '[') {
// Found a non-primitive type.
- if (!HasSameDescriptorClasses(descriptor, klass1, klass2)) {
+ if (!IsSameDescriptorInDifferentClassContexts(descriptor, klass1, klass2)) {
return false;
}
}
@@ -2187,18 +2189,17 @@
// Check the return type
const char* descriptor = dex_file.GetReturnTypeDescriptor(proto_id);
if (descriptor[0] == 'L' || descriptor[0] == '[') {
- if (!HasSameDescriptorClasses(descriptor, klass1, klass2)) {
+ if (!IsSameDescriptorInDifferentClassContexts(descriptor, klass1, klass2)) {
return false;
}
}
return true;
}
-// Returns true if classes referenced by the descriptor are the
-// same classes in klass1 as they are in klass2.
-bool ClassLinker::HasSameDescriptorClasses(const char* descriptor,
- const Class* klass1,
- const Class* klass2) {
+// Returns true if the descriptor resolves to the same class in the context of klass1 and klass2.
+bool ClassLinker::IsSameDescriptorInDifferentClassContexts(const char* descriptor,
+ const Class* klass1,
+ const Class* klass2) {
CHECK(descriptor != NULL);
CHECK(klass1 != NULL);
CHECK(klass2 != NULL);
@@ -2206,16 +2207,14 @@
return true;
}
Class* found1 = FindClass(descriptor, klass1->GetClassLoader());
- // TODO: found1 == NULL
- Class* found2 = FindClass(descriptor, klass2->GetClassLoader());
- // TODO: found2 == NULL
- // TODO: lookup found1 in initiating loader list
- if (found1 == NULL || found2 == NULL) {
+ if (found1 == NULL) {
Thread::Current()->ClearException();
- return found1 == found2;
- } else {
- return true;
}
+ Class* found2 = FindClass(descriptor, klass2->GetClassLoader());
+ if (found2 == NULL) {
+ Thread::Current()->ClearException();
+ }
+ return found1 == found2;
}
bool ClassLinker::InitializeSuperClass(Class* klass, bool can_run_clinit) {
@@ -2253,8 +2252,11 @@
Thread* self = Thread::Current();
ScopedThreadStateChange tsc(self, Thread::kRunnable);
- InitializeClass(c, can_run_clinit);
- return !self->IsExceptionPending();
+ bool success = InitializeClass(c, can_run_clinit);
+ if (!success) {
+ CHECK(self->IsExceptionPending());
+ }
+ return success;
}
void ClassLinker::ConstructFieldMap(const DexFile& dex_file, const DexFile::ClassDef& dex_class_def,
diff --git a/src/class_linker.h b/src/class_linker.h
index 7d94e95..45b1aa2 100644
--- a/src/class_linker.h
+++ b/src/class_linker.h
@@ -347,13 +347,13 @@
bool InitializeSuperClass(Class* klass, bool can_run_clinit);
void InitializeStaticFields(Class* klass);
- bool HasSameDescriptorClasses(const char* descriptor,
- const Class* klass1,
- const Class* klass2);
+ bool IsSameDescriptorInDifferentClassContexts(const char* descriptor,
+ const Class* klass1,
+ const Class* klass2);
- bool HasSameMethodDescriptorClasses(const Method* descriptor,
- const Class* klass1,
- const Class* klass2);
+ bool IsSameMethodSignatureInDifferentClassContexts(const Method* descriptor,
+ const Class* klass1,
+ const Class* klass2);
bool LinkClass(SirtRef<Class>& klass, ObjectArray<Class>* interfaces);
diff --git a/src/compiler/codegen/arm/MethodCodegenDriver.cc b/src/compiler/codegen/arm/MethodCodegenDriver.cc
index 08a53bd..7ad974c 100644
--- a/src/compiler/codegen/arm/MethodCodegenDriver.cc
+++ b/src/compiler/codegen/arm/MethodCodegenDriver.cc
@@ -759,7 +759,7 @@
tReg = oatAllocTemp(cUnit);
loadWordDisp(cUnit, r0, art::Array::LengthOffset().Int32Value(),
tReg);
- genRegRegCheck(cUnit, kArmCondCs, tReg, rLR, mir,
+ genRegRegCheck(cUnit, kArmCondCs, rLR, tReg, mir,
kArmThrowNoSuchMethod);
oatFreeTemp(cUnit, tReg);
}
@@ -2203,7 +2203,7 @@
OFFSETOF_MEMBER(Thread, pThrowNegArraySizeFromCode);
break;
case kArmThrowNoSuchMethod:
- genRegCopy(cUnit, r0, v2);
+ genRegCopy(cUnit, r0, v1);
funcOffset =
OFFSETOF_MEMBER(Thread, pThrowNoSuchMethodFromCode);
break;