<!DOCTYPE html>
<html>
  <head>
    <title>about:memory</title>
    <script>
      document.addEventListener("DOMContentLoaded", start);

      function insertNode(root, report) {
        let currentNode = root;
        for (let path of report.path) {
          if (!currentNode[path]) {
            currentNode[path] = { total: 0, container: true };
          }
          currentNode = currentNode[path];
          currentNode.total += report.size;
        }
        currentNode.size = report.size;
        currentNode.container = false;
      }

      function formatBytes(bytes) {
        if (bytes < 1024) {
          return bytes + " B";
        } else if (bytes < 1024 * 1024) {
          return (bytes / 1024).toFixed(2) + " KiB";
        } else if (bytes < 1024 * 1024 * 1024) {
          return (bytes / (1024 * 1024)).toFixed(2) + " MiB";
        } else {
          return (bytes / (1024 * 1024 * 1024)).toFixed(2) + " GiB";
        }
      }

      function formattedSize(size) {
        // Use enough padding to take into account the "MiB" part.
        return formatBytes(size).padStart(10);
      }

      function convertNodeToDOM(node, name = null) {
        let result = document.createDocumentFragment();

        if (node.container) {
          let details = document.createElement("details");
          let summary = document.createElement("summary");
          summary.textContent = `${formattedSize(node.total)} -- ${name}`;
          details.append(summary);
          result.append(details);

          // Add the children in descending order of total size.
          let entries = Object.entries(node)
            .filter((item) => {
              return !["total", "size", "container"].includes(item[0]);
            })
            .sort((a, b) => b[1].total - a[1].total)
            .forEach((item) =>
              details.append(convertNodeToDOM(item[1], item[0]))
            );
        } else {
          let inner = document.createElement("div");
          inner.textContent = `${formattedSize(node.size)} -- ${name}`;
          result.append(inner);
        }

        return result;
      }

      function reportsForProcess(processReport) {
        let explicitRoot = {};
        let nonExplicitRoot = {};

        let jemallocHeapReportedSize = 0;
        let systemHeapReportedSize = 0;

        let jemallocHeapAllocatedSize = NaN;
        let systemHeapAllocatedSize = NaN;

        // In content processes, get the list of urls.
        let urls = new Set();

        processReport.reports.forEach((report) => {
          if (report.path[0].startsWith("url(")) {
            // This can be a list of urls.
            let path_urls = report.path[0].slice(4, -1).split(", ");
            path_urls.forEach((url) => urls.add(url));
          }

          // Add "explicit" to the start of the path, when appropriate.
          if (report.kind.startsWith("Explicit")) {
            report.path.unshift("explicit");
          }

          // Update the reported fractions of the heaps, when appropriate.
          if (report.kind == "ExplicitJemallocHeapSize") {
            jemallocHeapReportedSize += report.size;
          } else if (report.kind == "ExplicitSystemHeapSize") {
            systemHeapReportedSize += report.size;
          }

          // Record total size of the heaps, when we see them.
          if (report.path.length == 1) {
            if (report.path[0] == "jemalloc-heap-allocated") {
              jemallocHeapAllocatedSize = report.size;
            } else if (report.path[0] == "system-heap-allocated") {
              systemHeapAllocatedSize = report.size;
            }
          }

          // Insert this report at the proper position.
          insertNode(
            report.kind.startsWith("Explicit") ? explicitRoot : nonExplicitRoot,
            report
          );
        });

        // Compute and insert the heap-unclassified values.
        if (!isNaN(jemallocHeapAllocatedSize)) {
          insertNode(explicitRoot, {
            path: ["explicit", "jemalloc-heap-unclassified"],
            size: jemallocHeapAllocatedSize - jemallocHeapReportedSize,
          });
        }
        if (!isNaN(systemHeapAllocatedSize)) {
          insertNode(explicitRoot, {
            path: ["explicit", "system-heap-unclassified"],
            size: systemHeapAllocatedSize - systemHeapReportedSize,
          });
        }

        // Create the DOM structure for each process report:
        // <div class=process> <h4>...<h4> <pre> ...</pre> </div>
        let container = document.createElement("div");
        container.classList.add("process");
        let reportTitle = document.createElement("h4");
        reportTitle.textContent = `${
          processReport.isMainProcess ? "Main Process" : "Content Process"
        } (pid ${processReport.pid}) ${[...urls.values()].join(", ")}`;

        container.append(reportTitle);
        let reportNode = document.createElement("pre");
        reportNode.classList.add("report");
        container.append(reportNode);

        reportNode.append(convertNodeToDOM(explicitRoot.explicit, "explicit"));

        for (let prop in nonExplicitRoot) {
          reportNode.append(convertNodeToDOM(nonExplicitRoot[prop], prop));
        }

        // Make sure we always put the main process first.
        if (processReport.isMainProcess) {
          window.reports.prepend(container);
        } else {
          window.reports.append(container);
        }
      }

      function start() {
        window.startButton.onclick = async () => {
          let content = await navigator.servo.reportMemory();
          let reports = JSON.parse(content);
          if (reports.error) {
            console.error(reports.error);
            return;
          }
          window.reports.innerHTML = "";
          window.reports.classList.remove("hidden");

          if (!Array.isArray(reports)) {
            console.error("Unexpected memory report format!");
            return;
          }

          reports.forEach(reportsForProcess);
        };
      }
    </script>
    <style>
      html {
        font-family: sans-serif;
      }

      details,
      details div {
        margin-left: 1em;
      }

      summary:hover {
        cursor: pointer;
      }

      div.process {
        margin: 0.5em;
        border: 2px solid gray;
        border-radius: 10px;
        padding: 5px;
        background-color: lightgray;
      }

      .report {
        line-height: 1.5em;
      }

      .report > details {
        margin-bottom: 1em;
      }

      .hidden {
        display: none;
      }
    </style>
  </head>
  <body>
    <h2>Memory Reports</h2>
    <button id="startButton">Measure</button>
    <div id="reports" class="hidden"></div>
  </body>
</html>
