diff options
| -rw-r--r-- | runtime/class_linker.cc | 21 | ||||
| -rw-r--r-- | runtime/entrypoints/entrypoint_utils-inl.h | 4 |
2 files changed, 22 insertions, 3 deletions
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc index d8f01db776..c8fed5a6cb 100644 --- a/runtime/class_linker.cc +++ b/runtime/class_linker.cc @@ -2062,6 +2062,7 @@ mirror::Class* ClassLinker::DefineClass(const char* descriptor, } return nullptr; } + self->AssertNoPendingException(); CHECK(new_class != nullptr) << descriptor; CHECK(new_class->IsResolved()) << descriptor; @@ -3939,6 +3940,8 @@ bool ClassLinker::InitializeClass(ConstHandle<mirror::Class> klass, bool can_ini CHECK_EQ(klass->GetStatus(), mirror::Class::kStatusRetryVerificationAtRuntime); } return false; + } else { + self->AssertNoPendingException(); } } @@ -3948,6 +3951,10 @@ bool ClassLinker::InitializeClass(ConstHandle<mirror::Class> klass, bool can_ini // invocation of InitializeClass will not be responsible for // running <clinit> and will return. if (klass->GetStatus() == mirror::Class::kStatusInitializing) { + // Could have got an exception during verification. + if (self->IsExceptionPending()) { + return false; + } // We caught somebody else in the act; was it us? if (klass->GetClinitThreadId() == self->GetTid()) { // Yes. That's fine. Return so we can continue initializing. @@ -4152,9 +4159,17 @@ bool ClassLinker::ValidateSuperClassDescriptors(ConstHandle<mirror::Class> klass bool ClassLinker::EnsureInitialized(ConstHandle<mirror::Class> c, bool can_init_fields, bool can_init_parents) { DCHECK(c.Get() != nullptr); - const bool success = c->IsInitialized() || InitializeClass(c, can_init_fields, can_init_parents); - if (!success && can_init_fields && can_init_parents) { - CHECK(Thread::Current()->IsExceptionPending()) << PrettyClass(c.Get()); + if (c->IsInitialized()) { + return true; + } + const bool success = InitializeClass(c, can_init_fields, can_init_parents); + Thread* self = Thread::Current(); + if (!success) { + if (can_init_fields && can_init_parents) { + CHECK(self->IsExceptionPending()) << PrettyClass(c.Get()); + } + } else { + self->AssertNoPendingException(); } return success; } diff --git a/runtime/entrypoints/entrypoint_utils-inl.h b/runtime/entrypoints/entrypoint_utils-inl.h index b874a74e7c..38842cb8c2 100644 --- a/runtime/entrypoints/entrypoint_utils-inl.h +++ b/runtime/entrypoints/entrypoint_utils-inl.h @@ -48,6 +48,8 @@ static inline mirror::Class* CheckObjectAlloc(uint32_t type_idx, if (klass == NULL) { DCHECK(self->IsExceptionPending()); return nullptr; // Failure + } else { + DCHECK(!self->IsExceptionPending()); } } if (kAccessCheck) { @@ -80,6 +82,8 @@ static inline mirror::Class* CheckObjectAlloc(uint32_t type_idx, if (!Runtime::Current()->GetClassLinker()->EnsureInitialized(h_klass, true, true)) { DCHECK(self->IsExceptionPending()); return nullptr; // Failure + } else { + DCHECK(!self->IsExceptionPending()); } return h_klass.Get(); } |