Merge "Fix the weird state transitions in verification." into dalvik-dev
diff --git a/src/class_linker.cc b/src/class_linker.cc
index 7225764..71abb21 100644
--- a/src/class_linker.cc
+++ b/src/class_linker.cc
@@ -533,7 +533,7 @@
Class* c = GetClassRoot(ClassRoot(i));
if (!c->IsArrayClass() && !c->IsPrimitive()) {
EnsureInitialized(GetClassRoot(ClassRoot(i)), true);
- CHECK(!self->IsExceptionPending());
+ CHECK(!self->IsExceptionPending()) << PrettyTypeOf(self->GetException());
}
}
}
@@ -1368,10 +1368,12 @@
klass->SetStatus(Class::kStatusVerified);
} else {
LOG(ERROR) << "Verification failed on class " << PrettyClass(klass);
- CHECK(!Thread::Current()->IsExceptionPending()) << PrettyTypeOf(Thread::Current()->GetException());
-
+ Thread* self = Thread::Current();
+ CHECK(!self->IsExceptionPending()) << PrettyTypeOf(self->GetException());
+ self->ThrowNewExceptionF("Ljava/lang/VerifyError;", "Verification of %s failed",
+ PrettyDescriptor(klass->GetDescriptor()).c_str());
CHECK_EQ(klass->GetStatus(), Class::kStatusVerifying);
- klass->SetStatus(Class::kStatusResolved);
+ klass->SetStatus(Class::kStatusError);
}
}
@@ -1465,7 +1467,7 @@
bool ClassLinker::WaitForInitializeClass(Class* klass, Thread* self, ObjectLock& lock) {
while (true) {
- CHECK(!self->IsExceptionPending());
+ CHECK(!self->IsExceptionPending()) << PrettyTypeOf(self->GetException());
lock.Wait();
// When we wake up, repeat the test for init-in-progress. If
diff --git a/src/compiler.cc b/src/compiler.cc
index c6705a6..f4e8874 100644
--- a/src/compiler.cc
+++ b/src/compiler.cc
@@ -201,6 +201,15 @@
}
CHECK(klass->IsResolved()) << PrettyClass(klass);
class_linker->VerifyClass(klass);
+
+ if (klass->IsErroneous()) {
+ // ClassLinker::VerifyClass throws, which isn't useful in the compiler.
+ CHECK(Thread::Current()->IsExceptionPending());
+ Thread::Current()->ClearException();
+ // We want to try verification again at run-time, so move back into the resolved state.
+ klass->SetStatus(Class::kStatusResolved);
+ }
+
CHECK(klass->IsVerified() || klass->IsResolved()) << PrettyClass(klass);
CHECK(!Thread::Current()->IsExceptionPending()) << PrettyTypeOf(Thread::Current()->GetException());
}
diff --git a/src/object.cc b/src/object.cc
index b812b90..342599e 100644
--- a/src/object.cc
+++ b/src/object.cc
@@ -795,21 +795,18 @@
}
void Class::SetStatus(Status new_status) {
- CHECK(new_status > GetStatus() || new_status == kStatusError ||
- !Runtime::Current()->IsStarted()) << PrettyClass(this);
+ CHECK(new_status > GetStatus() || new_status == kStatusError || !Runtime::Current()->IsStarted())
+ << PrettyClass(this) << " " << GetStatus() << " -> " << new_status;
CHECK(sizeof(Status) == sizeof(uint32_t)) << PrettyClass(this);
- return SetField32(OFFSET_OF_OBJECT_MEMBER(Class, status_),
- new_status, false);
+ return SetField32(OFFSET_OF_OBJECT_MEMBER(Class, status_), new_status, false);
}
DexCache* Class::GetDexCache() const {
- return GetFieldObject<DexCache*>(
- OFFSET_OF_OBJECT_MEMBER(Class, dex_cache_), false);
+ return GetFieldObject<DexCache*>(OFFSET_OF_OBJECT_MEMBER(Class, dex_cache_), false);
}
void Class::SetDexCache(DexCache* new_dex_cache) {
- SetFieldObject(OFFSET_OF_OBJECT_MEMBER(Class, dex_cache_),
- new_dex_cache, false);
+ SetFieldObject(OFFSET_OF_OBJECT_MEMBER(Class, dex_cache_), new_dex_cache, false);
}
Object* Class::AllocObject() {