summaryrefslogtreecommitdiff
path: root/runtime/runtime.cc
diff options
context:
space:
mode:
Diffstat (limited to 'runtime/runtime.cc')
-rw-r--r--runtime/runtime.cc102
1 files changed, 62 insertions, 40 deletions
diff --git a/runtime/runtime.cc b/runtime/runtime.cc
index 0d9d16cd01..1e327fc8ed 100644
--- a/runtime/runtime.cc
+++ b/runtime/runtime.cc
@@ -1090,6 +1090,17 @@ void Runtime::SetSentinel(mirror::Object* sentinel) {
sentinel_ = GcRoot<mirror::Object>(sentinel);
}
+static inline void InitPreAllocatedException(Thread* self,
+ GcRoot<mirror::Throwable>* exception,
+ const char* exception_class_descriptor,
+ const char* msg)
+ REQUIRES_SHARED(Locks::mutator_lock_) {
+ DCHECK_EQ(self, Thread::Current());
+ self->ThrowNewException(exception_class_descriptor, msg);
+ *exception = GcRoot<mirror::Throwable>(self->GetException());
+ self->ClearException();
+}
+
bool Runtime::Init(RuntimeArgumentMap&& runtime_options_in) {
// (b/30160149): protect subprocesses from modifications to LD_LIBRARY_PATH, etc.
// Take a snapshot of the environment at the time the runtime was created, for use by Exec, etc.
@@ -1505,34 +1516,54 @@ 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.
- 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.
- InitPreAllocatedException(self,
- &Runtime::pre_allocated_NoClassDefFoundError_,
- "Ljava/lang/NoClassDefFoundError;",
- "Class not found using the boot class loader; "
- "no stack trace available");
+ if (GetHeap()->HasBootImageSpace()) {
+ const ImageHeader& image_header = GetHeap()->GetBootImageSpaces()[0]->GetImageHeader();
+ pre_allocated_OutOfMemoryError_when_throwing_exception_ = GcRoot<mirror::Throwable>(
+ image_header.GetImageRoot(ImageHeader::kOomeWhenThrowingException)->AsThrowable());
+ DCHECK(pre_allocated_OutOfMemoryError_when_throwing_exception_.Read()->GetClass()
+ ->DescriptorEquals("Ljava/lang/OutOfMemoryError;"));
+ pre_allocated_OutOfMemoryError_when_throwing_oome_ = GcRoot<mirror::Throwable>(
+ image_header.GetImageRoot(ImageHeader::kOomeWhenThrowingOome)->AsThrowable());
+ DCHECK(pre_allocated_OutOfMemoryError_when_throwing_oome_.Read()->GetClass()
+ ->DescriptorEquals("Ljava/lang/OutOfMemoryError;"));
+ pre_allocated_OutOfMemoryError_when_handling_stack_overflow_ = GcRoot<mirror::Throwable>(
+ image_header.GetImageRoot(ImageHeader::kOomeWhenHandlingStackOverflow)->AsThrowable());
+ DCHECK(pre_allocated_OutOfMemoryError_when_handling_stack_overflow_.Read()->GetClass()
+ ->DescriptorEquals("Ljava/lang/OutOfMemoryError;"));
+ pre_allocated_NoClassDefFoundError_ = GcRoot<mirror::Throwable>(
+ image_header.GetImageRoot(ImageHeader::kNoClassDefFoundError)->AsThrowable());
+ DCHECK(pre_allocated_NoClassDefFoundError_.Read()->GetClass()
+ ->DescriptorEquals("Ljava/lang/NoClassDefFoundError;"));
+ } else {
+ // Pre-allocate an OutOfMemoryError for the case when we fail to
+ // allocate the exception to be thrown.
+ InitPreAllocatedException(self,
+ &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.
+ InitPreAllocatedException(self,
+ &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,
+ &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.
+ InitPreAllocatedException(self,
+ &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.
@@ -1682,16 +1713,6 @@ void Runtime::AttachAgent(JNIEnv* env, const std::string& agent_arg, jobject cla
}
}
-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();
@@ -2048,9 +2069,10 @@ void Runtime::VisitImageRoots(RootVisitor* visitor) {
auto* image_space = space->AsImageSpace();
const auto& image_header = image_space->GetImageHeader();
for (int32_t i = 0, size = image_header.GetImageRoots()->GetLength(); i != size; ++i) {
- auto* obj = image_header.GetImageRoot(static_cast<ImageHeader::ImageRoot>(i));
+ mirror::Object* obj =
+ image_header.GetImageRoot(static_cast<ImageHeader::ImageRoot>(i)).Ptr();
if (obj != nullptr) {
- auto* after_obj = obj;
+ mirror::Object* after_obj = obj;
visitor->VisitRoot(&after_obj, RootInfo(kRootStickyClass));
CHECK_EQ(after_obj, obj);
}