1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
6 WebInspector.TimelineJSProfileProcessor = { };
9 * @param {!WebInspector.TimelineModelImpl} timelineModel
10 * @param {!ProfilerAgent.CPUProfile} jsProfile
12 WebInspector.TimelineJSProfileProcessor.mergeJSProfileIntoTimeline = function(timelineModel, jsProfile)
14 if (!jsProfile.samples)
16 var jsProfileModel = new WebInspector.CPUProfileDataModel(jsProfile);
17 var idleNode = jsProfileModel.idleNode;
18 var programNode = jsProfileModel.programNode;
19 var gcNode = jsProfileModel.gcNode;
22 * @param {!WebInspector.TimelineModel.Record} record
24 function processRecord(record)
26 if (record.type() !== WebInspector.TimelineModel.RecordType.FunctionCall &&
27 record.type() !== WebInspector.TimelineModel.RecordType.EvaluateScript)
29 var recordStartTime = record.startTime();
30 var recordEndTime = record.endTime();
31 var originalChildren = record.children().splice(0);
35 * @param {number} depth
36 * @param {!ProfilerAgent.CPUProfileNode} node
37 * @param {number} startTime
39 function onOpenFrame(depth, node, startTime)
41 if (node === idleNode || node === programNode || node === gcNode)
48 putOriginalChildrenUpToTime(startTime);
49 record = new WebInspector.TimelineModel.RecordImpl(timelineModel, event, record);
53 * @param {number} depth
54 * @param {!ProfilerAgent.CPUProfileNode} node
55 * @param {number} startTime
56 * @param {number} totalTime
57 * @param {number} selfTime
59 function onCloseFrame(depth, node, startTime, totalTime, selfTime)
61 if (node === idleNode || node === programNode || node === gcNode)
63 record.setEndTime(Math.min(startTime + totalTime, recordEndTime));
64 record._selfTime = record.endTime() - record.startTime();
65 putOriginalChildrenUpToTime(record.endTime());
66 var deoptReason = node.deoptReason;
67 if (deoptReason && deoptReason !== "no reason")
68 record.addWarning(deoptReason);
69 record = record.parent;
73 * @param {number} endTime
75 function putOriginalChildrenUpToTime(endTime)
77 for (; childIndex < originalChildren.length; ++childIndex) {
78 var child = originalChildren[childIndex];
79 var midTime = (child.startTime() + child.endTime()) / 2;
80 if (midTime >= endTime)
82 child.parent = record;
83 record.children().push(child);
87 jsProfileModel.forEachFrame(onOpenFrame, onCloseFrame, recordStartTime, recordEndTime);
88 putOriginalChildrenUpToTime(recordEndTime);
91 timelineModel.forAllRecords(processRecord);
95 * @param {!WebInspector.TracingTimelineModel} timelineModel
96 * @param {!ProfilerAgent.CPUProfile} jsProfile
97 * @return {!Array.<!WebInspector.TracingModel.Event>}
99 WebInspector.TimelineJSProfileProcessor.generateTracingEventsFromCpuProfile = function(timelineModel, jsProfile)
101 if (!jsProfile.samples)
103 var jsProfileModel = new WebInspector.CPUProfileDataModel(jsProfile);
104 var idleNode = jsProfileModel.idleNode;
105 var programNode = jsProfileModel.programNode;
106 var gcNode = jsProfileModel.gcNode;
107 var samples = jsProfileModel.samples;
108 var timestamps = jsProfileModel.timestamps;
110 var mainThread = timelineModel.mainThreadEvents()[0].thread;
111 for (var i = 0; i < samples.length; ++i) {
112 var node = jsProfileModel.nodeByIndex(i);
113 if (node === programNode || node === gcNode || node === idleNode)
115 var stackTrace = node._stackTraceArray;
117 stackTrace = /** @type {!ConsoleAgent.StackTrace} */ (new Array(node.depth + 1));
118 node._stackTraceArray = stackTrace;
119 for (var j = 0; node.parent; node = node.parent)
120 stackTrace[j++] = /** @type {!ConsoleAgent.CallFrame} */ (node);
122 var payload = /** @type {!WebInspector.TracingModel.EventPayload} */ ({
123 ph: WebInspector.TracingModel.Phase.Instant,
124 cat: WebInspector.TracingModel.DevToolsMetadataEventCategory,
125 name: WebInspector.TracingTimelineModel.RecordType.JSSample,
126 ts: timestamps[i] * 1000,
129 var jsEvent = new WebInspector.TracingModel.Event(payload, 0, mainThread);
130 jsEvent.stackTrace = stackTrace;
131 jsEvents.push(jsEvent);