2018-02-13 14:03:38 +00:00
|
|
|
// Copyright 2018 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';
|
|
|
|
|
2020-03-23 12:26:38 +00:00
|
|
|
export class Isolate {
|
2018-02-13 14:03:38 +00:00
|
|
|
constructor(address) {
|
|
|
|
this.address = address;
|
|
|
|
this.start = null;
|
|
|
|
this.end = null;
|
|
|
|
this.samples = Object.create(null);
|
|
|
|
this.non_empty_instance_types = new Set();
|
|
|
|
this.gcs = Object.create(null);
|
|
|
|
this.zonetags = [];
|
|
|
|
this.samples = {zone: {}};
|
|
|
|
this.data_sets = new Set();
|
|
|
|
this.peakMemory = 0;
|
2018-03-01 14:08:59 +00:00
|
|
|
// Maps instance_types to their max memory consumption over all gcs.
|
|
|
|
this.instanceTypePeakMemory = Object.create(null);
|
|
|
|
// Peak memory consumed by any single instance type.
|
|
|
|
this.singleInstanceTypePeakMemory = 0;
|
2018-02-13 14:03:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
finalize() {
|
|
|
|
Object.values(this.gcs).forEach(gc => this.finalizeGC(gc));
|
2018-03-01 14:08:59 +00:00
|
|
|
this.sortInstanceTypePeakMemory();
|
2018-02-13 14:03:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
getLabel() {
|
|
|
|
let label = `${this.address}: gc=#${Object.keys(this.gcs).length}`;
|
2018-03-05 16:55:18 +00:00
|
|
|
label += ` peak=${formatBytes(this.peakMemory)}`
|
2018-02-13 14:03:38 +00:00
|
|
|
return label;
|
|
|
|
}
|
|
|
|
|
|
|
|
finalizeGC(gc_data) {
|
|
|
|
this.data_sets.forEach(key => this.finalizeDataSet(gc_data[key]));
|
2018-03-01 14:08:59 +00:00
|
|
|
if (!('live' in gc_data)) return;
|
|
|
|
let liveData = gc_data.live;
|
|
|
|
this.peakMemory = Math.max(this.peakMemory, liveData.overall);
|
|
|
|
let data = liveData.instance_type_data;
|
|
|
|
for (let name in data) {
|
|
|
|
let prev = this.instanceTypePeakMemory[name] || 0;
|
|
|
|
this.instanceTypePeakMemory[name] = Math.max(prev, data[name].overall);
|
2018-02-13 14:03:38 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
finalizeDataSet(data_set) {
|
|
|
|
// Create a ranked instance type array that sorts instance types by
|
|
|
|
// memory size (overall).
|
2018-03-05 16:55:18 +00:00
|
|
|
let data = data_set.instance_type_data;
|
|
|
|
let ranked_instance_types =
|
|
|
|
[...data_set.non_empty_instance_types].sort((a, b) => {
|
|
|
|
return data[a].overall - data[b].overall;
|
2018-02-13 14:03:38 +00:00
|
|
|
});
|
2018-03-05 16:55:18 +00:00
|
|
|
// Reassemble the instance_type list sorted by size.
|
|
|
|
let sorted_data = Object.create(null);
|
|
|
|
let max = 0;
|
|
|
|
ranked_instance_types.forEach((name) => {
|
|
|
|
let entry = sorted_data[name] = data[name];
|
|
|
|
max = Math.max(max, entry.overall);
|
|
|
|
});
|
|
|
|
data_set.instance_type_data = data;
|
|
|
|
data_set.singleInstancePeakMemory = max;
|
2018-02-13 14:03:38 +00:00
|
|
|
|
|
|
|
Object.entries(data_set.instance_type_data).forEach(([name, entry]) => {
|
|
|
|
this.checkHistogram(
|
|
|
|
name, entry, data_set.bucket_sizes, 'histogram', ' overall');
|
|
|
|
this.checkHistogram(
|
|
|
|
name, entry, data_set.bucket_sizes, 'over_allocated_histogram',
|
|
|
|
' over_allocated');
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
// Check that a lower bound for histogram memory does not exceed the
|
|
|
|
// overall counter.
|
|
|
|
checkHistogram(type, entry, bucket_sizes, histogram, overallProperty) {
|
|
|
|
let sum = 0;
|
|
|
|
for (let i = 1; i < entry[histogram].length; i++) {
|
|
|
|
sum += entry[histogram][i] * bucket_sizes[i - 1];
|
|
|
|
}
|
|
|
|
const overall = entry[overallProperty];
|
|
|
|
if (sum >= overall) {
|
|
|
|
console.error(
|
|
|
|
`${type}: sum('${histogram}') > overall (${sum} > ${overall})`);
|
|
|
|
}
|
|
|
|
}
|
2018-03-01 14:08:59 +00:00
|
|
|
|
|
|
|
sortInstanceTypePeakMemory() {
|
|
|
|
let entries = Object.entries(this.instanceTypePeakMemory);
|
|
|
|
entries.sort((a, b) => {return b[1] - a[1]});
|
|
|
|
this.instanceTypePeakMemory = Object.create(null);
|
|
|
|
let max = 0;
|
|
|
|
for (let [key, value] of entries) {
|
|
|
|
this.instanceTypePeakMemory[key] = value;
|
|
|
|
max = Math.max(max, value);
|
|
|
|
}
|
|
|
|
this.singleInstanceTypePeakMemory = max;
|
|
|
|
}
|
|
|
|
|
|
|
|
getInstanceTypePeakMemory(type) {
|
|
|
|
if (!(type in this.instanceTypePeakMemory)) return 0;
|
|
|
|
return this.instanceTypePeakMemory[type];
|
|
|
|
}
|
2018-02-13 14:03:38 +00:00
|
|
|
}
|