11cb0ef41Sopenharmony_ci// Copyright 2020 the V8 project authors. All rights reserved.
21cb0ef41Sopenharmony_ci// Use of this source code is governed by a BSD-style license that can be
31cb0ef41Sopenharmony_ci// found in the LICENSE file.
41cb0ef41Sopenharmony_ci
51cb0ef41Sopenharmony_ci'use strict';
61cb0ef41Sopenharmony_ci
71cb0ef41Sopenharmony_ciexport class Isolate {
81cb0ef41Sopenharmony_ci  constructor(address) {
91cb0ef41Sopenharmony_ci    this.address = address;
101cb0ef41Sopenharmony_ci    this.start = null;
111cb0ef41Sopenharmony_ci    this.end = null;
121cb0ef41Sopenharmony_ci    this.peakUsageTime = null;
131cb0ef41Sopenharmony_ci    // Maps zone name to per-zone statistics.
141cb0ef41Sopenharmony_ci    this.zones = new Map();
151cb0ef41Sopenharmony_ci    // Zone names sorted by memory usage (from low to high).
161cb0ef41Sopenharmony_ci    this.sorted_zone_names = [];
171cb0ef41Sopenharmony_ci    // Maps time to total and per-zone memory usages.
181cb0ef41Sopenharmony_ci    this.samples = new Map();
191cb0ef41Sopenharmony_ci
201cb0ef41Sopenharmony_ci    this.peakAllocatedMemory = 0;
211cb0ef41Sopenharmony_ci
221cb0ef41Sopenharmony_ci    // Maps zone name to their max memory consumption.
231cb0ef41Sopenharmony_ci    this.zonePeakMemory = Object.create(null);
241cb0ef41Sopenharmony_ci    // Peak memory consumed by a single zone.
251cb0ef41Sopenharmony_ci    this.singleZonePeakMemory = 0;
261cb0ef41Sopenharmony_ci  }
271cb0ef41Sopenharmony_ci
281cb0ef41Sopenharmony_ci  finalize() {
291cb0ef41Sopenharmony_ci    this.samples.forEach(sample => this.finalizeSample(sample));
301cb0ef41Sopenharmony_ci    this.start = Math.floor(this.start);
311cb0ef41Sopenharmony_ci    this.end = Math.ceil(this.end);
321cb0ef41Sopenharmony_ci    this.sortZoneNamesByPeakMemory();
331cb0ef41Sopenharmony_ci  }
341cb0ef41Sopenharmony_ci
351cb0ef41Sopenharmony_ci  getLabel() {
361cb0ef41Sopenharmony_ci    let label = `${this.address}: `;
371cb0ef41Sopenharmony_ci    label += ` peak=${formatBytes(this.peakAllocatedMemory)}`;
381cb0ef41Sopenharmony_ci    label += ` time=[${this.start}, ${this.end}] ms`;
391cb0ef41Sopenharmony_ci    return label;
401cb0ef41Sopenharmony_ci  }
411cb0ef41Sopenharmony_ci
421cb0ef41Sopenharmony_ci  finalizeSample(sample) {
431cb0ef41Sopenharmony_ci    const time = sample.time;
441cb0ef41Sopenharmony_ci    if (this.start == null) {
451cb0ef41Sopenharmony_ci      this.start = time;
461cb0ef41Sopenharmony_ci      this.end = time;
471cb0ef41Sopenharmony_ci    } else {
481cb0ef41Sopenharmony_ci      this.end = Math.max(this.end, time);
491cb0ef41Sopenharmony_ci    }
501cb0ef41Sopenharmony_ci
511cb0ef41Sopenharmony_ci    const allocated = sample.allocated;
521cb0ef41Sopenharmony_ci    if (allocated > this.peakAllocatedMemory) {
531cb0ef41Sopenharmony_ci      this.peakUsageTime = time;
541cb0ef41Sopenharmony_ci      this.peakAllocatedMemory = allocated;
551cb0ef41Sopenharmony_ci    }
561cb0ef41Sopenharmony_ci
571cb0ef41Sopenharmony_ci    const sample_zones = sample.zones;
581cb0ef41Sopenharmony_ci    if (sample_zones !== undefined) {
591cb0ef41Sopenharmony_ci      sample.zones.forEach((zone_sample, zone_name) => {
601cb0ef41Sopenharmony_ci        let zone_stats = this.zones.get(zone_name);
611cb0ef41Sopenharmony_ci        if (zone_stats === undefined) {
621cb0ef41Sopenharmony_ci          zone_stats = {max_allocated: 0, max_used: 0};
631cb0ef41Sopenharmony_ci          this.zones.set(zone_name, zone_stats);
641cb0ef41Sopenharmony_ci        }
651cb0ef41Sopenharmony_ci
661cb0ef41Sopenharmony_ci        zone_stats.max_allocated =
671cb0ef41Sopenharmony_ci            Math.max(zone_stats.max_allocated, zone_sample.allocated);
681cb0ef41Sopenharmony_ci        zone_stats.max_used = Math.max(zone_stats.max_used, zone_sample.used);
691cb0ef41Sopenharmony_ci      });
701cb0ef41Sopenharmony_ci    }
711cb0ef41Sopenharmony_ci  }
721cb0ef41Sopenharmony_ci
731cb0ef41Sopenharmony_ci  sortZoneNamesByPeakMemory() {
741cb0ef41Sopenharmony_ci    let entries = [...this.zones.keys()];
751cb0ef41Sopenharmony_ci    entries.sort((a, b) =>
761cb0ef41Sopenharmony_ci      this.zones.get(a).max_allocated - this.zones.get(b).max_allocated
771cb0ef41Sopenharmony_ci    );
781cb0ef41Sopenharmony_ci    this.sorted_zone_names = entries;
791cb0ef41Sopenharmony_ci
801cb0ef41Sopenharmony_ci    let max = 0;
811cb0ef41Sopenharmony_ci    for (let [key, value] of entries) {
821cb0ef41Sopenharmony_ci      this.zonePeakMemory[key] = value;
831cb0ef41Sopenharmony_ci      max = Math.max(max, value);
841cb0ef41Sopenharmony_ci    }
851cb0ef41Sopenharmony_ci    this.singleZonePeakMemory = max;
861cb0ef41Sopenharmony_ci  }
871cb0ef41Sopenharmony_ci
881cb0ef41Sopenharmony_ci  getInstanceTypePeakMemory(type) {
891cb0ef41Sopenharmony_ci    if (!(type in this.zonePeakMemory)) return 0;
901cb0ef41Sopenharmony_ci    return this.zonePeakMemory[type];
911cb0ef41Sopenharmony_ci  }
921cb0ef41Sopenharmony_ci}
93