chromium/third_party/blink/web_tests/inspector-protocol/heap-profiler/resources/heap-snapshot-common.js

(async function(/** @type {import('test_runner').TestRunner} */ testRunner, session) {
  self['Common'] = {};
  self['TextUtils'] = {};
  self['HeapSnapshotModel'] = {};
  self['HeapSnapshotWorker'] = {};

  // This script is supposed to be evaluated in inspector-protocol/heap-profiler tests
  // and the relative paths below are relative to that location.
  await testRunner.loadScript('./resources/HeapSnapshotLoader.js');

  // Expose the (de)serialize code from Common because the worker expects it on self.
  // TODO(https://crbug.com/680046) Remove the dupe code below.
  self.serializeUIString = Common.serializeUIString;
  self.deserializeUIString = Common.deserializeUIString;

  async function takeHeapSnapshotInternal(command) {
    var loader = new HeapSnapshotWorker.HeapSnapshotLoader();
    function onChunk(messageObject) {
      loader.write(messageObject['params']['chunk']);
    }
    session.protocol.HeapProfiler.onAddHeapSnapshotChunk(onChunk);
    await command();
    session.protocol.HeapProfiler.offAddHeapSnapshotChunk(onChunk);
    testRunner.log('Took heap snapshot');
    loader.close();
    await new Promise(r => setTimeout(r));
    var snapshot = loader.buildSnapshot(false);
    testRunner.log('Parsed snapshot');
    return snapshot;
  }

  function firstRetainingPath(node) {
    for (var iter = node.retainers(); iter.hasNext(); iter.next()) {
      var retainingEdge = iter.retainer;
      var retainer = retainingEdge.node();
      if (retainingEdge.isWeak() ||
          retainer.distance() >= node.distance()) continue;
      var path = firstRetainingPath(retainer);
      path.unshift(retainer);
      return path;
    }
    return [];
  }

  return {
    firstRetainingPath: firstRetainingPath,

    takeHeapSnapshot: function() {
      return takeHeapSnapshotInternal(() => session.protocol.HeapProfiler.takeHeapSnapshot());
    },

    stopRecordingHeapTimeline: function() {
      return takeHeapSnapshotInternal(() => session.protocol.HeapProfiler.stopTrackingHeapObjects());
    }
  };
})