1 // Copyright 2021 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "src/heap/heap-layout-tracer.h"
6
7 #include <iostream>
8
9 #include "src/heap/new-spaces.h"
10 #include "src/heap/paged-spaces.h"
11 #include "src/heap/read-only-spaces.h"
12 #include "src/heap/spaces-inl.h"
13
14 namespace v8 {
15 namespace internal {
16
17 // static
GCProloguePrintHeapLayout(v8::Isolate * isolate,v8::GCType gc_type,v8::GCCallbackFlags flags,void * data)18 void HeapLayoutTracer::GCProloguePrintHeapLayout(v8::Isolate* isolate,
19 v8::GCType gc_type,
20 v8::GCCallbackFlags flags,
21 void* data) {
22 Heap* heap = reinterpret_cast<i::Isolate*>(isolate)->heap();
23 // gc_count_ will increase after this callback, manually add 1.
24 PrintF("Before GC:%d,", heap->gc_count() + 1);
25 PrintF("collector_name:%s\n", Heap::CollectorName(gc_type));
26 PrintHeapLayout(std::cout, heap);
27 }
28
29 // static
GCEpiloguePrintHeapLayout(v8::Isolate * isolate,v8::GCType gc_type,v8::GCCallbackFlags flags,void * data)30 void HeapLayoutTracer::GCEpiloguePrintHeapLayout(v8::Isolate* isolate,
31 v8::GCType gc_type,
32 v8::GCCallbackFlags flags,
33 void* data) {
34 Heap* heap = reinterpret_cast<i::Isolate*>(isolate)->heap();
35 PrintF("After GC:%d,", heap->gc_count());
36 PrintF("collector_name:%s\n", Heap::CollectorName(gc_type));
37 PrintHeapLayout(std::cout, heap);
38 }
39
40 // static
PrintBasicMemoryChunk(std::ostream & os,BasicMemoryChunk * chunk,const char * owner_name)41 void HeapLayoutTracer::PrintBasicMemoryChunk(std::ostream& os,
42 BasicMemoryChunk* chunk,
43 const char* owner_name) {
44 os << "{owner:" << owner_name << ","
45 << "address:" << chunk << ","
46 << "size:" << chunk->size() << ","
47 << "allocated_bytes:" << chunk->allocated_bytes() << ","
48 << "wasted_memory:" << chunk->wasted_memory() << "}" << std::endl;
49 }
50
51 // static
PrintHeapLayout(std::ostream & os,Heap * heap)52 void HeapLayoutTracer::PrintHeapLayout(std::ostream& os, Heap* heap) {
53 for (PageIterator it = heap->new_space()->to_space().begin();
54 it != heap->new_space()->to_space().end(); ++it) {
55 PrintBasicMemoryChunk(os, *it, "to_space");
56 }
57
58 for (PageIterator it = heap->new_space()->from_space().begin();
59 it != heap->new_space()->from_space().end(); ++it) {
60 PrintBasicMemoryChunk(os, *it, "from_space");
61 }
62
63 OldGenerationMemoryChunkIterator it(heap);
64 MemoryChunk* chunk;
65 while ((chunk = it.next()) != nullptr) {
66 PrintBasicMemoryChunk(os, chunk, chunk->owner()->name());
67 }
68
69 for (ReadOnlyPage* page : heap->read_only_space()->pages()) {
70 PrintBasicMemoryChunk(os, page, "ro_space");
71 }
72 }
73 } // namespace internal
74 } // namespace v8
75