model.js 2.59 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92
// 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];
  }
}