Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / devtools / front_end / timeline / TimelineJSProfile.js
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.
4
5
6 WebInspector.TimelineJSProfileProcessor = { };
7
8 /**
9  * @param {!WebInspector.TimelineModelImpl} timelineModel
10  * @param {!ProfilerAgent.CPUProfile} jsProfile
11  */
12 WebInspector.TimelineJSProfileProcessor.mergeJSProfileIntoTimeline = function(timelineModel, jsProfile)
13 {
14     if (!jsProfile.samples)
15         return;
16     var jsProfileModel = new WebInspector.CPUProfileDataModel(jsProfile);
17     var idleNode = jsProfileModel.idleNode;
18     var programNode = jsProfileModel.programNode;
19     var gcNode = jsProfileModel.gcNode;
20
21     /**
22      * @param {!WebInspector.TimelineModel.Record} record
23      */
24     function processRecord(record)
25     {
26         if (record.type() !== WebInspector.TimelineModel.RecordType.FunctionCall &&
27             record.type() !== WebInspector.TimelineModel.RecordType.EvaluateScript)
28             return;
29         var recordStartTime = record.startTime();
30         var recordEndTime = record.endTime();
31         var originalChildren = record.children().splice(0);
32         var childIndex = 0;
33
34         /**
35          * @param {number} depth
36          * @param {!ProfilerAgent.CPUProfileNode} node
37          * @param {number} startTime
38          */
39         function onOpenFrame(depth, node, startTime)
40         {
41             if (node === idleNode || node === programNode || node === gcNode)
42                 return;
43             var event = {
44                 type: "JSFrame",
45                 data: node,
46                 startTime: startTime
47             };
48             putOriginalChildrenUpToTime(startTime);
49             record = new WebInspector.TimelineModel.RecordImpl(timelineModel, event, record);
50         }
51
52         /**
53          * @param {number} depth
54          * @param {!ProfilerAgent.CPUProfileNode} node
55          * @param {number} startTime
56          * @param {number} totalTime
57          * @param {number} selfTime
58          */
59         function onCloseFrame(depth, node, startTime, totalTime, selfTime)
60         {
61             if (node === idleNode || node === programNode || node === gcNode)
62                 return;
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;
70         }
71
72         /**
73          * @param {number} endTime
74          */
75         function putOriginalChildrenUpToTime(endTime)
76         {
77             for (; childIndex < originalChildren.length; ++childIndex)  {
78                 var child = originalChildren[childIndex];
79                 var midTime = (child.startTime() + child.endTime()) / 2;
80                 if (midTime >= endTime)
81                     break;
82                 child.parent = record;
83                 record.children().push(child);
84             }
85         }
86
87         jsProfileModel.forEachFrame(onOpenFrame, onCloseFrame, recordStartTime, recordEndTime);
88         putOriginalChildrenUpToTime(recordEndTime);
89     }
90
91     timelineModel.forAllRecords(processRecord);
92 }
93
94 /**
95  * @param {!WebInspector.TracingTimelineModel} timelineModel
96  * @param {!ProfilerAgent.CPUProfile} jsProfile
97  * @return {!Array.<!WebInspector.TracingModel.Event>}
98  */
99 WebInspector.TimelineJSProfileProcessor.generateTracingEventsFromCpuProfile = function(timelineModel, jsProfile)
100 {
101     if (!jsProfile.samples)
102         return [];
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;
109     var jsEvents = [];
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)
114             continue;
115         var stackTrace = node._stackTraceArray;
116         if (!stackTrace) {
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);
121         }
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,
127             args: { }
128         });
129         var jsEvent = new WebInspector.TracingModel.Event(payload, 0, mainThread);
130         jsEvent.stackTrace = stackTrace;
131         jsEvents.push(jsEvent);
132     }
133     return jsEvents;
134 }