diff options
Diffstat (limited to 'runtime/runtime.cc')
| -rw-r--r-- | runtime/runtime.cc | 113 |
1 files changed, 79 insertions, 34 deletions
diff --git a/runtime/runtime.cc b/runtime/runtime.cc index 1e327fc8ed..a81c4d0518 100644 --- a/runtime/runtime.cc +++ b/runtime/runtime.cc @@ -240,7 +240,7 @@ Runtime::Runtime() exit_(nullptr), abort_(nullptr), stats_enabled_(false), - is_running_on_memory_tool_(RUNNING_ON_MEMORY_TOOL), + is_running_on_memory_tool_(kRunningOnMemoryTool), instrumentation_(), main_thread_group_(nullptr), system_thread_group_(nullptr), @@ -713,6 +713,23 @@ std::string Runtime::GetCompilerExecutable() const { return compiler_executable; } +void Runtime::RunRootClinits(Thread* self) { + class_linker_->RunRootClinits(self); + + GcRoot<mirror::Throwable>* exceptions[] = { + &pre_allocated_OutOfMemoryError_when_throwing_exception_, + // &pre_allocated_OutOfMemoryError_when_throwing_oome_, // Same class as above. + // &pre_allocated_OutOfMemoryError_when_handling_stack_overflow_, // Same class as above. + &pre_allocated_NoClassDefFoundError_, + }; + for (GcRoot<mirror::Throwable>* exception : exceptions) { + StackHandleScope<1> hs(self); + Handle<mirror::Class> klass = hs.NewHandle<mirror::Class>(exception->Read()->GetClass()); + class_linker_->EnsureInitialized(self, klass, true, true); + self->AssertNoPendingException(); + } +} + bool Runtime::Start() { VLOG(startup) << "Runtime::Start entering"; @@ -742,8 +759,10 @@ bool Runtime::Start() { auto field_class(hs.NewHandle<mirror::Class>(GetClassRoot<mirror::Field>(class_roots))); class_linker_->EnsureInitialized(soa.Self(), class_class, true, true); + self->AssertNoPendingException(); // Field class is needed for register_java_net_InetAddress in libcore, b/28153851. class_linker_->EnsureInitialized(soa.Self(), field_class, true, true); + self->AssertNoPendingException(); } // InitNativeMethods needs to be after started_ so that the classes @@ -1020,7 +1039,7 @@ static bool OpenDexFilesFromImage(const std::string& image_location, return false; } - for (const OatFile::OatDexFile* oat_dex_file : oat_file->GetOatDexFiles()) { + for (const OatDexFile* oat_dex_file : oat_file->GetOatDexFiles()) { if (oat_dex_file == nullptr) { *failures += 1; continue; @@ -1090,15 +1109,30 @@ 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) +static inline void CreatePreAllocatedException(Thread* self, + Runtime* runtime, + 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(); + ClassLinker* class_linker = runtime->GetClassLinker(); + // Allocate an object without initializing the class to allow non-trivial Throwable.<clinit>(). + ObjPtr<mirror::Class> klass = class_linker->FindSystemClass(self, exception_class_descriptor); + CHECK(klass != nullptr); + gc::AllocatorType allocator_type = runtime->GetHeap()->GetCurrentAllocator(); + ObjPtr<mirror::Throwable> exception_object = ObjPtr<mirror::Throwable>::DownCast( + klass->Alloc</* kIsInstrumented */ true>(self, allocator_type)); + CHECK(exception_object != nullptr); + *exception = GcRoot<mirror::Throwable>(exception_object); + // Initialize the "detailMessage" field. + ObjPtr<mirror::String> message = mirror::String::AllocFromModifiedUtf8(self, msg); + CHECK(message != nullptr); + ObjPtr<mirror::Class> throwable = GetClassRoot<mirror::Throwable>(class_linker); + ArtField* detailMessageField = + throwable->FindDeclaredInstanceField("detailMessage", "Ljava/lang/String;"); + CHECK(detailMessageField != nullptr); + detailMessageField->SetObject</* kTransactionActive */ false>(exception->Read(), message); } bool Runtime::Init(RuntimeArgumentMap&& runtime_options_in) { @@ -1283,7 +1317,8 @@ bool Runtime::Init(RuntimeArgumentMap&& runtime_options_in) { dump_gc_performance_on_shutdown_ = runtime_options.Exists(Opt::DumpGCPerformanceOnShutdown); jdwp_options_ = runtime_options.GetOrDefault(Opt::JdwpOptions); - jdwp_provider_ = runtime_options.GetOrDefault(Opt::JdwpProvider); + jdwp_provider_ = CanonicalizeJdwpProvider(runtime_options.GetOrDefault(Opt::JdwpProvider), + IsJavaDebuggable()); switch (jdwp_provider_) { case JdwpProvider::kNone: { VLOG(jdwp) << "Disabling all JDWP support."; @@ -1317,6 +1352,11 @@ bool Runtime::Init(RuntimeArgumentMap&& runtime_options_in) { constexpr const char* plugin_name = kIsDebugBuild ? "libadbconnectiond.so" : "libadbconnection.so"; plugins_.push_back(Plugin::Create(plugin_name)); + break; + } + case JdwpProvider::kUnset: { + LOG(FATAL) << "Illegal jdwp provider " << jdwp_provider_ << " was not filtered out!"; + break; } } callbacks_->AddThreadLifecycleCallback(Dbg::GetThreadLifecycleCallback()); @@ -1362,8 +1402,8 @@ bool Runtime::Init(RuntimeArgumentMap&& runtime_options_in) { case InstructionSet::kMips: case InstructionSet::kMips64: implicit_null_checks_ = true; - // Installing stack protection does not play well with valgrind. - implicit_so_checks_ = !(RUNNING_ON_MEMORY_TOOL && kMemoryToolIsValgrind); + // Historical note: Installing stack protection was not playing well with Valgrind. + implicit_so_checks_ = true; break; default: // Keep the defaults. @@ -1378,8 +1418,8 @@ bool Runtime::Init(RuntimeArgumentMap&& runtime_options_in) { // These need to be in a specific order. The null point check handler must be // after the suspend check and stack overflow check handlers. // - // Note: the instances attach themselves to the fault manager and are handled by it. The manager - // will delete the instance on Shutdown(). + // Note: the instances attach themselves to the fault manager and are handled by it. The + // manager will delete the instance on Shutdown(). if (implicit_suspend_checks_) { new SuspensionHandler(&fault_manager); } @@ -1537,32 +1577,36 @@ bool Runtime::Init(RuntimeArgumentMap&& runtime_options_in) { } 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"); + CreatePreAllocatedException(self, + this, + &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"); + CreatePreAllocatedException(self, + this, + &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"); + CreatePreAllocatedException(self, + this, + &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"); + CreatePreAllocatedException(self, + this, + &pre_allocated_NoClassDefFoundError_, + "Ljava/lang/NoClassDefFoundError;", + "Class not found using the boot class loader; " + "no stack trace available"); } // Runtime initialization is largely done now. @@ -2045,6 +2089,7 @@ void Runtime::VisitNonThreadRoots(RootVisitor* visitor) { pre_allocated_OutOfMemoryError_when_handling_stack_overflow_ .VisitRootIfNonNull(visitor, RootInfo(kRootVMInternal)); pre_allocated_NoClassDefFoundError_.VisitRootIfNonNull(visitor, RootInfo(kRootVMInternal)); + VisitImageRoots(visitor); verifier::MethodVerifier::VisitStaticRoots(visitor); VisitTransactionRoots(visitor); } |