1// Copyright 2018 the V8 project authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5'use strict'; 6 7export class Isolate { 8 constructor(address) { 9 this.address = address; 10 this.start = null; 11 this.end = null; 12 this.samples = Object.create(null); 13 this.non_empty_instance_types = new Set(); 14 this.gcs = Object.create(null); 15 this.zonetags = []; 16 this.samples = {zone: {}}; 17 this.data_sets = new Set(); 18 this.peakMemory = 0; 19 // Maps instance_types to their max memory consumption over all gcs. 20 this.instanceTypePeakMemory = Object.create(null); 21 // Peak memory consumed by any single instance type. 22 this.singleInstanceTypePeakMemory = 0; 23 } 24 25 finalize() { 26 Object.values(this.gcs).forEach(gc => this.finalizeGC(gc)); 27 this.sortInstanceTypePeakMemory(); 28 } 29 30 getLabel() { 31 let label = `${this.address}: gc=#${Object.keys(this.gcs).length}`; 32 label += ` peak=${formatBytes(this.peakMemory)}` 33 return label; 34 } 35 36 finalizeGC(gc_data) { 37 this.data_sets.forEach(key => this.finalizeDataSet(gc_data[key])); 38 if (!('live' in gc_data)) return; 39 let liveData = gc_data.live; 40 this.peakMemory = Math.max(this.peakMemory, liveData.overall); 41 let data = liveData.instance_type_data; 42 for (let name in data) { 43 let prev = this.instanceTypePeakMemory[name] || 0; 44 this.instanceTypePeakMemory[name] = Math.max(prev, data[name].overall); 45 } 46 } 47 48 finalizeDataSet(data_set) { 49 // Create a ranked instance type array that sorts instance types by 50 // memory size (overall). 51 let data = data_set.instance_type_data; 52 let ranked_instance_types = 53 [...data_set.non_empty_instance_types].sort((a, b) => { 54 return data[a].overall - data[b].overall; 55 }); 56 // Reassemble the instance_type list sorted by size. 57 let sorted_data = Object.create(null); 58 let max = 0; 59 ranked_instance_types.forEach((name) => { 60 let entry = sorted_data[name] = data[name]; 61 max = Math.max(max, entry.overall); 62 }); 63 data_set.instance_type_data = data; 64 data_set.singleInstancePeakMemory = max; 65 66 Object.entries(data_set.instance_type_data).forEach(([name, entry]) => { 67 this.checkHistogram( 68 name, entry, data_set.bucket_sizes, 'histogram', ' overall'); 69 this.checkHistogram( 70 name, entry, data_set.bucket_sizes, 'over_allocated_histogram', 71 ' over_allocated'); 72 }); 73 } 74 75 // Check that a lower bound for histogram memory does not exceed the 76 // overall counter. 77 checkHistogram(type, entry, bucket_sizes, histogram, overallProperty) { 78 let sum = 0; 79 for (let i = 1; i < entry[histogram].length; i++) { 80 sum += entry[histogram][i] * bucket_sizes[i - 1]; 81 } 82 const overall = entry[overallProperty]; 83 if (sum >= overall) { 84 console.error( 85 `${type}: sum('${histogram}') > overall (${sum} > ${overall})`); 86 } 87 } 88 89 sortInstanceTypePeakMemory() { 90 let entries = Object.entries(this.instanceTypePeakMemory); 91 entries.sort((a, b) => {return b[1] - a[1]}); 92 this.instanceTypePeakMemory = Object.create(null); 93 let max = 0; 94 for (let [key, value] of entries) { 95 this.instanceTypePeakMemory[key] = value; 96 max = Math.max(max, value); 97 } 98 this.singleInstanceTypePeakMemory = max; 99 } 100 101 getInstanceTypePeakMemory(type) { 102 if (!(type in this.instanceTypePeakMemory)) return 0; 103 return this.instanceTypePeakMemory[type]; 104 } 105} 106