| // Copyright 2021 the V8 project authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "src/heap/heap-layout-tracer.h" |
| |
| #include <iostream> |
| |
| #include "src/heap/new-spaces.h" |
| #include "src/heap/paged-spaces.h" |
| #include "src/heap/read-only-spaces.h" |
| #include "src/heap/spaces-inl.h" |
| |
| namespace v8 { |
| namespace internal { |
| |
| // static |
| void HeapLayoutTracer::GCProloguePrintHeapLayout(v8::Isolate* isolate, |
| v8::GCType gc_type, |
| v8::GCCallbackFlags flags, |
| void* data) { |
| Heap* heap = reinterpret_cast<i::Isolate*>(isolate)->heap(); |
| // gc_count_ will increase after this callback, manually add 1. |
| PrintF("Before GC:%d,", heap->gc_count() + 1); |
| PrintF("collector_name:%s\n", Heap::CollectorName(gc_type)); |
| PrintHeapLayout(std::cout, heap); |
| } |
| |
| // static |
| void HeapLayoutTracer::GCEpiloguePrintHeapLayout(v8::Isolate* isolate, |
| v8::GCType gc_type, |
| v8::GCCallbackFlags flags, |
| void* data) { |
| Heap* heap = reinterpret_cast<i::Isolate*>(isolate)->heap(); |
| PrintF("After GC:%d,", heap->gc_count()); |
| PrintF("collector_name:%s\n", Heap::CollectorName(gc_type)); |
| PrintHeapLayout(std::cout, heap); |
| } |
| |
| // static |
| void HeapLayoutTracer::PrintBasicMemoryChunk(std::ostream& os, |
| BasicMemoryChunk* chunk, |
| const char* owner_name) { |
| os << "{owner:" << owner_name << "," |
| << "address:" << chunk << "," |
| << "size:" << chunk->size() << "," |
| << "allocated_bytes:" << chunk->allocated_bytes() << "," |
| << "wasted_memory:" << chunk->wasted_memory() << "}" << std::endl; |
| } |
| |
| // static |
| void HeapLayoutTracer::PrintHeapLayout(std::ostream& os, Heap* heap) { |
| for (PageIterator it = heap->new_space()->to_space().begin(); |
| it != heap->new_space()->to_space().end(); ++it) { |
| PrintBasicMemoryChunk(os, *it, "to_space"); |
| } |
| |
| for (PageIterator it = heap->new_space()->from_space().begin(); |
| it != heap->new_space()->from_space().end(); ++it) { |
| PrintBasicMemoryChunk(os, *it, "from_space"); |
| } |
| |
| OldGenerationMemoryChunkIterator it(heap); |
| MemoryChunk* chunk; |
| while ((chunk = it.next()) != nullptr) { |
| PrintBasicMemoryChunk(os, chunk, chunk->owner()->name()); |
| } |
| |
| for (ReadOnlyPage* page : heap->read_only_space()->pages()) { |
| PrintBasicMemoryChunk(os, page, "ro_space"); |
| } |
| } |
| } // namespace internal |
| } // namespace v8 |