| (async function(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.loadScriptModule( |
| '../../../../devtools-frontend/src/front_end/platform/utilities.js'); |
| await testRunner.loadScriptModule( |
| '../../../../devtools-frontend/src/front_end/common/UIString.js'); |
| await testRunner.loadScriptModule( |
| '../../../../devtools-frontend/src/front_end/heap_snapshot_model/HeapSnapshotModel.js'); |
| await testRunner.loadScriptModule( |
| '../../../../devtools-frontend/src/front_end/heap_snapshot_worker/HeapSnapshot.js'); |
| await testRunner.loadScriptModule( |
| '../../../../devtools-frontend/src/front_end/text_utils/TextUtils.js'); |
| await testRunner.loadScriptModule( |
| '../../../../devtools-frontend/src/front_end/heap_snapshot_worker/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()); |
| } |
| }; |
| }) |