Commit 272cf914 authored by JianxiaoLuIntel's avatar JianxiaoLuIntel Committed by V8 LUCI CQ

[heap] trace heap layout before and after gc

Change-Id: Ic79f5829ae47cb4217d424aa6582f4686751ff1a
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3299279
Auto-Submit: Jianxiao Lu <jianxiao.lu@intel.com>
Reviewed-by: 's avatarMichael Lippautz <mlippautz@chromium.org>
Commit-Queue: Michael Lippautz <mlippautz@chromium.org>
Cr-Commit-Position: refs/heads/main@{#78287}
parent ec84e33c
......@@ -1344,6 +1344,8 @@ filegroup(
"src/heap/heap-controller.cc",
"src/heap/heap-controller.h",
"src/heap/heap-inl.h",
"src/heap/heap-layout-tracer.cc",
"src/heap/heap-layout-tracer.h",
"src/heap/heap-write-barrier-inl.h",
"src/heap/heap-write-barrier.cc",
"src/heap/heap-write-barrier.h",
......
......@@ -2941,6 +2941,7 @@ v8_header_set("v8_internal_headers") {
"src/heap/gc-tracer.h",
"src/heap/heap-controller.h",
"src/heap/heap-inl.h",
"src/heap/heap-layout-tracer.h",
"src/heap/heap-write-barrier-inl.h",
"src/heap/heap-write-barrier.h",
"src/heap/heap.h",
......@@ -4132,6 +4133,7 @@ v8_source_set("v8_base_without_compiler") {
"src/heap/gc-idle-time-handler.cc",
"src/heap/gc-tracer.cc",
"src/heap/heap-controller.cc",
"src/heap/heap-layout-tracer.cc",
"src/heap/heap-write-barrier.cc",
"src/heap/heap.cc",
"src/heap/incremental-marking-job.cc",
......
......@@ -148,11 +148,13 @@ using JitCodeEventHandler = void (*)(const JitCodeEvent* event);
*/
enum GCType {
kGCTypeScavenge = 1 << 0,
kGCTypeMarkSweepCompact = 1 << 1,
kGCTypeIncrementalMarking = 1 << 2,
kGCTypeProcessWeakCallbacks = 1 << 3,
kGCTypeAll = kGCTypeScavenge | kGCTypeMarkSweepCompact |
kGCTypeIncrementalMarking | kGCTypeProcessWeakCallbacks
kGCTypeMinorMarkCompact = 1 << 1,
kGCTypeMarkSweepCompact = 1 << 2,
kGCTypeIncrementalMarking = 1 << 3,
kGCTypeProcessWeakCallbacks = 1 << 4,
kGCTypeAll = kGCTypeScavenge | kGCTypeMinorMarkCompact |
kGCTypeMarkSweepCompact | kGCTypeIncrementalMarking |
kGCTypeProcessWeakCallbacks
};
/**
......
......@@ -1205,6 +1205,10 @@ DEFINE_BOOL(trace_gc_freelists_verbose, false,
"prints details of freelists of each page before and after "
"each major garbage collection")
DEFINE_IMPLICATION(trace_gc_freelists_verbose, trace_gc_freelists)
DEFINE_BOOL(trace_gc_heap_layout, false,
"print layout of pages in heap before and after gc")
DEFINE_BOOL(trace_gc_heap_layout_ignore_minor_gc, true,
"do not print trace line before and after minor-gc")
DEFINE_BOOL(trace_evacuation_candidates, false,
"Show statistics about the pages evacuation by the compaction")
DEFINE_BOOL(
......
// 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();
PrintF("Before GC:%d,", heap->gc_count());
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
// 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.
#ifndef V8_HEAP_HEAP_LAYOUT_TRACER_H_
#define V8_HEAP_HEAP_LAYOUT_TRACER_H_
#include "include/v8-callbacks.h"
#include "src/common/globals.h"
namespace v8 {
namespace internal {
class Heap;
class BasicMemoryChunk;
class HeapLayoutTracer : AllStatic {
public:
static void GCProloguePrintHeapLayout(v8::Isolate* isolate,
v8::GCType gc_type,
v8::GCCallbackFlags flags, void* data);
static void GCEpiloguePrintHeapLayout(v8::Isolate* isolate,
v8::GCType gc_type,
v8::GCCallbackFlags flags, void* data);
private:
static void PrintBasicMemoryChunk(std::ostream& os, BasicMemoryChunk* chunk,
const char* owner_name);
static void PrintHeapLayout(std::ostream& os, Heap* heap);
};
} // namespace internal
} // namespace v8
#endif // V8_HEAP_HEAP_LAYOUT_TRACER_H_
......@@ -51,6 +51,7 @@
#include "src/heap/gc-idle-time-handler.h"
#include "src/heap/gc-tracer.h"
#include "src/heap/heap-controller.h"
#include "src/heap/heap-layout-tracer.h"
#include "src/heap/heap-write-barrier-inl.h"
#include "src/heap/incremental-marking-inl.h"
#include "src/heap/incremental-marking.h"
......@@ -1762,9 +1763,22 @@ bool Heap::CollectGarbage(AllocationSpace space,
PROFILE(isolate_, CodeMovingGCEvent());
}
GCType gc_type = collector == GarbageCollector::MARK_COMPACTOR
? kGCTypeMarkSweepCompact
: kGCTypeScavenge;
GCType gc_type;
switch (collector) {
case GarbageCollector::MARK_COMPACTOR:
gc_type = kGCTypeMarkSweepCompact;
break;
case GarbageCollector::SCAVENGER:
gc_type = kGCTypeScavenge;
break;
case GarbageCollector::MINOR_MARK_COMPACTOR:
gc_type = kGCTypeMinorMarkCompact;
break;
default:
UNREACHABLE();
}
{
GCCallbacksScope scope(this);
// Temporary override any embedder stack state as callbacks may create
......@@ -5653,6 +5667,19 @@ void Heap::SetUp(LocalHeap* main_thread_local_heap) {
for (int i = FIRST_SPACE; i <= LAST_SPACE; i++) {
space_[i] = nullptr;
}
// Set up layout tracing callback.
if (V8_UNLIKELY(FLAG_trace_gc_heap_layout)) {
v8::GCType gc_type = kGCTypeMarkSweepCompact;
if (V8_UNLIKELY(!FLAG_trace_gc_heap_layout_ignore_minor_gc)) {
gc_type = static_cast<v8::GCType>(gc_type | kGCTypeScavenge |
kGCTypeMinorMarkCompact);
}
AddGCPrologueCallback(HeapLayoutTracer::GCProloguePrintHeapLayout, gc_type,
nullptr);
AddGCEpilogueCallback(HeapLayoutTracer::GCEpiloguePrintHeapLayout, gc_type,
nullptr);
}
}
void Heap::SetUpFromReadOnlyHeap(ReadOnlyHeap* ro_heap) {
......
......@@ -500,6 +500,20 @@ class Heap {
return "Unknown collector";
}
static inline const char* CollectorName(v8::GCType gc_type) {
switch (gc_type) {
case kGCTypeScavenge:
return "Scavenger";
case kGCTypeMarkSweepCompact:
return "Mark-Compact";
case kGCTypeMinorMarkCompact:
return "Minor Mark-Compact";
default:
break;
}
return "Unknown collector";
}
// Copy block of memory from src to dst. Size of block should be aligned
// by pointer size.
static inline void CopyBlock(Address dst, Address src, int byte_size);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment