OLD | NEW |
1 <!DOCTYPE html> | 1 <!DOCTYPE html> |
2 <!-- | 2 <!-- |
3 Copyright 2016 The Chromium Authors. All rights reserved. | 3 Copyright 2016 The Chromium Authors. All rights reserved. |
4 Use of this source code is governed by a BSD-style license that can be | 4 Use of this source code is governed by a BSD-style license that can be |
5 found in the LICENSE file. | 5 found in the LICENSE file. |
6 --> | 6 --> |
7 | 7 |
8 <link rel="import" href="/tracing/base/unit.html"> | 8 <link rel="import" href="/tracing/base/unit.html"> |
9 <link rel="import" href="/tracing/extras/chrome/blame_context/frame_tree_node.ht
ml"> | 9 <link rel="import" href="/tracing/extras/chrome/blame_context/frame_tree_node.ht
ml"> |
10 <link rel="import" href="/tracing/extras/chrome/blame_context/render_frame.html"
> | 10 <link rel="import" href="/tracing/extras/chrome/blame_context/render_frame.html"
> |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
63 */ | 63 */ |
64 function Row(context) { | 64 function Row(context) { |
65 this.subRows = undefined; | 65 this.subRows = undefined; |
66 this.contexts = []; | 66 this.contexts = []; |
67 this.type = undefined; | 67 this.type = undefined; |
68 this.renderer = 'N/A'; | 68 this.renderer = 'N/A'; |
69 this.url = undefined; | 69 this.url = undefined; |
70 this.time = 0; | 70 this.time = 0; |
71 this.eventsOfInterest = new tr.model.EventSet(); | 71 this.eventsOfInterest = new tr.model.EventSet(); |
72 | 72 |
73 if (context === undefined) | 73 if (context === undefined) return; |
74 return; | |
75 | 74 |
76 this.type = context.objectInstance.blameContextType; | 75 this.type = context.objectInstance.blameContextType; |
77 this.contexts.push(context); | 76 this.contexts.push(context); |
78 if (context instanceof FrameTreeNodeSnapshot) { | 77 if (context instanceof FrameTreeNodeSnapshot) { |
79 if (context.renderFrame) { | 78 if (context.renderFrame) { |
80 this.contexts.push(context.renderFrame); | 79 this.contexts.push(context.renderFrame); |
81 this.renderer = context.renderFrame.objectInstance.parent.pid; | 80 this.renderer = context.renderFrame.objectInstance.parent.pid; |
82 } | 81 } |
83 } else if (context instanceof RenderFrameSnapshot) { | 82 } else if (context instanceof RenderFrameSnapshot) { |
84 if (context.frameTreeNode) | 83 if (context.frameTreeNode) { |
85 this.contexts.push(context.frameTreeNode); | 84 this.contexts.push(context.frameTreeNode); |
| 85 } |
86 this.renderer = context.objectInstance.parent.pid; | 86 this.renderer = context.objectInstance.parent.pid; |
87 } else if (context instanceof TopLevelSnapshot) { | 87 } else if (context instanceof TopLevelSnapshot) { |
88 this.renderer = context.objectInstance.parent.pid; | 88 this.renderer = context.objectInstance.parent.pid; |
89 } else { | 89 } else { |
90 throw new Error('Unknown context type'); | 90 throw new Error('Unknown context type'); |
91 } | 91 } |
92 this.eventsOfInterest.addEventSet(this.contexts); | 92 this.eventsOfInterest.addEventSet(this.contexts); |
93 | 93 |
94 // TODO(xiaochengh): Handle the case where a subframe has a trivial url | 94 // TODO(xiaochengh): Handle the case where a subframe has a trivial url |
95 // (e.g., about:blank), but inherits the origin of its parent. This is not | 95 // (e.g., about:blank), but inherits the origin of its parent. This is not |
(...skipping 14 matching lines...) Expand all Loading... |
110 // +- Subframe | 1 | b | 110 // +- Subframe | 1 | b |
111 // +- Frame Tree | 2 | c | 111 // +- Frame Tree | 2 | c |
112 // +- Frame | 1 | c | 112 // +- Frame | 1 | c |
113 // +- Subframe | 1 | d | 113 // +- Subframe | 1 | d |
114 tree: function(rows, rowMap) { | 114 tree: function(rows, rowMap) { |
115 // Finds the parent of a specific row. When there is conflict between the | 115 // Finds the parent of a specific row. When there is conflict between the |
116 // browser's dump of the frame tree and the renderers', use the browser's. | 116 // browser's dump of the frame tree and the renderers', use the browser's. |
117 var getParentRow = function(row) { | 117 var getParentRow = function(row) { |
118 var pivot; | 118 var pivot; |
119 row.contexts.forEach(function(context) { | 119 row.contexts.forEach(function(context) { |
120 if (context instanceof tr.e.chrome.FrameTreeNodeSnapshot) | 120 if (context instanceof tr.e.chrome.FrameTreeNodeSnapshot) { |
121 pivot = context; | 121 pivot = context; |
| 122 } |
122 }); | 123 }); |
123 if (pivot && pivot.parentContext) | 124 if (pivot && pivot.parentContext) { |
124 return rowMap[pivot.parentContext.guid]; | 125 return rowMap[pivot.parentContext.guid]; |
| 126 } |
125 return undefined; | 127 return undefined; |
126 }; | 128 }; |
127 | 129 |
128 var rootRows = []; | 130 var rootRows = []; |
129 rows.forEach(function(row) { | 131 rows.forEach(function(row) { |
130 var parentRow = getParentRow(row); | 132 var parentRow = getParentRow(row); |
131 if (parentRow === undefined) { | 133 if (parentRow === undefined) { |
132 rootRows.push(row); | 134 rootRows.push(row); |
133 return; | 135 return; |
134 } | 136 } |
135 if (parentRow.subRows === undefined) | 137 if (parentRow.subRows === undefined) { |
136 parentRow.subRows = []; | 138 parentRow.subRows = []; |
| 139 } |
137 parentRow.subRows.push(row); | 140 parentRow.subRows.push(row); |
138 }); | 141 }); |
139 | 142 |
140 var aggregateAllDescendants = function(row) { | 143 var aggregateAllDescendants = function(row) { |
141 if (!row.subRows) { | 144 if (!row.subRows) { |
142 if (getParentRow(row)) | 145 if (getParentRow(row)) { |
143 row.type = 'Subframe'; | 146 row.type = 'Subframe'; |
| 147 } |
144 return row; | 148 return row; |
145 } | 149 } |
146 var result = new Row(); | 150 var result = new Row(); |
147 result.type = 'Frame Tree'; | 151 result.type = 'Frame Tree'; |
148 result.renderer = row.renderer; | 152 result.renderer = row.renderer; |
149 result.url = row.url; | 153 result.url = row.url; |
150 result.subRows = [row]; | 154 result.subRows = [row]; |
151 row.subRows.forEach( | 155 row.subRows.forEach( |
152 subRow => result.subRows.push(aggregateAllDescendants(subRow))); | 156 subRow => result.subRows.push(aggregateAllDescendants(subRow))); |
153 result.subRows.forEach(function(subRow) { | 157 result.subRows.forEach(function(subRow) { |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
217 }, | 221 }, |
218 { | 222 { |
219 title: 'URL', | 223 title: 'URL', |
220 value: row => row.url, | 224 value: row => row.url, |
221 cmp: (a, b) => (a.url || '').localeCompare(b.url || '') | 225 cmp: (a, b) => (a.url || '').localeCompare(b.url || '') |
222 } | 226 } |
223 ]; | 227 ]; |
224 }, | 228 }, |
225 | 229 |
226 createFrameDataTableRows_: function() { | 230 createFrameDataTableRows_: function() { |
227 if (!this.model_) | 231 if (!this.model_) return []; |
228 return []; | |
229 | 232 |
230 // Gather contexts into skeletons of rows. | 233 // Gather contexts into skeletons of rows. |
231 var rows = []; | 234 var rows = []; |
232 var rowMap = {}; | 235 var rowMap = {}; |
233 for (var proc of Object.values(this.model_.processes)) { | 236 for (var proc of Object.values(this.model_.processes)) { |
234 proc.objects.iterObjectInstances(function(objectInstance) { | 237 proc.objects.iterObjectInstances(function(objectInstance) { |
235 if (!(objectInstance instanceof BlameContextInstance)) | 238 if (!(objectInstance instanceof BlameContextInstance)) { |
236 return; | 239 return; |
| 240 } |
237 objectInstance.snapshots.forEach(function(snapshot) { | 241 objectInstance.snapshots.forEach(function(snapshot) { |
238 if (rowMap[snapshot.guid]) | 242 if (rowMap[snapshot.guid]) return; |
239 return; | 243 |
240 var row = new Row(snapshot); | 244 var row = new Row(snapshot); |
241 row.contexts.forEach(context => rowMap[context.guid] = row); | 245 row.contexts.forEach(context => rowMap[context.guid] = row); |
242 rows.push(row); | 246 rows.push(row); |
243 }, this); | 247 }, this); |
244 }, this); | 248 }, this); |
245 } | 249 } |
246 | 250 |
247 // Find slices attributed to each row. | 251 // Find slices attributed to each row. |
248 // TODO(xiaochengh): We should implement a getter | 252 // TODO(xiaochengh): We should implement a getter |
249 // BlameContextSnapshot.attributedEvents, instead of process the model in | 253 // BlameContextSnapshot.attributedEvents, instead of process the model in |
250 // a UI component. | 254 // a UI component. |
251 for (var proc of Object.values(this.model_.processes)) { | 255 for (var proc of Object.values(this.model_.processes)) { |
252 for (var thread of Object.values(proc.threads)) { | 256 for (var thread of Object.values(proc.threads)) { |
253 thread.sliceGroup.iterSlicesInTimeRange(function(topLevelSlice) { | 257 thread.sliceGroup.iterSlicesInTimeRange(function(topLevelSlice) { |
254 topLevelSlice.contexts.forEach(function(context) { | 258 topLevelSlice.contexts.forEach(function(context) { |
255 if (!context.snapshot.guid || !rowMap[context.snapshot.guid]) | 259 if (!context.snapshot.guid || !rowMap[context.snapshot.guid]) { |
256 return; | 260 return; |
| 261 } |
257 var row = rowMap[context.snapshot.guid]; | 262 var row = rowMap[context.snapshot.guid]; |
258 row.eventsOfInterest.push(topLevelSlice); | 263 row.eventsOfInterest.push(topLevelSlice); |
259 row.time += topLevelSlice.selfTime || 0; | 264 row.time += topLevelSlice.selfTime || 0; |
260 }); | 265 }); |
261 }, this.currentRangeOfInterest.min, this.currentRangeOfInterest.max); | 266 }, this.currentRangeOfInterest.min, this.currentRangeOfInterest.max); |
262 } | 267 } |
263 } | 268 } |
264 | 269 |
265 // Apply grouping to rows. | 270 // Apply grouping to rows. |
266 var select = this.$.select; | 271 var select = this.$.select; |
(...skipping 11 matching lines...) Expand all Loading... |
278 if (!m) { | 283 if (!m) { |
279 return { | 284 return { |
280 supported: false, | 285 supported: false, |
281 reason: 'No model available.' | 286 reason: 'No model available.' |
282 }; | 287 }; |
283 } | 288 } |
284 | 289 |
285 var ans = {supported: false}; | 290 var ans = {supported: false}; |
286 for (var proc of Object.values(m.processes)) { | 291 for (var proc of Object.values(m.processes)) { |
287 proc.objects.iterObjectInstances(function(instance) { | 292 proc.objects.iterObjectInstances(function(instance) { |
288 if (instance instanceof BlameContextInstance) | 293 if (instance instanceof BlameContextInstance) { |
289 ans.supported = true; | 294 ans.supported = true; |
| 295 } |
290 }); | 296 }); |
291 } | 297 } |
292 | 298 |
293 if (!ans.supported) | 299 if (!ans.supported) { |
294 ans.reason = 'No frame data available'; | 300 ans.reason = 'No frame data available'; |
| 301 } |
295 return ans; | 302 return ans; |
296 }, | 303 }, |
297 | 304 |
298 get currentRangeOfInterest() { | 305 get currentRangeOfInterest() { |
299 if (this.rangeOfInterest_.isEmpty) | 306 if (this.rangeOfInterest_.isEmpty) { |
300 return this.model_.bounds; | 307 return this.model_.bounds; |
| 308 } |
301 return this.rangeOfInterest_; | 309 return this.rangeOfInterest_; |
302 }, | 310 }, |
303 | 311 |
304 get rangeOfInterest() { | 312 get rangeOfInterest() { |
305 return this.rangeOfInterest_; | 313 return this.rangeOfInterest_; |
306 }, | 314 }, |
307 | 315 |
308 set rangeOfInterest(rangeOfInterest) { | 316 set rangeOfInterest(rangeOfInterest) { |
309 this.rangeOfInterest_ = rangeOfInterest; | 317 this.rangeOfInterest_ = rangeOfInterest; |
310 this.updateContents_(); | 318 this.updateContents_(); |
(...skipping 19 matching lines...) Expand all Loading... |
330 this.model_ = model; | 338 this.model_ = model; |
331 this.updateContents_(); | 339 this.updateContents_(); |
332 } | 340 } |
333 }); | 341 }); |
334 | 342 |
335 tr.ui.side_panel.SidePanelRegistry.register(function() { | 343 tr.ui.side_panel.SidePanelRegistry.register(function() { |
336 return document.createElement('tr-ui-e-s-frame-data-side-panel'); | 344 return document.createElement('tr-ui-e-s-frame-data-side-panel'); |
337 }); | 345 }); |
338 }); | 346 }); |
339 </script> | 347 </script> |
OLD | NEW |