diff options
Diffstat (limited to 'runtime/gc/space/dlmalloc_space.cc')
| -rw-r--r-- | runtime/gc/space/dlmalloc_space.cc | 24 |
1 files changed, 24 insertions, 0 deletions
diff --git a/runtime/gc/space/dlmalloc_space.cc b/runtime/gc/space/dlmalloc_space.cc index 5123e4787d..456d1b31e2 100644 --- a/runtime/gc/space/dlmalloc_space.cc +++ b/runtime/gc/space/dlmalloc_space.cc @@ -304,6 +304,30 @@ void DlMallocSpace::CheckMoreCoreForPrecondition() { } #endif +static void MSpaceChunkCallback(void* start, void* end, size_t used_bytes, void* arg) { + size_t chunk_size = reinterpret_cast<uint8_t*>(end) - reinterpret_cast<uint8_t*>(start); + if (used_bytes < chunk_size) { + size_t chunk_free_bytes = chunk_size - used_bytes; + size_t& max_contiguous_allocation = *reinterpret_cast<size_t*>(arg); + max_contiguous_allocation = std::max(max_contiguous_allocation, chunk_free_bytes); + } +} + +void DlMallocSpace::LogFragmentationAllocFailure(std::ostream& os, size_t failed_alloc_bytes) { + Thread* self = Thread::Current(); + size_t max_contiguous_allocation = 0; + // To allow the Walk/InspectAll() to exclusively-lock the mutator + // lock, temporarily release the shared access to the mutator + // lock here by transitioning to the suspended state. + Locks::mutator_lock_->AssertSharedHeld(self); + self->TransitionFromRunnableToSuspended(kSuspended); + Walk(MSpaceChunkCallback, &max_contiguous_allocation); + self->TransitionFromSuspendedToRunnable(); + Locks::mutator_lock_->AssertSharedHeld(self); + os << "; failed due to fragmentation (largest possible contiguous allocation " + << max_contiguous_allocation << " bytes)"; +} + } // namespace space } // namespace gc } // namespace art |