<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>
  <style>
    .entry-details {}
    
    .entry-details TD {}
    
    .details {
      width: 2em;
      border: 1px black dotted;
    }
    
    .count {
      text-align: right;
      width: 5em;
      font-family: monospace;
    }
    
    .percentage {
      text-align: right;
      width: 5em;
      font-family: monospace;
    }
    
    .key {
      padding-left: 1em;
    }
    
    .drilldown-group-title {
      font-weight: bold;
      padding: 0.5em 0 0.2em 0;
    }
  </style>
  <script>
    "use strict"
    var entries = [];

    var properties = ['type', 'category', 'file', 'filePosition', 'state',
      'key', 'isNative', 'map', 'propertiesMode', 'numberOfOwnProperties',
      'instanceType'
    ]

    class Entry {
      constructor(id, line) {
        this.id = id;
        this.line = line;
        var parts = line.split(" ");
        if (parts.length < 6) return
        this.isValid = false;
        if (parts[0][0] !== "[") return;
        if (parts[1] === "patching") return;
        this.type = parts[0].substr(1);
        this.category = "unknown";
        this.map = "unknown";
        this.propertiesMode = "unknown";
        this.numberOfOwnProperties = 0;
        this.instanceType = "unknown";
        if (this.type.indexOf("Store") !== -1) {
          this.category = "Store";
        } else if (this.type.indexOf("Load") !== -1) {
          this.category = "Load";
        }
        if (this.type.length == 0) return;
        if (this.type.indexOf('BinaryOpIC(') === 0) {
          this.type = "BinaryOpIC";
          var split = parts[0].split('(');
          this.state = "(" + split[1] + " => " + parts[2];
          var offset = this.parsePositionAndFile(parts, 6);
          if (offset == -1) return
          if (this.file === undefined) return
          this.file = this.file.slice(0, -1);
        } else {
          var offset = this.parsePositionAndFile(parts, 2);
          if (offset == -1) return
          this.state = parts[++offset];
          var mapPart = parts[offset + 1];
          if (mapPart !== undefined && mapPart.startsWith("map=")) {
            if (mapPart[4] == "(") {
              if (mapPart.endsWith(")")) {
                this.map = mapPart.substr(5, mapPart.length-6);
              } else {
                this.map = mapPart.substr(5);
              }
              offset++;
              offset = this.parseMapProperties(parts, offset);
            } else {
              this.map = mapPart.substr(4);
              offset++;
            }
            if (this.map == "(nil)") this.map = "unknown";
          } 
          if (this.type !== "CompareIC") {
            // if there is no address we have a smi key
            var address = parts[++offset];
            if (address !== undefined && address.indexOf("0x") === 0) {
              this.key = parts.slice(++offset).join(" ");
            } else {
              this.key = address;
            }
          }
        }
        this.filePosition = this.file + " " + this.position;
        if (this.key) {
          var isStringKey = false
          if (this.key.indexOf("<String[") === 0) {
            isStringKey = true;
            this.key = "\"" + this.key.slice(this.key.indexOf(']') + 3);
          } else if (this.key.indexOf("<") === 0) {
            this.key = this.key.slice(1);
          }
          if (this.key.endsWith(">]")) {
            this.key = this.key.slice(0, -2);
          } else if (this.key.endsWith("]")) {
            this.key = this.key.slice(0, -1);
          }
          if (isStringKey) {
            this.key = this.key + "\"";
          }
        }
        this.isValid = true;
      }

      parseMapProperties(parts, offset) {
        var 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.
        var offset = start;
        for (var 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() {
      var files = document.getElementById("uploadInput").files;

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

      reader.onload = function(evt) {
        entries = [];
        var end = this.result.length;
        var current = 0;
        var next = 0;
        var line;
        var i = 0;
        var entry;
        while (current < end) {
          next = this.result.indexOf("\n", current);
          if (next === -1) break;
          i++;
          line = this.result.substring(current, next);
          current = next + 1;
          entry = new Entry(i, line);
          if (entry.isValid) entries.push(entry);
        }

        document.getElementById("count").innerHTML = i;
        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 (var i = 0; i < properties.length; i++) {
          var subProperty = properties[i];
          if (this.property == subProperty) continue;
          this.groups[subProperty] = groupBy(this.entries, subProperty);
        }
      }
    }

    function groupBy(entries, property) {
      var accumulator = {};
      accumulator.__proto__ = null;
      var length = entries.length;
      for (var i = 0; i < length; i++) {
        var entry = entries[i];
        var key = entry[property];
        if (accumulator[key] == undefined) {
          accumulator[key] = new Group(property, key, entry)
        } else {
          var group = accumulator[key];
          if (group.entries == undefined) console.log([group, entry]);
          group.add(entry)
        }
      }
      var result = []
      for (var key in accumulator) {
        var 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 updateTable() {
      var select = document.getElementById("group-key");
      var key = select.options[select.selectedIndex].text;
      console.log(key);
      var tableBody = document.getElementById("table-body");
      removeAllChildren(tableBody);
      var 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) {
      var fragment = document.createDocumentFragment();

      function td(tr, content, className) {
        var td = document.createElement("td");
        td.innerHTML = content;
        td.className = className
        tr.appendChild(td);
        return td
      }
      var max = Math.min(1000, entries.length)
      for (var i = 0; i < max; i++) {
        var entry = entries[i];
        var tr = document.createElement("tr");
        tr.entry = entry;
        td(tr, '<span onclick="toggleDetails(this)">details</a>', 'details');
        td(tr, entry.percentage + "%", 'percentage');
        td(tr, entry.count, 'count');
        td(tr, escapeHtml(entry.key), 'key');
        fragment.appendChild(tr);
      }
      var omitted = entries.length - max;
      if (omitted > 0) {
        var tr = document.createElement("tr");
        var td = td(tr, 'Omitted ' + omitted + " entries.");
        td.colSpan = 4;
        fragment.appendChild(tr);
      }
      parent.appendChild(fragment);
    }

    function displayDrilldown(entry, previousSibling) {
      var tr = document.createElement('tr');
      tr.className = "entry-details";
      tr.style.display = "none";
      // indent by one td.
      tr.appendChild(document.createElement("td"));
      var td = document.createElement("td");
      td.colSpan = 3;
      for (var 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) {
      var max = 20;
      var group = entry.groups[key];
      var div = document.createElement("div")
      div.className = 'drilldown-group-title'
      div.innerHTML = key + ' [top ' + max + ' out of ' + group.length + ']';
      var table = document.createElement("table");
      display(group.slice(0, max), table, false)
      div.appendChild(table);
      return div;
    }

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

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

    function initGroupKeySelect() {
      var select = document.getElementById("group-key");
      for (var i in properties) {
        var 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>
    . premonomorphic<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 on this page:<br/>
  <code>/path/to/d8 --trace_ic your_script.js > trace.txt</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>
