Fix erroneous behaviors with OOME present.
Bug: 16454510
Change-Id: I757088a7b82ff73f58aba8d357080028b56442e6
diff --git a/runtime/class_linker.cc b/runtime/class_linker.cc
index 2d0b147..6c5679e 100644
--- a/runtime/class_linker.cc
+++ b/runtime/class_linker.cc
@@ -1658,23 +1658,24 @@
// size when the class becomes resolved.
klass.Assign(AllocClass(self, SizeOfClassWithoutEmbeddedTables(dex_file, dex_class_def)));
}
- if (UNLIKELY(klass.Get() == NULL)) {
+ if (UNLIKELY(klass.Get() == nullptr)) {
CHECK(self->IsExceptionPending()); // Expect an OOME.
- return NULL;
+ return nullptr;
}
klass->SetDexCache(FindDexCache(dex_file));
LoadClass(dex_file, dex_class_def, klass, class_loader.Get());
- // Check for a pending exception during load
- if (self->IsExceptionPending()) {
- klass->SetStatus(mirror::Class::kStatusError, self);
- return NULL;
- }
ObjectLock<mirror::Class> lock(self, klass);
+ if (self->IsExceptionPending()) {
+ // An exception occured during load, set status to erroneous while holding klass' lock in case
+ // notification is necessary.
+ klass->SetStatus(mirror::Class::kStatusError, self);
+ return nullptr;
+ }
klass->SetClinitThreadId(self->GetTid());
// Add the newly loaded class to the loaded classes table.
mirror::Class* existing = InsertClass(descriptor, klass.Get(), Hash(descriptor));
- if (existing != NULL) {
+ if (existing != nullptr) {
// We failed to insert because we raced with another thread. Calling EnsureResolved may cause
// this thread to block.
return EnsureResolved(self, descriptor, existing);
@@ -1685,7 +1686,7 @@
if (!LoadSuperAndInterfaces(klass, dex_file)) {
// Loading failed.
klass->SetStatus(mirror::Class::kStatusError, self);
- return NULL;
+ return nullptr;
}
CHECK(klass->IsLoaded());
// Link the class (if necessary)
@@ -1697,7 +1698,7 @@
if (!LinkClass(self, descriptor, klass, interfaces, &new_class)) {
// Linking failed.
klass->SetStatus(mirror::Class::kStatusError, self);
- return NULL;
+ return nullptr;
}
CHECK(new_class != nullptr) << descriptor;
CHECK(new_class->IsResolved()) << descriptor;
diff --git a/runtime/native/java_lang_Class.cc b/runtime/native/java_lang_Class.cc
index e577c2c..124bdf5 100644
--- a/runtime/native/java_lang_Class.cc
+++ b/runtime/native/java_lang_Class.cc
@@ -71,7 +71,10 @@
jthrowable cnfe = reinterpret_cast<jthrowable>(env->NewObject(WellKnownClasses::java_lang_ClassNotFoundException,
WellKnownClasses::java_lang_ClassNotFoundException_init,
javaName, cause.get()));
- env->Throw(cnfe);
+ if (cnfe != nullptr) {
+ // Make sure allocation didn't fail with an OOME.
+ env->Throw(cnfe);
+ }
return nullptr;
}
if (initialize) {
diff --git a/runtime/thread.cc b/runtime/thread.cc
index f888029..ba5f9d4 100644
--- a/runtime/thread.cc
+++ b/runtime/thread.cc
@@ -1138,7 +1138,7 @@
if (UNLIKELY(IsExceptionPending())) {
ScopedObjectAccess soa(Thread::Current());
mirror::Throwable* exception = GetException(nullptr);
- LOG(FATAL) << "Throwing new exception " << msg << " with unexpected pending exception: "
+ LOG(FATAL) << "Throwing new exception '" << msg << "' with unexpected pending exception: "
<< exception->Dump();
}
}