Commit 990084ba authored by Pierre Langlois's avatar Pierre Langlois Committed by Commit Bot

[tracing] Emit heap statistics at every GC.

When the 'disabled-by-default-v8.gc' category is enabled, emit an instant event
with heap statistics after every GC. The data that's emitted is the same as what
the V8 API gives you with `GetHeapStatistics()` and `GetHeapSpaceStatistics()`.

We generate JSON with the following format:

```
{
 "isolate": "0x55dd5cf03b50",
 "id": 1,
 "time_ms": 42.619,

 "total_heap_size": 3981312,
 "total_heap_size_executable": 573440,
 "total_physical_size": 2820440,
 "total_available_size": 2195254440,

 "used_heap_size": 1799616,
 "heap_size_limit": 2197815296,
 "malloced_memory": 251024,
 "external_memory": 2981,
 "peak_malloced_memory": 589280,

 "spaces": [
   {
     "name": "read_only_space",
     "size": 262144,
     "used_size": 32568,
     "available_size": 229256,
     "physical_size": 32888
   },
   {
     "name": "new_space",
     "size": 2097152,
     "used_size": 903392,
     "available_size": 143904,
     "physical_size": 1856136
   },
   ...
 ]
}
```

Bug: v8:9186
Change-Id: I0d07aa37b65d45778d6b47dbe6e07a9dd25d1097
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1619763Reviewed-by: 's avatarUlan Degenbaev <ulan@chromium.org>
Commit-Queue: Pierre Langlois <pierre.langlois@arm.com>
Cr-Commit-Position: refs/heads/master@{#61667}
parent 5504068f
......@@ -363,6 +363,16 @@ void GCTracer::Stop(GarbageCollector collector) {
if (FLAG_trace_gc) {
heap_->PrintShortHeapStatistics();
}
if (V8_UNLIKELY(TracingFlags::gc.load(std::memory_order_relaxed) &
v8::tracing::TracingCategoryObserver::ENABLED_BY_TRACING)) {
std::stringstream heap_stats;
heap_->DumpJSONHeapStatistics(heap_stats);
TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("v8.gc"), "V8.GC_Heap_Stats",
TRACE_EVENT_SCOPE_THREAD, "stats",
TRACE_STR_COPY(heap_stats.str().c_str()));
}
}
......
......@@ -442,6 +442,63 @@ void Heap::PrintShortHeapStatistics() {
total_gc_time_ms_);
}
void Heap::DumpJSONHeapStatistics(std::stringstream& stream) {
HeapStatistics stats;
reinterpret_cast<v8::Isolate*>(isolate())->GetHeapStatistics(&stats);
// clang-format off
#define DICT(s) "{" << s << "}"
#define LIST(s) "[" << s << "]"
#define ESCAPE(s) "\"" << s << "\""
#define MEMBER(s) ESCAPE(s) << ":"
auto SpaceStatistics = [this](int space_index) {
HeapSpaceStatistics space_stats;
reinterpret_cast<v8::Isolate*>(isolate())->GetHeapSpaceStatistics(
&space_stats, space_index);
std::stringstream stream;
stream << DICT(
MEMBER("name")
<< ESCAPE(GetSpaceName(static_cast<AllocationSpace>(space_index)))
<< ","
MEMBER("size") << space_stats.space_size() << ","
MEMBER("used_size") << space_stats.space_used_size() << ","
MEMBER("available_size") << space_stats.space_available_size() << ","
MEMBER("physical_size") << space_stats.physical_space_size());
return stream.str();
};
stream << DICT(
MEMBER("isolate") << ESCAPE(reinterpret_cast<void*>(isolate())) << ","
MEMBER("id") << gc_count() << ","
MEMBER("time_ms") << isolate()->time_millis_since_init() << ","
MEMBER("total_heap_size") << stats.total_heap_size() << ","
MEMBER("total_heap_size_executable")
<< stats.total_heap_size_executable() << ","
MEMBER("total_physical_size") << stats.total_physical_size() << ","
MEMBER("total_available_size") << stats.total_available_size() << ","
MEMBER("used_heap_size") << stats.used_heap_size() << ","
MEMBER("heap_size_limit") << stats.heap_size_limit() << ","
MEMBER("malloced_memory") << stats.malloced_memory() << ","
MEMBER("external_memory") << stats.external_memory() << ","
MEMBER("peak_malloced_memory") << stats.peak_malloced_memory() << ","
MEMBER("pages") << LIST(
SpaceStatistics(RO_SPACE) << "," <<
SpaceStatistics(NEW_SPACE) << "," <<
SpaceStatistics(OLD_SPACE) << "," <<
SpaceStatistics(CODE_SPACE) << "," <<
SpaceStatistics(MAP_SPACE) << "," <<
SpaceStatistics(LO_SPACE) << "," <<
SpaceStatistics(CODE_LO_SPACE) << "," <<
SpaceStatistics(NEW_LO_SPACE)));
#undef DICT
#undef LIST
#undef ESCAPE
#undef MEMBER
// clang-format on
}
void Heap::ReportStatisticsAfterGC() {
for (int i = 0; i < static_cast<int>(v8::Isolate::kUseCounterFeatureCount);
++i) {
......
......@@ -474,6 +474,9 @@ class Heap {
// Print short heap statistics.
void PrintShortHeapStatistics();
// Dump heap statistics in JSON format.
void DumpJSONHeapStatistics(std::stringstream& stream);
bool write_protect_code_memory() const { return write_protect_code_memory_; }
uintptr_t code_space_memory_modification_scope_depth() {
......
......@@ -18,6 +18,7 @@ namespace v8 {
namespace internal {
std::atomic_uint TracingFlags::runtime_stats{0};
std::atomic_uint TracingFlags::gc{0};
std::atomic_uint TracingFlags::gc_stats{0};
std::atomic_uint TracingFlags::ic_stats{0};
......
......@@ -30,6 +30,7 @@ namespace internal {
struct TracingFlags {
static V8_EXPORT_PRIVATE std::atomic_uint runtime_stats;
static V8_EXPORT_PRIVATE std::atomic_uint gc;
static V8_EXPORT_PRIVATE std::atomic_uint gc_stats;
static V8_EXPORT_PRIVATE std::atomic_uint ic_stats;
......@@ -37,6 +38,10 @@ struct TracingFlags {
return runtime_stats.load(std::memory_order_relaxed) != 0;
}
static bool is_gc_enabled() {
return gc.load(std::memory_order_relaxed) != 0;
}
static bool is_gc_stats_enabled() {
return gc_stats.load(std::memory_order_relaxed) != 0;
}
......
......@@ -40,6 +40,11 @@ void TracingCategoryObserver::OnTraceEnabled() {
i::TracingFlags::runtime_stats.fetch_or(ENABLED_BY_SAMPLING,
std::memory_order_relaxed);
}
TRACE_EVENT_CATEGORY_GROUP_ENABLED(TRACE_DISABLED_BY_DEFAULT("v8.gc"),
&enabled);
if (enabled) {
i::TracingFlags::gc.fetch_or(ENABLED_BY_TRACING, std::memory_order_relaxed);
}
TRACE_EVENT_CATEGORY_GROUP_ENABLED(TRACE_DISABLED_BY_DEFAULT("v8.gc_stats"),
&enabled);
if (enabled) {
......@@ -58,6 +63,8 @@ void TracingCategoryObserver::OnTraceDisabled() {
i::TracingFlags::runtime_stats.fetch_and(
~(ENABLED_BY_TRACING | ENABLED_BY_SAMPLING), std::memory_order_relaxed);
i::TracingFlags::gc.fetch_and(~ENABLED_BY_TRACING, std::memory_order_relaxed);
i::TracingFlags::gc_stats.fetch_and(~ENABLED_BY_TRACING,
std::memory_order_relaxed);
......
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