<!DOCTYPE html>
<html>
<!--
Copyright 2016 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.
-->

<head>
  <meta charset="utf-8">
  <title>V8 IC explorer</title>
  <style>
    html {
      font-family: monospace;
    }

    .entry-details {}

    .entry-details TD {}

    .details {
      width: 0.1em;
    }

    .details span {
      padding: 0 0.4em 0 0.4em;
      background-color: black;
      color: white;
      border-radius: 25px;
      text-align: center;
      cursor: -webkit-zoom-in;
    }

    .count {
      text-align: right;
      width: 5em;
    }

    .percentage {
      text-align: right;
      width: 5em;
    }

    .key {
      padding-left: 1em;
    }

    .drilldown-group-title {
      font-weight: bold;
      padding: 0.5em 0 0.2em 0;
    }
  </style>
  <script src="./splaytree.js"></script>
  <script src="./codemap.js"></script>
  <script src="./csvparser.js"></script>
  <script src="./consarray.js"></script>
  <script src="./profile.js"></script>
  <script src="./profile_view.js"></script>
  <script src="./logreader.js"></script>
  <script src="./arguments.js"></script>
  <script src="./ic-processor.js"></script>
  <script src="./SourceMap.js"></script>

  <script>
    "use strict"
    let entries = [];

    let properties = ['type', 'category', 'functionName', 'filePosition',
      'state', 'key', 'map', 'reason', 'file',
    ];

    // For compatibility with console scripts:
    print = console.log;

  class CustomIcProcessor extends IcProcessor {
    constructor() {
      super();
      this.entries = [];
    }

    functionName(pc) {
      let entry = this.profile_.findEntry(pc);
      return this.formatName(entry);
    }

    processPropertyIC(
        type, pc, time, line, column, old_state, new_state, map, key, modifier,
        slow_reason) {
      let fnName = this.functionName(pc);
      this.entries.push(new Entry(
          type, fnName, time, line, column, key, old_state, new_state, map,
          slow_reason));
    }
  };


  class Entry {
  constructor(
      type, fn_file, time, line, column, key, oldState, newState, map, reason,
      additional) {
    this.time = time;
    this.type = type;
    this.category = 'other';
    if (this.type.indexOf('Store') !== -1) {
      this.category = 'Store';
    } else if (this.type.indexOf('Load') !== -1) {
      this.category = 'Load';
    }
    let parts = fn_file.split(' ');
    this.functionName = parts[0];
    this.file = parts[1];
    let position = line + ':' + column;
    this.filePosition = this.file + ':' + position;
    this.oldState = oldState;
    this.newState = newState;
    this.state = this.oldState + ' → ' + this.newState;
    this.key = key;
    this.map = map.toString(16);
    this.reason = reason;
    this.additional = additional;
  }

  parseMapProperties(parts, offset) {
    let next = parts[++offset];
    if (!next.startsWith('dict')) return offset;
    this.propertiesMode = next.substr(5) == '0' ? 'fast' : 'slow';
    this.numberOfOwnProperties = parts[++offset].substr(4);
    next = parts[++offset];
    this.instanceType = next.substr(5, next.length - 6);
    return offset;
  }

  parsePositionAndFile(parts, start) {
    // find the position of 'at' in the parts array.
    let offset = start;
    for (let i = start + 1; i < parts.length; i++) {
      offset++;
      if (parts[i] == 'at') break;
    }
    if (parts[offset] !== 'at') return -1;
    this.position = parts.slice(start, offset).join(' ');
    offset += 1;
    this.isNative = parts[offset] == 'native'
    offset += this.isNative ? 1 : 0;
    this.file = parts[offset];
    return offset;
  }
}

    function loadFile() {
      let files = document.getElementById("uploadInput").files;

      let file = files[0];
      let reader = new FileReader();

      reader.onload = function(evt) {
        let icProcessor = new CustomIcProcessor();
        icProcessor.processString(this.result);
        entries = icProcessor.entries;

        document.getElementById("count").innerHTML = entries.length;
        updateTable();
      }
      reader.readAsText(file);
      initGroupKeySelect();
    }


    class Group {
      constructor(property, key, entry) {
        this.property = property;
        this.key = key;
        this.count = 1;
        this.entries = [entry];
        this.percentage = undefined;
        this.groups = undefined;
      }

      add(entry) {
        this.count++;
        this.entries.push(entry)
      }

      createSubGroups() {
        this.groups = {};
        for (let i = 0; i < properties.length; i++) {
          let subProperty = properties[i];
          if (this.property == subProperty) continue;
          this.groups[subProperty] = groupBy(this.entries, subProperty);
        }
      }
    }

    function groupBy(entries, property) {
      let accumulator = Object.create(null);
      let length = entries.length;
      for (let i = 0; i < length; i++) {
        let entry = entries[i];
        let key = entry[property];
        if (accumulator[key] == undefined) {
          accumulator[key] = new Group(property, key, entry)
        } else {
          let group = accumulator[key];
          if (group.entries == undefined) console.log([group, entry]);
          group.add(entry)
        }
      }
      let result = []
      for (let key in accumulator) {
        let group = accumulator[key];
        group.percentage = Math.round(group.count / length * 100 * 100) / 100;
        result.push(group);
      }
      result.sort((a, b) => {
        return b.count - a.count
      });
      return result;
    }



    function escapeHtml(unsafe) {
      if (!unsafe) return "";
      return unsafe.toString()
        .replace(/&/g, "&amp;")
        .replace(/</g, "&lt;")
        .replace(/>/g, "&gt;")
        .replace(/"/g, "&quot;")
        .replace(/'/g, "&#039;");
    }

    function processValue(unsafe) {
      if (!unsafe) return "";
      if (!unsafe.startsWith("http")) return escapeHtml(unsafe);
      let a = document.createElement("a");
      a.href = unsafe;
      a.textContent = unsafe;
      return a;
    }

    function updateTable() {
      let select = document.getElementById("group-key");
      let key = select.options[select.selectedIndex].text;
      let tableBody = document.getElementById("table-body");
      removeAllChildren(tableBody);
      let groups = groupBy(entries, key, true);
      display(groups, tableBody);
    }

    function selecedOption(node) {
      return node.options[node.selectedIndex]
    }

    function removeAllChildren(node) {
      while (node.firstChild) {
        node.removeChild(node.firstChild);
      }
    }

    function display(entries, parent) {
      let fragment = document.createDocumentFragment();

      function td(tr, content, className) {
        let node = document.createElement("td");
        if (typeof content == "object") {
          node.appendChild(content);
        } else {
          node.innerHTML = content;
        }
        node.className = className
        tr.appendChild(node);
        return node
      }

      let max = Math.min(1000, entries.length)
      for (let i = 0; i < max; i++) {
        let entry = entries[i];
        let tr = document.createElement("tr");
        tr.entry = entry;
        td(tr, '<span onclick="toggleDetails(this)">&#8505;</a>', 'details');
        td(tr, entry.percentage + "%", 'percentage');
        td(tr, entry.count, 'count');
        td(tr, processValue(entry.key), 'key');
        fragment.appendChild(tr);
      }
      let omitted = entries.length - max;
      if (omitted > 0) {
        let tr = document.createElement("tr");
        let tdNode = td(tr, 'Omitted ' + omitted + " entries.");
        tdNode.colSpan = 4;
        fragment.appendChild(tr);
      }
      parent.appendChild(fragment);
    }

    function displayDrilldown(entry, previousSibling) {
      let tr = document.createElement('tr');
      tr.className = "entry-details";
      tr.style.display = "none";
      // indent by one td.
      tr.appendChild(document.createElement("td"));
      let td = document.createElement("td");
      td.colSpan = 3;
      for (let key in entry.groups) {
        td.appendChild(displayDrilldownGroup(entry, key));
      }
      tr.appendChild(td);
      // Append the new TR after previousSibling.
      previousSibling.parentNode.insertBefore(tr, previousSibling.nextSibling)
    }

    function displayDrilldownGroup(entry, key) {
      let max = 20;
      let group = entry.groups[key];
      let div = document.createElement("div")
      div.className = 'drilldown-group-title'
      div.textContent = key + ' [top ' + max + ' out of ' + group.length + ']';
      let table = document.createElement("table");
      display(group.slice(0, max), table, false)
      div.appendChild(table);
      return div;
    }

    function toggleDetails(node) {
      let tr = node.parentNode.parentNode;
      let entry = tr.entry;

      // Create subgroup in-place if the don't exist yet.
      if (entry.groups === undefined) {
        entry.createSubGroups();
        displayDrilldown(entry, tr);
      }
      let details = tr.nextSibling;
      let display = details.style.display;
      if (display != "none") {
        display = "none";
      } else {
        display = "table-row"
      };
      details.style.display = display;
    }

    function initGroupKeySelect() {
      let select = document.getElementById("group-key");
      select.options.length = 0;
      for (let i in properties) {
        let option = document.createElement("option");
        option.text = properties[i];
        select.add(option);
      }
    }

    function handleOnLoad() {
      document.querySelector("#uploadInput").focus();
    }
  </script>
</head>

<body onload="handleOnLoad()">
  <h1>
    <span style="color: #00FF00">I</span>
    <span style="color: #FF00FF">C</span>
    <span style="color: #00FFFF">E</span>
  </h1> Your IC-Explorer.

  <div id="legend" style="padding-right: 200px">
    <div style="float:right;  border-style: solid; border-width: 1px; padding:20px">
      0 uninitialized<br>
      X no feedback<br>
      1 monomorphic<br>
      ^ recompute handler<br>
      P polymorphic<br>
      N megamorphic<br>
      G generic
    </div>
  </div>

  <h2>Usage</h2> Run your script with <code>--trace_ic</code> and upload <code>v8.log</code> on this page:<br/>
  <code>/path/to/d8 --trace_ic your_script.js</code>
  <h2>Data</h2>
  <form name="fileForm">
    <p>
      <input id="uploadInput" type="file" name="files" onchange="loadFile();"> trace entries: <span id="count">0</span>
    </p>
  </form>
  <h2>Result</h2>
  <p>
    Group-Key:
    <select id="group-key" onchange="updateTable()"></select>
  </p>
  <p>
    <table id="table" width="100%">
      <tbody id="table-body">
      </tbody>
    </table>
  </p>
</body>

</html>
