diff options
| author | 2015-05-12 10:47:11 -0700 | |
|---|---|---|
| committer | 2015-05-12 14:59:31 -0700 | |
| commit | b43390cb87eace4a017f672d66cfb20fb9e76aa1 (patch) | |
| tree | 7d4f2f0f0d0ad561f20cac4a2aa78cba9a477c78 | |
| parent | 28d332c720cb7c9c0163c4844bb0c1a2a067470e (diff) | |
Hold heap bitmap lock in Heap::GetObjectsAllocated
Fixes a race condition where add and remove space could cause a crash
when we iterated over the spaces.
TODO: Add a spaces lock or something to guard against this.
(cherry picked from commit a395c0a492079d86b312c9edc796d63001576954)
Bug: 21031927
Change-Id: I7f0d558316f8e9d9f22ffd182e8666355bf50d47
| -rw-r--r-- | runtime/debugger.cc | 1 | ||||
| -rw-r--r-- | runtime/gc/heap.cc | 13 | ||||
| -rw-r--r-- | runtime/native/java_lang_Thread.cc | 1 | ||||
| -rw-r--r-- | runtime/thread_state.h | 1 |
4 files changed, 14 insertions, 2 deletions
diff --git a/runtime/debugger.cc b/runtime/debugger.cc index 811d15ad97..4bc9f98dfe 100644 --- a/runtime/debugger.cc +++ b/runtime/debugger.cc @@ -2143,6 +2143,7 @@ JDWP::JdwpThreadStatus Dbg::ToJdwpThreadStatus(ThreadState state) { case kWaitingForDebuggerToAttach: case kWaitingForDeoptimization: case kWaitingForGcToComplete: + case kWaitingForGetObjectsAllocated: case kWaitingForJniOnLoad: case kWaitingForMethodTracingStart: case kWaitingForSignalCatcherOutput: diff --git a/runtime/gc/heap.cc b/runtime/gc/heap.cc index 4129d75520..11a0e3c3b8 100644 --- a/runtime/gc/heap.cc +++ b/runtime/gc/heap.cc @@ -1612,10 +1612,19 @@ void Heap::SetTargetHeapUtilization(float target) { } size_t Heap::GetObjectsAllocated() const { + Thread* self = Thread::Current(); + ScopedThreadStateChange tsc(self, kWaitingForGetObjectsAllocated); + auto* tl = Runtime::Current()->GetThreadList(); + // Need SuspendAll here to prevent lock violation if RosAlloc does it during InspectAll. + tl->SuspendAll(__FUNCTION__); size_t total = 0; - for (space::AllocSpace* space : alloc_spaces_) { - total += space->GetObjectsAllocated(); + { + ReaderMutexLock mu(self, *Locks::heap_bitmap_lock_); + for (space::AllocSpace* space : alloc_spaces_) { + total += space->GetObjectsAllocated(); + } } + tl->ResumeAll(); return total; } diff --git a/runtime/native/java_lang_Thread.cc b/runtime/native/java_lang_Thread.cc index be7022e281..6569d833c5 100644 --- a/runtime/native/java_lang_Thread.cc +++ b/runtime/native/java_lang_Thread.cc @@ -84,6 +84,7 @@ static jint Thread_nativeGetStatus(JNIEnv* env, jobject java_thread, jboolean ha case kWaitingInMainDebuggerLoop: return kJavaWaiting; case kWaitingForDebuggerSuspension: return kJavaWaiting; case kWaitingForDeoptimization: return kJavaWaiting; + case kWaitingForGetObjectsAllocated: return kJavaWaiting; case kWaitingForJniOnLoad: return kJavaWaiting; case kWaitingForSignalCatcherOutput: return kJavaWaiting; case kWaitingInMainSignalCatcherLoop: return kJavaWaiting; diff --git a/runtime/thread_state.h b/runtime/thread_state.h index b5479edb80..c7ea7f4381 100644 --- a/runtime/thread_state.h +++ b/runtime/thread_state.h @@ -42,6 +42,7 @@ enum ThreadState { kWaitingForDeoptimization, // WAITING TS_WAIT waiting for deoptimization suspend all kWaitingForMethodTracingStart, // WAITING TS_WAIT waiting for method tracing to start kWaitingForVisitObjects, // WAITING TS_WAIT waiting for visiting objects + kWaitingForGetObjectsAllocated, // WAITING TS_WAIT waiting for getting the number of allocated objects kStarting, // NEW TS_WAIT native thread started, not yet ready to run managed code kNative, // RUNNABLE TS_RUNNING running in a JNI native method kSuspended, // RUNNABLE TS_RUNNING suspended by GC or debugger |