• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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