11cb0ef41Sopenharmony_ci// Copyright 2018 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_ciimport {
81cb0ef41Sopenharmony_ci  VIEW_BY_INSTANCE_TYPE,
91cb0ef41Sopenharmony_ci  VIEW_BY_INSTANCE_CATEGORY,
101cb0ef41Sopenharmony_ci  VIEW_BY_FIELD_TYPE
111cb0ef41Sopenharmony_ci} from './details-selection.js';
121cb0ef41Sopenharmony_ci
131cb0ef41Sopenharmony_cidefineCustomElement('global-timeline', (templateText) =>
141cb0ef41Sopenharmony_ci class GlobalTimeline extends HTMLElement {
151cb0ef41Sopenharmony_ci  constructor() {
161cb0ef41Sopenharmony_ci    super();
171cb0ef41Sopenharmony_ci    const shadowRoot = this.attachShadow({mode: 'open'});
181cb0ef41Sopenharmony_ci    shadowRoot.innerHTML = templateText;
191cb0ef41Sopenharmony_ci  }
201cb0ef41Sopenharmony_ci
211cb0ef41Sopenharmony_ci  $(id) {
221cb0ef41Sopenharmony_ci    return this.shadowRoot.querySelector(id);
231cb0ef41Sopenharmony_ci  }
241cb0ef41Sopenharmony_ci
251cb0ef41Sopenharmony_ci  set data(value) {
261cb0ef41Sopenharmony_ci    this._data = value;
271cb0ef41Sopenharmony_ci    this.stateChanged();
281cb0ef41Sopenharmony_ci  }
291cb0ef41Sopenharmony_ci
301cb0ef41Sopenharmony_ci  get data() {
311cb0ef41Sopenharmony_ci    return this._data;
321cb0ef41Sopenharmony_ci  }
331cb0ef41Sopenharmony_ci
341cb0ef41Sopenharmony_ci  set selection(value) {
351cb0ef41Sopenharmony_ci    this._selection = value;
361cb0ef41Sopenharmony_ci    this.stateChanged();
371cb0ef41Sopenharmony_ci  }
381cb0ef41Sopenharmony_ci
391cb0ef41Sopenharmony_ci  get selection() {
401cb0ef41Sopenharmony_ci    return this._selection;
411cb0ef41Sopenharmony_ci  }
421cb0ef41Sopenharmony_ci
431cb0ef41Sopenharmony_ci  isValid() {
441cb0ef41Sopenharmony_ci    return this.data && this.selection;
451cb0ef41Sopenharmony_ci  }
461cb0ef41Sopenharmony_ci
471cb0ef41Sopenharmony_ci  hide() {
481cb0ef41Sopenharmony_ci    this.$('#container').style.display = 'none';
491cb0ef41Sopenharmony_ci  }
501cb0ef41Sopenharmony_ci
511cb0ef41Sopenharmony_ci  show() {
521cb0ef41Sopenharmony_ci    this.$('#container').style.display = 'block';
531cb0ef41Sopenharmony_ci  }
541cb0ef41Sopenharmony_ci
551cb0ef41Sopenharmony_ci  stateChanged() {
561cb0ef41Sopenharmony_ci    if (this.isValid()) {
571cb0ef41Sopenharmony_ci      this.drawChart();
581cb0ef41Sopenharmony_ci    } else {
591cb0ef41Sopenharmony_ci      this.hide();
601cb0ef41Sopenharmony_ci    }
611cb0ef41Sopenharmony_ci  }
621cb0ef41Sopenharmony_ci
631cb0ef41Sopenharmony_ci  getFieldData() {
641cb0ef41Sopenharmony_ci    const labels = [
651cb0ef41Sopenharmony_ci      {type: 'number', label: 'Time'},
661cb0ef41Sopenharmony_ci      {type: 'number', label: 'Ptr compression benefit'},
671cb0ef41Sopenharmony_ci      {type: 'string', role: 'tooltip'},
681cb0ef41Sopenharmony_ci      {type: 'number', label: 'Embedder fields'},
691cb0ef41Sopenharmony_ci      {type: 'number', label: 'Tagged fields (excl. in-object Smis)'},
701cb0ef41Sopenharmony_ci      {type: 'number', label: 'In-object Smi-only fields'},
711cb0ef41Sopenharmony_ci      {type: 'number', label: 'Other raw fields'},
721cb0ef41Sopenharmony_ci      {type: 'number', label: 'Unboxed doubles'},
731cb0ef41Sopenharmony_ci      {type: 'number', label: 'Boxed doubles'},
741cb0ef41Sopenharmony_ci      {type: 'number', label: 'String data'}
751cb0ef41Sopenharmony_ci    ];
761cb0ef41Sopenharmony_ci    const chart_data = [labels];
771cb0ef41Sopenharmony_ci    const isolate_data = this.data[this.selection.isolate];
781cb0ef41Sopenharmony_ci    let sum_total = 0;
791cb0ef41Sopenharmony_ci    let sum_ptr_compr_benefit_perc = 0;
801cb0ef41Sopenharmony_ci    let count = 0;
811cb0ef41Sopenharmony_ci    Object.keys(isolate_data.gcs).forEach(gc_key => {
821cb0ef41Sopenharmony_ci      const gc_data = isolate_data.gcs[gc_key];
831cb0ef41Sopenharmony_ci      const data_set = gc_data[this.selection.data_set].field_data;
841cb0ef41Sopenharmony_ci      const data = [];
851cb0ef41Sopenharmony_ci      data.push(gc_data.time * kMillis2Seconds);
861cb0ef41Sopenharmony_ci      const total = data_set.tagged_fields +
871cb0ef41Sopenharmony_ci                    data_set.inobject_smi_fields +
881cb0ef41Sopenharmony_ci                    data_set.embedder_fields +
891cb0ef41Sopenharmony_ci                    data_set.other_raw_fields +
901cb0ef41Sopenharmony_ci                    data_set.unboxed_double_fields +
911cb0ef41Sopenharmony_ci                    data_set.boxed_double_fields +
921cb0ef41Sopenharmony_ci                    data_set.string_data;
931cb0ef41Sopenharmony_ci      const ptr_compr_benefit =
941cb0ef41Sopenharmony_ci          (data_set.inobject_smi_fields + data_set.tagged_fields) / 2;
951cb0ef41Sopenharmony_ci      const ptr_compr_benefit_perc = ptr_compr_benefit / total * 100;
961cb0ef41Sopenharmony_ci      sum_total += total;
971cb0ef41Sopenharmony_ci      sum_ptr_compr_benefit_perc += ptr_compr_benefit_perc;
981cb0ef41Sopenharmony_ci      count++;
991cb0ef41Sopenharmony_ci      const tooltip = "Ptr compression benefit: " +
1001cb0ef41Sopenharmony_ci                      (ptr_compr_benefit / KB).toFixed(2) + "KB " +
1011cb0ef41Sopenharmony_ci                      " (" + ptr_compr_benefit_perc.toFixed(2) + "%)";
1021cb0ef41Sopenharmony_ci      data.push(ptr_compr_benefit / KB);
1031cb0ef41Sopenharmony_ci      data.push(tooltip);
1041cb0ef41Sopenharmony_ci      data.push(data_set.embedder_fields / KB);
1051cb0ef41Sopenharmony_ci      data.push(data_set.tagged_fields / KB);
1061cb0ef41Sopenharmony_ci      data.push(data_set.inobject_smi_fields / KB);
1071cb0ef41Sopenharmony_ci      data.push(data_set.other_raw_fields / KB);
1081cb0ef41Sopenharmony_ci      data.push(data_set.unboxed_double_fields / KB);
1091cb0ef41Sopenharmony_ci      data.push(data_set.boxed_double_fields / KB);
1101cb0ef41Sopenharmony_ci      data.push(data_set.string_data / KB);
1111cb0ef41Sopenharmony_ci      chart_data.push(data);
1121cb0ef41Sopenharmony_ci    });
1131cb0ef41Sopenharmony_ci    const avg_ptr_compr_benefit_perc =
1141cb0ef41Sopenharmony_ci        count ? sum_ptr_compr_benefit_perc / count : 0;
1151cb0ef41Sopenharmony_ci    console.log("==================================================");
1161cb0ef41Sopenharmony_ci    console.log("= Average ptr compression benefit is " +
1171cb0ef41Sopenharmony_ci                avg_ptr_compr_benefit_perc.toFixed(2) + "%");
1181cb0ef41Sopenharmony_ci    console.log("= Average V8 heap size " +
1191cb0ef41Sopenharmony_ci                (sum_total / count / KB).toFixed(2) + " KB");
1201cb0ef41Sopenharmony_ci    console.log("==================================================");
1211cb0ef41Sopenharmony_ci    return chart_data;
1221cb0ef41Sopenharmony_ci  }
1231cb0ef41Sopenharmony_ci
1241cb0ef41Sopenharmony_ci  getCategoryData() {
1251cb0ef41Sopenharmony_ci    const categories = Object.keys(this.selection.categories)
1261cb0ef41Sopenharmony_ci                           .map(k => this.selection.category_names.get(k));
1271cb0ef41Sopenharmony_ci    const labels = ['Time', ...categories];
1281cb0ef41Sopenharmony_ci    const chart_data = [labels];
1291cb0ef41Sopenharmony_ci    const isolate_data = this.data[this.selection.isolate];
1301cb0ef41Sopenharmony_ci    Object.keys(isolate_data.gcs).forEach(gc_key => {
1311cb0ef41Sopenharmony_ci      const gc_data = isolate_data.gcs[gc_key];
1321cb0ef41Sopenharmony_ci      const data_set = gc_data[this.selection.data_set].instance_type_data;
1331cb0ef41Sopenharmony_ci      const data = [];
1341cb0ef41Sopenharmony_ci      data.push(gc_data.time * kMillis2Seconds);
1351cb0ef41Sopenharmony_ci      Object.values(this.selection.categories).forEach(instance_types => {
1361cb0ef41Sopenharmony_ci        data.push(
1371cb0ef41Sopenharmony_ci            instance_types
1381cb0ef41Sopenharmony_ci                .map(instance_type => {
1391cb0ef41Sopenharmony_ci                  return data_set[instance_type].overall;
1401cb0ef41Sopenharmony_ci                })
1411cb0ef41Sopenharmony_ci                .reduce((accu, current) => accu + current, 0) /
1421cb0ef41Sopenharmony_ci            KB);
1431cb0ef41Sopenharmony_ci      });
1441cb0ef41Sopenharmony_ci      chart_data.push(data);
1451cb0ef41Sopenharmony_ci    });
1461cb0ef41Sopenharmony_ci    return chart_data;
1471cb0ef41Sopenharmony_ci  }
1481cb0ef41Sopenharmony_ci
1491cb0ef41Sopenharmony_ci  getInstanceTypeData() {
1501cb0ef41Sopenharmony_ci    const instance_types =
1511cb0ef41Sopenharmony_ci        Object.values(this.selection.categories)
1521cb0ef41Sopenharmony_ci            .reduce((accu, current) => accu.concat(current), []);
1531cb0ef41Sopenharmony_ci    const labels = ['Time', ...instance_types];
1541cb0ef41Sopenharmony_ci    const chart_data = [labels];
1551cb0ef41Sopenharmony_ci    const isolate_data = this.data[this.selection.isolate];
1561cb0ef41Sopenharmony_ci    Object.keys(isolate_data.gcs).forEach(gc_key => {
1571cb0ef41Sopenharmony_ci      const gc_data = isolate_data.gcs[gc_key];
1581cb0ef41Sopenharmony_ci      const data_set = gc_data[this.selection.data_set].instance_type_data;
1591cb0ef41Sopenharmony_ci      const data = [];
1601cb0ef41Sopenharmony_ci      data.push(gc_data.time * kMillis2Seconds);
1611cb0ef41Sopenharmony_ci      instance_types.forEach(instance_type => {
1621cb0ef41Sopenharmony_ci        data.push(data_set[instance_type].overall / KB);
1631cb0ef41Sopenharmony_ci      });
1641cb0ef41Sopenharmony_ci      chart_data.push(data);
1651cb0ef41Sopenharmony_ci    });
1661cb0ef41Sopenharmony_ci    return chart_data;
1671cb0ef41Sopenharmony_ci  }
1681cb0ef41Sopenharmony_ci
1691cb0ef41Sopenharmony_ci  getChartData() {
1701cb0ef41Sopenharmony_ci    switch (this.selection.data_view) {
1711cb0ef41Sopenharmony_ci      case VIEW_BY_FIELD_TYPE:
1721cb0ef41Sopenharmony_ci        return this.getFieldData();
1731cb0ef41Sopenharmony_ci      case VIEW_BY_INSTANCE_CATEGORY:
1741cb0ef41Sopenharmony_ci        return this.getCategoryData();
1751cb0ef41Sopenharmony_ci      case VIEW_BY_INSTANCE_TYPE:
1761cb0ef41Sopenharmony_ci      default:
1771cb0ef41Sopenharmony_ci        return this.getInstanceTypeData();
1781cb0ef41Sopenharmony_ci    }
1791cb0ef41Sopenharmony_ci  }
1801cb0ef41Sopenharmony_ci
1811cb0ef41Sopenharmony_ci  getChartOptions() {
1821cb0ef41Sopenharmony_ci    const options = {
1831cb0ef41Sopenharmony_ci      isStacked: true,
1841cb0ef41Sopenharmony_ci      hAxis: {
1851cb0ef41Sopenharmony_ci        format: '###.##s',
1861cb0ef41Sopenharmony_ci        title: 'Time [s]',
1871cb0ef41Sopenharmony_ci      },
1881cb0ef41Sopenharmony_ci      vAxis: {
1891cb0ef41Sopenharmony_ci        format: '#,###KB',
1901cb0ef41Sopenharmony_ci        title: 'Memory consumption [KBytes]'
1911cb0ef41Sopenharmony_ci      },
1921cb0ef41Sopenharmony_ci      chartArea: {left:100, width: '85%', height: '70%'},
1931cb0ef41Sopenharmony_ci      legend: {position: 'top', maxLines: '1'},
1941cb0ef41Sopenharmony_ci      pointsVisible: true,
1951cb0ef41Sopenharmony_ci      pointSize: 5,
1961cb0ef41Sopenharmony_ci      explorer: {},
1971cb0ef41Sopenharmony_ci    };
1981cb0ef41Sopenharmony_ci    switch (this.selection.data_view) {
1991cb0ef41Sopenharmony_ci      case VIEW_BY_FIELD_TYPE:
2001cb0ef41Sopenharmony_ci        // Overlay pointer compression benefit on top of the graph
2011cb0ef41Sopenharmony_ci        return Object.assign(options, {
2021cb0ef41Sopenharmony_ci          series: {0: {type: 'line', lineDashStyle: [13, 13]}},
2031cb0ef41Sopenharmony_ci        });
2041cb0ef41Sopenharmony_ci      case VIEW_BY_INSTANCE_CATEGORY:
2051cb0ef41Sopenharmony_ci      case VIEW_BY_INSTANCE_TYPE:
2061cb0ef41Sopenharmony_ci      default:
2071cb0ef41Sopenharmony_ci        return options;
2081cb0ef41Sopenharmony_ci    }
2091cb0ef41Sopenharmony_ci  }
2101cb0ef41Sopenharmony_ci
2111cb0ef41Sopenharmony_ci  drawChart() {
2121cb0ef41Sopenharmony_ci    setTimeout(() => this._drawChart(), 10);
2131cb0ef41Sopenharmony_ci  }
2141cb0ef41Sopenharmony_ci
2151cb0ef41Sopenharmony_ci  _drawChart() {
2161cb0ef41Sopenharmony_ci    console.assert(this.data, 'invalid data');
2171cb0ef41Sopenharmony_ci    console.assert(this.selection, 'invalid selection');
2181cb0ef41Sopenharmony_ci
2191cb0ef41Sopenharmony_ci    const chart_data = this.getChartData();
2201cb0ef41Sopenharmony_ci
2211cb0ef41Sopenharmony_ci    const data = google.visualization.arrayToDataTable(chart_data);
2221cb0ef41Sopenharmony_ci    const options = this.getChartOptions();
2231cb0ef41Sopenharmony_ci    const chart = new google.visualization.AreaChart(this.$('#chart'));
2241cb0ef41Sopenharmony_ci    this.show();
2251cb0ef41Sopenharmony_ci    chart.draw(data, google.charts.Line.convertOptions(options));
2261cb0ef41Sopenharmony_ci  }
2271cb0ef41Sopenharmony_ci});
228