diff options
author | Vladimir Marko <vmarko@google.com> | 2015-05-08 15:17:32 +0100 |
---|---|---|
committer | Vladimir Marko <vmarko@google.com> | 2015-05-08 22:38:48 +0100 |
commit | dd5a4d0a9cdf75e8fffc3cc3a08c808bbd997b22 (patch) | |
tree | 014ba0947dc04c2c09a52605139933d243a5e3b8 | |
parent | 8ee43e3ce18e90bfbf8cbeb05ff78ad281015d1a (diff) | |
download | art-dd5a4d0a9cdf75e8fffc3cc3a08c808bbd997b22.zip art-dd5a4d0a9cdf75e8fffc3cc3a08c808bbd997b22.tar.gz art-dd5a4d0a9cdf75e8fffc3cc3a08c808bbd997b22.tar.bz2 |
ART: Merge entries with same name and protect in MemMap dump.
This should make the MemMap dump less chatty and allow the
logger to keep more relevant output.
Bug: 20873174
(cherry picked from commit 17a924abde2b0f1f37f6008b451a0a75190c71ff)
Change-Id: I1748f57a1f149a5498b42ee246f13d2bf1e8c2f7
-rw-r--r-- | runtime/gc/collector/mark_sweep.cc | 2 | ||||
-rw-r--r-- | runtime/gc/heap.cc | 2 | ||||
-rw-r--r-- | runtime/mem_map.cc | 63 | ||||
-rw-r--r-- | runtime/mem_map.h | 4 |
4 files changed, 63 insertions, 8 deletions
diff --git a/runtime/gc/collector/mark_sweep.cc b/runtime/gc/collector/mark_sweep.cc index 1068e90..55a8411 100644 --- a/runtime/gc/collector/mark_sweep.cc +++ b/runtime/gc/collector/mark_sweep.cc @@ -385,7 +385,7 @@ class MarkSweepMarkObjectSlowPath { LOG(INTERNAL_FATAL) << "Attempting see if it's a bad root"; mark_sweep_->VerifyRoots(); PrintFileToLog("/proc/self/maps", LogSeverity::INTERNAL_FATAL); - MemMap::DumpMaps(LOG(INTERNAL_FATAL)); + MemMap::DumpMaps(LOG(INTERNAL_FATAL), true); LOG(FATAL) << "Can't mark invalid object"; } } diff --git a/runtime/gc/heap.cc b/runtime/gc/heap.cc index cbbc76c..4129d75 100644 --- a/runtime/gc/heap.cc +++ b/runtime/gc/heap.cc @@ -491,7 +491,7 @@ Heap::Heap(size_t initial_size, size_t growth_limit, size_t min_free, size_t max bool no_gap = MemMap::CheckNoGaps(GetImageSpace()->GetMemMap(), non_moving_space_->GetMemMap()); if (!no_gap) { - MemMap::DumpMaps(LOG(ERROR)); + MemMap::DumpMaps(LOG(ERROR), true); LOG(FATAL) << "There's a gap between the image space and the non-moving space"; } } diff --git a/runtime/mem_map.cc b/runtime/mem_map.cc index a5f7341..cf4233c 100644 --- a/runtime/mem_map.cc +++ b/runtime/mem_map.cc @@ -617,13 +617,68 @@ bool MemMap::CheckNoGaps(MemMap* begin_map, MemMap* end_map) { return true; } -void MemMap::DumpMaps(std::ostream& os) { +void MemMap::DumpMaps(std::ostream& os, bool terse) { MutexLock mu(Thread::Current(), *Locks::mem_maps_lock_); - DumpMapsLocked(os); + DumpMapsLocked(os, terse); } -void MemMap::DumpMapsLocked(std::ostream& os) { - os << *maps_; +void MemMap::DumpMapsLocked(std::ostream& os, bool terse) { + const auto& mem_maps = *maps_; + if (!terse) { + os << mem_maps; + return; + } + + // Terse output example: + // [MemMap: 0x409be000+0x20P~0x11dP+0x20P~0x61cP+0x20P prot=0x3 LinearAlloc] + // [MemMap: 0x451d6000+0x6bP(3) prot=0x3 large object space allocation] + // The details: + // "+0x20P" means 0x20 pages taken by a single mapping, + // "~0x11dP" means a gap of 0x11d pages, + // "+0x6bP(3)" means 3 mappings one after another, together taking 0x6b pages. + os << "MemMap:" << std::endl; + for (auto it = mem_maps.begin(), maps_end = mem_maps.end(); it != maps_end;) { + MemMap* map = it->second; + void* base = it->first; + CHECK_EQ(base, map->BaseBegin()); + os << "[MemMap: " << base; + ++it; + // Merge consecutive maps with the same protect flags and name. + constexpr size_t kMaxGaps = 9; + size_t num_gaps = 0; + size_t num = 1u; + size_t size = map->BaseSize(); + CHECK(IsAligned<kPageSize>(size)); + void* end = map->BaseEnd(); + while (it != maps_end && + it->second->GetProtect() == map->GetProtect() && + it->second->GetName() == map->GetName() && + (it->second->BaseBegin() == end || num_gaps < kMaxGaps)) { + if (it->second->BaseBegin() != end) { + ++num_gaps; + os << "+0x" << std::hex << (size / kPageSize) << "P"; + if (num != 1u) { + os << "(" << std::dec << num << ")"; + } + size_t gap = + reinterpret_cast<uintptr_t>(it->second->BaseBegin()) - reinterpret_cast<uintptr_t>(end); + CHECK(IsAligned<kPageSize>(gap)); + os << "~0x" << std::hex << (gap / kPageSize) << "P"; + num = 0u; + size = 0u; + } + CHECK(IsAligned<kPageSize>(it->second->BaseSize())); + ++num; + size += it->second->BaseSize(); + end = it->second->BaseEnd(); + ++it; + } + os << "+0x" << std::hex << (size / kPageSize) << "P"; + if (num != 1u) { + os << "(" << std::dec << num << ")"; + } + os << " prot=0x" << std::hex << map->GetProtect() << " " << map->GetName() << "]" << std::endl; + } } bool MemMap::HasMemMap(MemMap* map) { diff --git a/runtime/mem_map.h b/runtime/mem_map.h index dc6d935..6023a70 100644 --- a/runtime/mem_map.h +++ b/runtime/mem_map.h @@ -137,7 +137,7 @@ class MemMap { static bool CheckNoGaps(MemMap* begin_map, MemMap* end_map) LOCKS_EXCLUDED(Locks::mem_maps_lock_); - static void DumpMaps(std::ostream& os) + static void DumpMaps(std::ostream& os, bool terse = false) LOCKS_EXCLUDED(Locks::mem_maps_lock_); typedef AllocationTrackingMultiMap<void*, MemMap*, kAllocatorTagMaps> Maps; @@ -149,7 +149,7 @@ class MemMap { MemMap(const std::string& name, uint8_t* begin, size_t size, void* base_begin, size_t base_size, int prot, bool reuse) LOCKS_EXCLUDED(Locks::mem_maps_lock_); - static void DumpMapsLocked(std::ostream& os) + static void DumpMapsLocked(std::ostream& os, bool terse) EXCLUSIVE_LOCKS_REQUIRED(Locks::mem_maps_lock_); static bool HasMemMap(MemMap* map) EXCLUSIVE_LOCKS_REQUIRED(Locks::mem_maps_lock_); |