summaryrefslogtreecommitdiffstats
path: root/runtime/gc/space
diff options
context:
space:
mode:
authorHiroshi Yamauchi <yamauchi@google.com>2014-03-28 15:26:48 -0700
committerHiroshi Yamauchi <yamauchi@google.com>2014-03-28 15:26:48 -0700
commit1cd53dbb2163f18b689d2a65cf9c6bdcdb01b407 (patch)
treeb6a214bcc7bd33cfa60e0e7ee51329b3327a537a /runtime/gc/space
parent0fd52d5d0cf01e5a109851098a43a79f5615dc0f (diff)
downloadart-1cd53dbb2163f18b689d2a65cf9c6bdcdb01b407.zip
art-1cd53dbb2163f18b689d2a65cf9c6bdcdb01b407.tar.gz
art-1cd53dbb2163f18b689d2a65cf9c6bdcdb01b407.tar.bz2
Fix a DCHECK failure when causing GC from DDMS.
Bug: 13647069 Change-Id: Iae2746b2b7b4493fcf5f0d40d2bf36a9b2d2efc8
Diffstat (limited to 'runtime/gc/space')
-rw-r--r--runtime/gc/space/rosalloc_space.cc52
-rw-r--r--runtime/gc/space/rosalloc_space.h6
2 files changed, 41 insertions, 17 deletions
diff --git a/runtime/gc/space/rosalloc_space.cc b/runtime/gc/space/rosalloc_space.cc
index 3c65205..012267b 100644
--- a/runtime/gc/space/rosalloc_space.cc
+++ b/runtime/gc/space/rosalloc_space.cc
@@ -231,7 +231,7 @@ size_t RosAllocSpace::Trim() {
if (!rosalloc_->DoesReleaseAllPages()) {
VLOG(heap) << "RosAllocSpace::Trim() ";
size_t reclaimed = 0;
- InspectAllRosAlloc(DlmallocMadviseCallback, &reclaimed);
+ InspectAllRosAlloc(DlmallocMadviseCallback, &reclaimed, false);
return reclaimed;
}
return 0;
@@ -239,8 +239,7 @@ size_t RosAllocSpace::Trim() {
void RosAllocSpace::Walk(void(*callback)(void *start, void *end, size_t num_bytes, void* callback_arg),
void* arg) {
- InspectAllRosAlloc(callback, arg);
- callback(NULL, NULL, 0, arg); // Indicate end of a space.
+ InspectAllRosAlloc(callback, arg, true);
}
size_t RosAllocSpace::GetFootprint() {
@@ -268,35 +267,56 @@ void RosAllocSpace::SetFootprintLimit(size_t new_size) {
uint64_t RosAllocSpace::GetBytesAllocated() {
size_t bytes_allocated = 0;
- InspectAllRosAlloc(art::gc::allocator::RosAlloc::BytesAllocatedCallback, &bytes_allocated);
+ InspectAllRosAlloc(art::gc::allocator::RosAlloc::BytesAllocatedCallback, &bytes_allocated, false);
return bytes_allocated;
}
uint64_t RosAllocSpace::GetObjectsAllocated() {
size_t objects_allocated = 0;
- InspectAllRosAlloc(art::gc::allocator::RosAlloc::ObjectsAllocatedCallback, &objects_allocated);
+ InspectAllRosAlloc(art::gc::allocator::RosAlloc::ObjectsAllocatedCallback, &objects_allocated, false);
return objects_allocated;
}
+void RosAllocSpace::InspectAllRosAllocWithSuspendAll(
+ void (*callback)(void *start, void *end, size_t num_bytes, void* callback_arg),
+ void* arg, bool do_null_callback_at_end) NO_THREAD_SAFETY_ANALYSIS {
+ // TODO: NO_THREAD_SAFETY_ANALYSIS.
+ Thread* self = Thread::Current();
+ ThreadList* tl = Runtime::Current()->GetThreadList();
+ tl->SuspendAll();
+ {
+ MutexLock mu(self, *Locks::runtime_shutdown_lock_);
+ MutexLock mu2(self, *Locks::thread_list_lock_);
+ rosalloc_->InspectAll(callback, arg);
+ if (do_null_callback_at_end) {
+ callback(NULL, NULL, 0, arg); // Indicate end of a space.
+ }
+ }
+ tl->ResumeAll();
+}
+
void RosAllocSpace::InspectAllRosAlloc(void (*callback)(void *start, void *end, size_t num_bytes, void* callback_arg),
- void* arg) NO_THREAD_SAFETY_ANALYSIS {
+ void* arg, bool do_null_callback_at_end) NO_THREAD_SAFETY_ANALYSIS {
// TODO: NO_THREAD_SAFETY_ANALYSIS.
Thread* self = Thread::Current();
if (Locks::mutator_lock_->IsExclusiveHeld(self)) {
// The mutators are already suspended. For example, a call path
// from SignalCatcher::HandleSigQuit().
rosalloc_->InspectAll(callback, arg);
- } else {
- // The mutators are not suspended yet.
- DCHECK(!Locks::mutator_lock_->IsSharedHeld(self));
- ThreadList* tl = Runtime::Current()->GetThreadList();
- tl->SuspendAll();
- {
- MutexLock mu(self, *Locks::runtime_shutdown_lock_);
- MutexLock mu2(self, *Locks::thread_list_lock_);
- rosalloc_->InspectAll(callback, arg);
+ if (do_null_callback_at_end) {
+ callback(NULL, NULL, 0, arg); // Indicate end of a space.
}
- tl->ResumeAll();
+ } else if (Locks::mutator_lock_->IsSharedHeld(self)) {
+ // The mutators are not suspended yet and we have a shared access
+ // to the mutator lock. Temporarily release the shared access by
+ // transitioning to the suspend state, and suspend the mutators.
+ self->TransitionFromRunnableToSuspended(kSuspended);
+ InspectAllRosAllocWithSuspendAll(callback, arg, do_null_callback_at_end);
+ self->TransitionFromSuspendedToRunnable();
+ Locks::mutator_lock_->AssertSharedHeld(self);
+ } else {
+ // The mutators are not suspended yet. Suspend the mutators.
+ InspectAllRosAllocWithSuspendAll(callback, arg, do_null_callback_at_end);
}
}
diff --git a/runtime/gc/space/rosalloc_space.h b/runtime/gc/space/rosalloc_space.h
index 949ec08..900e7a9 100644
--- a/runtime/gc/space/rosalloc_space.h
+++ b/runtime/gc/space/rosalloc_space.h
@@ -124,7 +124,11 @@ class RosAllocSpace : public MallocSpace {
size_t maximum_size, bool low_memory_mode);
void InspectAllRosAlloc(void (*callback)(void *start, void *end, size_t num_bytes, void* callback_arg),
- void* arg)
+ void* arg, bool do_null_callback_at_end)
+ LOCKS_EXCLUDED(Locks::runtime_shutdown_lock_, Locks::thread_list_lock_);
+ void InspectAllRosAllocWithSuspendAll(
+ void (*callback)(void *start, void *end, size_t num_bytes, void* callback_arg),
+ void* arg, bool do_null_callback_at_end)
LOCKS_EXCLUDED(Locks::runtime_shutdown_lock_, Locks::thread_list_lock_);
// Underlying rosalloc.