diff options
Diffstat (limited to 'runtime/runtime.cc')
| -rw-r--r-- | runtime/runtime.cc | 72 |
1 files changed, 59 insertions, 13 deletions
diff --git a/runtime/runtime.cc b/runtime/runtime.cc index f550a151bb..c394fefb38 100644 --- a/runtime/runtime.cc +++ b/runtime/runtime.cc @@ -1503,19 +1503,34 @@ bool Runtime::Init(RuntimeArgumentMap&& runtime_options_in) { // TODO: move this to just be an Trace::Start argument Trace::SetDefaultClockSource(runtime_options.GetOrDefault(Opt::ProfileClock)); + // Pre-allocate an OutOfMemoryError for the case when we fail to + // allocate the exception to be thrown. + InitPreAllocatedException(self, + &Runtime::pre_allocated_OutOfMemoryError_when_throwing_exception_, + "Ljava/lang/OutOfMemoryError;", + "OutOfMemoryError thrown while trying to throw an exception; " + "no stack trace available"); // Pre-allocate an OutOfMemoryError for the double-OOME case. - self->ThrowNewException("Ljava/lang/OutOfMemoryError;", - "OutOfMemoryError thrown while trying to throw OutOfMemoryError; " - "no stack trace available"); - pre_allocated_OutOfMemoryError_ = GcRoot<mirror::Throwable>(self->GetException()); - self->ClearException(); + InitPreAllocatedException(self, + &Runtime::pre_allocated_OutOfMemoryError_when_throwing_oome_, + "Ljava/lang/OutOfMemoryError;", + "OutOfMemoryError thrown while trying to throw OutOfMemoryError; " + "no stack trace available"); + // Pre-allocate an OutOfMemoryError for the case when we fail to + // allocate while handling a stack overflow. + InitPreAllocatedException(self, + &Runtime::pre_allocated_OutOfMemoryError_when_handling_stack_overflow_, + "Ljava/lang/OutOfMemoryError;", + "OutOfMemoryError thrown while trying to handle a stack overflow; " + "no stack trace available"); // Pre-allocate a NoClassDefFoundError for the common case of failing to find a system class // ahead of checking the application's class loader. - self->ThrowNewException("Ljava/lang/NoClassDefFoundError;", - "Class not found using the boot class loader; no stack trace available"); - pre_allocated_NoClassDefFoundError_ = GcRoot<mirror::Throwable>(self->GetException()); - self->ClearException(); + InitPreAllocatedException(self, + &Runtime::pre_allocated_NoClassDefFoundError_, + "Ljava/lang/NoClassDefFoundError;", + "Class not found using the boot class loader; " + "no stack trace available"); // Runtime initialization is largely done now. // We load plugins first since that can modify the runtime state slightly. @@ -1666,6 +1681,16 @@ void Runtime::AttachAgent(JNIEnv* env, } } +void Runtime::InitPreAllocatedException(Thread* self, + GcRoot<mirror::Throwable> Runtime::* exception, + const char* exception_class_descriptor, + const char* msg) { + DCHECK_EQ(self, Thread::Current()); + self->ThrowNewException(exception_class_descriptor, msg); + this->*exception = GcRoot<mirror::Throwable>(self->GetException()); + self->ClearException(); +} + void Runtime::InitNativeMethods() { VLOG(startup) << "Runtime::InitNativeMethods entering"; Thread* self = Thread::Current(); @@ -1917,10 +1942,26 @@ void Runtime::DetachCurrentThread() { thread_list_->Unregister(self); } -mirror::Throwable* Runtime::GetPreAllocatedOutOfMemoryError() { - mirror::Throwable* oome = pre_allocated_OutOfMemoryError_.Read(); +mirror::Throwable* Runtime::GetPreAllocatedOutOfMemoryErrorWhenThrowingException() { + mirror::Throwable* oome = pre_allocated_OutOfMemoryError_when_throwing_exception_.Read(); + if (oome == nullptr) { + LOG(ERROR) << "Failed to return pre-allocated OOME-when-throwing-exception"; + } + return oome; +} + +mirror::Throwable* Runtime::GetPreAllocatedOutOfMemoryErrorWhenThrowingOOME() { + mirror::Throwable* oome = pre_allocated_OutOfMemoryError_when_throwing_oome_.Read(); + if (oome == nullptr) { + LOG(ERROR) << "Failed to return pre-allocated OOME-when-throwing-OOME"; + } + return oome; +} + +mirror::Throwable* Runtime::GetPreAllocatedOutOfMemoryErrorWhenHandlingStackOverflow() { + mirror::Throwable* oome = pre_allocated_OutOfMemoryError_when_handling_stack_overflow_.Read(); if (oome == nullptr) { - LOG(ERROR) << "Failed to return pre-allocated OOME"; + LOG(ERROR) << "Failed to return pre-allocated OOME-when-handling-stack-overflow"; } return oome; } @@ -2005,7 +2046,12 @@ void Runtime::VisitTransactionRoots(RootVisitor* visitor) { void Runtime::VisitNonThreadRoots(RootVisitor* visitor) { java_vm_->VisitRoots(visitor); sentinel_.VisitRootIfNonNull(visitor, RootInfo(kRootVMInternal)); - pre_allocated_OutOfMemoryError_.VisitRootIfNonNull(visitor, RootInfo(kRootVMInternal)); + pre_allocated_OutOfMemoryError_when_throwing_exception_ + .VisitRootIfNonNull(visitor, RootInfo(kRootVMInternal)); + pre_allocated_OutOfMemoryError_when_throwing_oome_ + .VisitRootIfNonNull(visitor, RootInfo(kRootVMInternal)); + pre_allocated_OutOfMemoryError_when_handling_stack_overflow_ + .VisitRootIfNonNull(visitor, RootInfo(kRootVMInternal)); pre_allocated_NoClassDefFoundError_.VisitRootIfNonNull(visitor, RootInfo(kRootVMInternal)); verifier::MethodVerifier::VisitStaticRoots(visitor); VisitTransactionRoots(visitor); |