Commit a5a9198a authored by lpy's avatar lpy Committed by Commit bot

[Tracing] Integrate GC object statistics with tracing.

Memory infra in tracing currently uses Isolate::GetHeapStatistics to fetch
object statistics from V8 at certain frequency, which is not accurate and will
have redundant result. This path adds a trace event as well as a trace category
at where we collect object statistics after marking before sweeping, and dumps
all information to the trace event.

In order to use this functionality, we need to enable two flags:
--track-gc-object-stats and --noincremental-marking.

BUG=v8:5453

Review-Url: https://codereview.chromium.org/2379823004
Cr-Commit-Position: refs/heads/master@{#39966}
parent fa5b221e
......@@ -2246,6 +2246,13 @@ void MarkCompactCollector::RecordObjectStats() {
ObjectStatsVisitor visitor(heap(), heap()->live_object_stats_,
heap()->dead_object_stats_);
VisitAllObjects(&visitor);
std::stringstream live, dead;
heap()->live_object_stats_->Dump(live);
heap()->dead_object_stats_->Dump(dead);
TRACE_EVENT_INSTANT2(TRACE_DISABLED_BY_DEFAULT("v8.gc_stats"),
"V8.GC_Objects_Stats", TRACE_EVENT_SCOPE_THREAD,
"live", TRACE_STR_COPY(live.str().c_str()), "dead",
TRACE_STR_COPY(dead.str().c_str()));
if (FLAG_trace_gc_object_stats) {
heap()->live_object_stats_->PrintJSON("live");
heap()->dead_object_stats_->PrintJSON("dead");
......
......@@ -42,6 +42,16 @@ V8_NOINLINE static void PrintJSONArray(size_t* array, const int len) {
PrintF(" ]");
}
V8_NOINLINE static void DumpJSONArray(std::stringstream& stream, size_t* array,
const int len) {
stream << "[";
for (int i = 0; i < len; i++) {
stream << array[i];
if (i != (len - 1)) stream << ",";
}
stream << "]";
}
void ObjectStats::PrintJSON(const char* key) {
double time = isolate()->time_millis_since_init();
int gc_count = heap()->gc_count();
......@@ -97,6 +107,60 @@ void ObjectStats::PrintJSON(const char* key) {
FIXED_ARRAY_SUB_INSTANCE_TYPE_LIST(FIXED_ARRAY_SUB_INSTANCE_TYPE_WRAPPER)
CODE_AGE_LIST_COMPLETE(CODE_AGE_WRAPPER)
#undef INSTANCE_TYPE_WRAPPER
#undef CODE_KIND_WRAPPER
#undef FIXED_ARRAY_SUB_INSTANCE_TYPE_WRAPPER
#undef CODE_AGE_WRAPPER
#undef PRINT_INSTANCE_TYPE_DATA
#undef PRINT_KEY_AND_ID
}
void ObjectStats::Dump(std::stringstream& stream) {
double time = isolate()->time_millis_since_init();
int gc_count = heap()->gc_count();
stream << "{";
stream << "\"isolate\":\"" << reinterpret_cast<void*>(isolate()) << "\",";
stream << "\"id\":" << gc_count << ",";
stream << "\"time\":" << time << ",";
stream << "\"bucket_sizes\":[";
for (int i = 0; i < kNumberOfBuckets; i++) {
stream << (1 << (kFirstBucketShift + i));
if (i != (kNumberOfBuckets - 1)) stream << ",";
}
stream << "],";
stream << "\"type_data\":{";
#define PRINT_INSTANCE_TYPE_DATA(name, index) \
stream << "\"" << name << "\":{"; \
stream << "\"type\":" << static_cast<int>(index) << ","; \
stream << "\"overall\":" << object_sizes_[index] << ","; \
stream << "\"count\":" << object_counts_[index] << ","; \
stream << "\"over_allocated\":" << over_allocated_[index] << ","; \
stream << "\"histogram\":"; \
DumpJSONArray(stream, size_histogram_[index], kNumberOfBuckets); \
stream << ",\"over_allocated_histogram\":"; \
DumpJSONArray(stream, over_allocated_histogram_[index], kNumberOfBuckets); \
stream << "},";
#define INSTANCE_TYPE_WRAPPER(name) PRINT_INSTANCE_TYPE_DATA(#name, name)
#define CODE_KIND_WRAPPER(name) \
PRINT_INSTANCE_TYPE_DATA("*CODE_" #name, \
FIRST_CODE_KIND_SUB_TYPE + Code::name)
#define FIXED_ARRAY_SUB_INSTANCE_TYPE_WRAPPER(name) \
PRINT_INSTANCE_TYPE_DATA("*FIXED_ARRAY_" #name, \
FIRST_FIXED_ARRAY_SUB_TYPE + name)
#define CODE_AGE_WRAPPER(name) \
PRINT_INSTANCE_TYPE_DATA( \
"*CODE_AGE_" #name, \
FIRST_CODE_AGE_SUB_TYPE + Code::k##name##CodeAge - Code::kFirstCodeAge)
INSTANCE_TYPE_LIST(INSTANCE_TYPE_WRAPPER);
CODE_KIND_LIST(CODE_KIND_WRAPPER);
FIXED_ARRAY_SUB_INSTANCE_TYPE_LIST(FIXED_ARRAY_SUB_INSTANCE_TYPE_WRAPPER);
CODE_AGE_LIST_COMPLETE(CODE_AGE_WRAPPER);
stream << "\"END\":{}}}";
#undef INSTANCE_TYPE_WRAPPER
#undef CODE_KIND_WRAPPER
#undef FIXED_ARRAY_SUB_INSTANCE_TYPE_WRAPPER
......
......@@ -35,6 +35,7 @@ class ObjectStats {
void CheckpointObjectStats();
void PrintJSON(const char* key);
void Dump(std::stringstream& stream);
void RecordObjectStats(InstanceType type, size_t size) {
DCHECK(type <= LAST_TYPE);
......
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