v8/tools/zone-stats/model.js
Igor Sheludko 262a1078d5 [zone-stats] Add a UI for exploring zone memory usage stats
... collected via --trace-zone-stats flag or v8.zone_stats trace
category.

This is an initial version inspired by heap-stats UI.

Bug: v8:10572
Change-Id: Ib87cf0b4e120bc99683227eef02668a2a5c3d594
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2226855
Reviewed-by: Camillo Bruni <cbruni@chromium.org>
Commit-Queue: Igor Sheludko <ishell@chromium.org>
Cr-Commit-Position: refs/heads/master@{#68133}
2020-06-03 10:22:34 +00:00

93 lines
2.6 KiB
JavaScript

// Copyright 2020 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.
'use strict';
export class Isolate {
constructor(address) {
this.address = address;
this.start = null;
this.end = null;
this.peakUsageTime = null;
// Maps zone name to per-zone statistics.
this.zones = new Map();
// Zone names sorted by memory usage (from low to high).
this.sorted_zone_names = [];
// Maps time to total and per-zone memory usages.
this.samples = new Map();
this.peakAllocatedMemory = 0;
// Maps zone name to their max memory consumption.
this.zonePeakMemory = Object.create(null);
// Peak memory consumed by a single zone.
this.singleZonePeakMemory = 0;
}
finalize() {
this.samples.forEach(sample => this.finalizeSample(sample));
this.start = Math.floor(this.start);
this.end = Math.ceil(this.end);
this.sortZoneNamesByPeakMemory();
}
getLabel() {
let label = `${this.address}: `;
label += ` peak=${formatBytes(this.peakAllocatedMemory)}`;
label += ` time=[${this.start}, ${this.end}] ms`;
return label;
}
finalizeSample(sample) {
const time = sample.time;
if (this.start == null) {
this.start = time;
this.end = time;
} else {
this.end = Math.max(this.end, time);
}
const allocated = sample.allocated;
if (allocated > this.peakAllocatedMemory) {
this.peakUsageTime = time;
this.peakAllocatedMemory = allocated;
}
const sample_zones = sample.zones;
if (sample_zones !== undefined) {
sample.zones.forEach((zone_sample, zone_name) => {
let zone_stats = this.zones.get(zone_name);
if (zone_stats === undefined) {
zone_stats = {max_allocated: 0, max_used: 0};
this.zones.set(zone_name, zone_stats);
}
zone_stats.max_allocated =
Math.max(zone_stats.max_allocated, zone_sample.allocated);
zone_stats.max_used = Math.max(zone_stats.max_used, zone_sample.used);
});
}
}
sortZoneNamesByPeakMemory() {
let entries = [...this.zones.keys()];
entries.sort((a, b) =>
this.zones.get(a).max_allocated - this.zones.get(b).max_allocated
);
this.sorted_zone_names = entries;
let max = 0;
for (let [key, value] of entries) {
this.zonePeakMemory[key] = value;
max = Math.max(max, value);
}
this.singleZonePeakMemory = max;
}
getInstanceTypePeakMemory(type) {
if (!(type in this.zonePeakMemory)) return 0;
return this.zonePeakMemory[type];
}
}