summaryrefslogtreecommitdiffstats
path: root/runtime/runtime.cc
diff options
context:
space:
mode:
authorIan Rogers <irogers@google.com>2013-08-27 23:34:06 -0700
committerIan Rogers <irogers@google.com>2013-08-27 23:37:33 -0700
commita436fde2762664a3ecdda5eefcadd20b2e104f59 (patch)
tree22431bc387483220728a3bc99ec7314abce3ad60 /runtime/runtime.cc
parent10cc81056261625902a8a073bafb9f499eec4ff7 (diff)
downloadart-a436fde2762664a3ecdda5eefcadd20b2e104f59.zip
art-a436fde2762664a3ecdda5eefcadd20b2e104f59.tar.gz
art-a436fde2762664a3ecdda5eefcadd20b2e104f59.tar.bz2
Handle OOMEs in class linker with grace.
Check for OOMEs and then fail due to them in class loading. Make the compiler driver spot OOMEs during resolution and abort compilation to avoid needless GC thrash then eventual death. Allocate the pre-allocated OOME during Runtime::Init as Runtime::Start isn't called in the context of the compiler/tools. Change-Id: Id72199d0fe82001b5bf22758b3cdc9cc4b8efbb9
Diffstat (limited to 'runtime/runtime.cc')
-rw-r--r--runtime/runtime.cc23
1 files changed, 15 insertions, 8 deletions
diff --git a/runtime/runtime.cc b/runtime/runtime.cc
index 5679d4e..09cbd0b 100644
--- a/runtime/runtime.cc
+++ b/runtime/runtime.cc
@@ -704,14 +704,8 @@ bool Runtime::Start() {
CHECK(host_prefix_.empty()) << host_prefix_;
- // Pre-allocate an OutOfMemoryError for the double-OOME case.
- Thread* self = Thread::Current();
- self->ThrowNewException(ThrowLocation(), "Ljava/lang/OutOfMemoryError;",
- "OutOfMemoryError thrown while trying to throw OutOfMemoryError; no stack available");
- pre_allocated_OutOfMemoryError_ = self->GetException(NULL);
- self->ClearException();
-
// Restore main thread state to kNative as expected by native code.
+ Thread* self = Thread::Current();
self->TransitionFromRunnableToSuspended(kNative);
started_ = true;
@@ -906,7 +900,7 @@ bool Runtime::Init(const Options& raw_options, bool ignore_unrecognized) {
// Set us to runnable so tools using a runtime can allocate and GC by default
self->TransitionFromSuspendedToRunnable();
- // Now we're attached, we can take the heap lock and validate the heap.
+ // Now we're attached, we can take the heap locks and validate the heap.
GetHeap()->EnableObjectValidation();
CHECK_GE(GetHeap()->GetContinuousSpaces().size(), 1U);
@@ -929,6 +923,12 @@ bool Runtime::Init(const Options& raw_options, bool ignore_unrecognized) {
false, false, 0);
}
+ // Pre-allocate an OutOfMemoryError for the double-OOME case.
+ self->ThrowNewException(ThrowLocation(), "Ljava/lang/OutOfMemoryError;",
+ "OutOfMemoryError thrown while trying to throw OutOfMemoryError; no stack available");
+ pre_allocated_OutOfMemoryError_ = self->GetException(NULL);
+ self->ClearException();
+
VLOG(startup) << "Runtime::Init exiting";
return true;
}
@@ -1123,6 +1123,13 @@ void Runtime::DetachCurrentThread() {
thread_list_->Unregister(self);
}
+ mirror::Throwable* Runtime::GetPreAllocatedOutOfMemoryError() const {
+ if (pre_allocated_OutOfMemoryError_ == NULL) {
+ LOG(ERROR) << "Failed to return pre-allocated OOME";
+ }
+ return pre_allocated_OutOfMemoryError_;
+}
+
void Runtime::VisitConcurrentRoots(RootVisitor* visitor, void* arg, bool only_dirty,
bool clean_dirty) {
if (!only_dirty || intern_table_->IsDirty()) {