Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(257)

Side by Side Diff: runtime/observatory/lib/src/elements/code_view.dart

Issue 928833003: Add Function based profile tree (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 library code_view_element; 5 library code_view_element;
6 6
7 import 'dart:html'; 7 import 'dart:html';
8 import 'observatory_element.dart'; 8 import 'observatory_element.dart';
9 import 'package:observatory/app.dart';
9 import 'package:observatory/service.dart'; 10 import 'package:observatory/service.dart';
11 import 'package:observatory/cpu_profile.dart';
10 import 'package:polymer/polymer.dart'; 12 import 'package:polymer/polymer.dart';
11 13
14 class DisassemblyTable extends SortedTable {
15 DisassemblyTable(columns) : super(columns);
16 }
17
18 class InlineTable extends SortedTable {
19 InlineTable(columns) : super(columns);
20 }
21
12 @CustomTag('code-view') 22 @CustomTag('code-view')
13 class CodeViewElement extends ObservatoryElement { 23 class CodeViewElement extends ObservatoryElement {
14 @published Code code; 24 @observable Code code;
15 CodeViewElement.created() : super.created(); 25 ProfileCode get profile => code == null ? null : code.profile;
26 DisassemblyTable disassemblyTable;
27 InlineTable inlineTable;
28
29 CodeViewElement.created() : super.created() {
30 // Create table models.
31 var columns = [
32 new SortedTableColumn('Address'),
33 new SortedTableColumn('Inclusive'),
34 new SortedTableColumn('Exclusive'),
35 new SortedTableColumn('Disassembly'),
36 ];
37 disassemblyTable = new DisassemblyTable(columns);
38 columns = [
39 new SortedTableColumn('Address'),
40 new SortedTableColumn('Inclusive'),
41 new SortedTableColumn('Exclusive'),
42 new SortedTableColumn('Functions'),
43 ];
44 inlineTable = new InlineTable(columns);
45 }
16 46
17 @override 47 @override
18 void attached() { 48 void attached() {
19 super.attached(); 49 super.attached();
50 }
51
52 void codeChanged(oldValue) {
20 if (code == null) { 53 if (code == null) {
21 return; 54 return;
22 } 55 }
23 code.load().then((Code c) { 56 code.load().then((Code c) {
24 c.loadScript(); 57 c.loadScript();
25 }); 58 });
59 _updateDisassembly();
60 _updateInline();
26 } 61 }
27 62
28 void refresh(var done) { 63 void refresh(var done) {
29 code.reload().whenComplete(done); 64 code.reload().whenComplete(done);
30 } 65 }
31 66
67 void refreshTicks(var done) {
68 var isolate = code.isolate;
69 isolate.invokeRpc('getCpuProfile', { 'tags': 'None' })
70 .then((ServiceMap response) {
71 var cpuProfile = new CpuProfile();
72 cpuProfile.load(isolate, response);
73 _updateDisassembly();
74 _updateInline();
75 }).whenComplete(done);
76 }
77
78 String formattedAddress(CodeInstruction instruction) {
79 if (instruction.address == 0) {
80 return '';
81 }
82 return '0x${instruction.address.toRadixString(16)}';
83 }
84
85 String formattedAddressRange(CodeInlineInterval interval) {
86 String start = interval.start.toRadixString(16);
87 String end = interval.end.toRadixString(16);
88 return '[0x$start, 0x$end)';
89 }
90
91 String formattedInclusiveInterval(CodeInlineInterval interval) {
92 if (code == null) {
93 return '';
94 }
95 if (code.profile == null) {
96 return '';
97 }
98 var intervalTick = code.profile.intervalTicks[interval.start];
99 if (intervalTick == null) {
100 return '';
101 }
102 // Don't show inclusive ticks if they are the same as exclusive ticks.
103 if (intervalTick.inclusiveTicks == intervalTick.exclusiveTicks) {
104 return '';
105 }
106 var pcent = Utils.formatPercent(intervalTick.inclusiveTicks,
107 code.profile.profile.sampleCount);
108 return '$pcent (${intervalTick.inclusiveTicks})';
109 }
110
111 String formattedExclusiveInterval(CodeInlineInterval interval) {
112 if (code == null) {
113 return '';
114 }
115 if (code.profile == null) {
116 return '';
117 }
118 var intervalTick = code.profile.intervalTicks[interval.start];
119 if (intervalTick == null) {
120 return '';
121 }
122 var pcent = Utils.formatPercent(intervalTick.exclusiveTicks,
123 code.profile.profile.sampleCount);
124 return '$pcent (${intervalTick.exclusiveTicks})';
125 }
126
127
128 String formattedInclusive(CodeInstruction instruction) {
129 if (code == null) {
130 return '';
131 }
132 if (code.profile == null) {
133 return '';
134 }
135 var tick = code.profile.addressTicks[instruction.address];
136 if (tick == null) {
137 return '';
138 }
139 // Don't show inclusive ticks if they are the same as exclusive ticks.
140 if (tick.inclusiveTicks == tick.exclusiveTicks) {
141 return '';
142 }
143 var pcent = Utils.formatPercent(tick.inclusiveTicks,
144 code.profile.profile.sampleCount);
145 return '$pcent (${tick.inclusiveTicks})';
146 }
147
148 String formattedExclusive(CodeInstruction instruction) {
149 if (code == null) {
150 return '';
151 }
152 if (code.profile == null) {
153 return '';
154 }
155 var tick = code.profile.addressTicks[instruction.address];
156 if (tick == null) {
157 return '';
158 }
159 var pcent = Utils.formatPercent(tick.exclusiveTicks,
160 code.profile.profile.sampleCount);
161 return '$pcent (${tick.exclusiveTicks})';
162 }
163
164 void _updateDiasssemblyTable() {
165 disassemblyTable.clearRows();
166 if (code == null) {
167 return;
168 }
169 for (CodeInstruction instruction in code.instructions) {
170 var row = [formattedAddress(instruction),
171 formattedInclusive(instruction),
172 formattedExclusive(instruction),
173 instruction.human];
174 disassemblyTable.addRow(new SortedTableRow(row));
175 }
176 }
177
178 void _addDisassemblyDOMRow() {
179 var tableBody = $['disassemblyTableBody'];
180 assert(tableBody != null);
181 var tr = new TableRowElement();
182
183 var cell;
184
185 // Add new space.
186 cell = tr.insertCell(-1);
187 cell.classes.add('monospace');
188 cell = tr.insertCell(-1);
189 cell.classes.add('monospace');
190 cell = tr.insertCell(-1);
191 cell.classes.add('monospace');
192 cell = tr.insertCell(-1);
193 cell.classes.add('monospace');
194
195 tableBody.children.add(tr);
196 }
197
198 void _fillDisassemblyDOMRow(TableRowElement tr, int rowIndex) {
199 var row = disassemblyTable.rows[rowIndex];
200 for (var i = 0; i < row.values.length; i++) {
201 var cell = tr.children[i];
202 cell.title = row.values[i].toString();
203 cell.text = row.values[i].toString();
204 }
205 }
206
207 void _updateDisassemblyDOMTable() {
208 var tableBody = $['disassemblyTableBody'];
209 assert(tableBody != null);
210 // Resize DOM table.
211 if (tableBody.children.length > disassemblyTable.sortedRows.length) {
212 // Shrink the table.
213 var deadRows =
214 tableBody.children.length - disassemblyTable.sortedRows.length;
215 for (var i = 0; i < deadRows; i++) {
216 tableBody.children.removeLast();
217 }
218 } else if (tableBody.children.length < disassemblyTable.sortedRows.length) {
219 // Grow table.
220 var newRows =
221 disassemblyTable.sortedRows.length - tableBody.children.length;
222 for (var i = 0; i < newRows; i++) {
223 _addDisassemblyDOMRow();
224 }
225 }
226
227 assert(tableBody.children.length == disassemblyTable.sortedRows.length);
228 // Fill table.
229 for (var i = 0; i < disassemblyTable.sortedRows.length; i++) {
230 var rowIndex = disassemblyTable.sortedRows[i];
231 var tr = tableBody.children[i];
232 _fillDisassemblyDOMRow(tr, rowIndex);
233 }
234 }
235
236 void _updateDisassembly() {
237 notifyPropertyChange(#code, true, false);
238 _updateDiasssemblyTable();
239 _updateDisassemblyDOMTable();
240 }
241
242 void _updateInlineTable() {
243 inlineTable.clearRows();
244 if (code == null) {
245 return;
246 }
247 for (CodeInlineInterval interval in code.inlineIntervals) {
248 var row = [interval,
249 formattedInclusiveInterval(interval),
250 formattedExclusiveInterval(interval),
251 interval.functions];
252 inlineTable.addRow(new SortedTableRow(row));
253 }
254 }
255
256 void _addInlineDOMRow() {
257 var tableBody = shadowRoot.querySelector('#inlineRangeTableBody');
258 assert(tableBody != null);
259 var tr = new TableRowElement();
260
261 var cell;
262
263 // Add new space.
264 cell = tr.insertCell(-1);
265 cell.classes.add('monospace');
266 cell = tr.insertCell(-1);
267 cell.classes.add('monospace');
268 cell = tr.insertCell(-1);
269 cell.classes.add('monospace');
270 cell = tr.insertCell(-1);
271
272 tableBody.children.add(tr);
273 }
274
275 void _fillInlineDOMRow(TableRowElement tr, int rowIndex) {
276 var row = inlineTable.rows[rowIndex];
277 var columns = row.values.length;
278 var addressRangeColumn = 0;
279 var functionsColumn = columns - 1;
280
281 {
282 var addressRangeCell = tr.children[addressRangeColumn];
283 var interval = row.values[addressRangeColumn];
284 var addressRangeString = formattedAddressRange(interval);
285 var addressRangeElement = new SpanElement();
286 addressRangeElement.classes.add('monospace');
287 addressRangeElement.text = addressRangeString;
288 addressRangeCell.children.clear();
289 addressRangeCell.children.add(addressRangeElement);
290 }
291
292 for (var i = addressRangeColumn + 1; i < columns - 1; i++) {
293 var cell = tr.children[i];
294 cell.title = row.values[i].toString();
295 cell.text = row.values[i].toString();
296 }
297 var functions = row.values[functionsColumn];
298 var functionsCell = tr.children[functionsColumn];
299 functionsCell.children.clear();
300 for (var func in functions) {
301 var functionRef = new Element.tag('function-ref');
302 functionRef.ref = func;
303 functionsCell.children.add(functionRef);
304 var gap = new SpanElement();
305 gap.style.minWidth = '1em';
306 gap.text = ' ';
307 functionsCell.children.add(gap);
308 }
309 }
310
311 void _updateInlineDOMTable() {
312 var tableBody = shadowRoot.querySelector('#inlineRangeTableBody');
313 // Resize DOM table.
314 if (tableBody.children.length > inlineTable.sortedRows.length) {
315 // Shrink the table.
316 var deadRows =
317 tableBody.children.length - inlineTable.sortedRows.length;
318 for (var i = 0; i < deadRows; i++) {
319 tableBody.children.removeLast();
320 }
321 } else if (tableBody.children.length < inlineTable.sortedRows.length) {
322 // Grow table.
323 var newRows = inlineTable.sortedRows.length - tableBody.children.length;
324 for (var i = 0; i < newRows; i++) {
325 _addInlineDOMRow();
326 }
327 }
328 assert(tableBody.children.length == inlineTable.sortedRows.length);
329 // Fill table.
330 for (var i = 0; i < inlineTable.sortedRows.length; i++) {
331 var rowIndex = inlineTable.sortedRows[i];
332 var tr = tableBody.children[i];
333 _fillInlineDOMRow(tr, rowIndex);
334 }
335 }
336
337 void _updateInline() {
338 _updateInlineTable();
339 _updateInlineDOMTable();
340 }
341
32 Element _findJumpTarget(Element target) { 342 Element _findJumpTarget(Element target) {
33 var jumpTarget = target.attributes['data-jump-target']; 343 var jumpTarget = target.attributes['data-jump-target'];
34 if (jumpTarget == '') { 344 if (jumpTarget == '') {
35 return null; 345 return null;
36 } 346 }
37 var address = int.parse(jumpTarget); 347 var address = int.parse(jumpTarget);
38 var node = shadowRoot.querySelector('#addr-$address'); 348 var node = shadowRoot.querySelector('#addr-$address');
39 if (node == null) { 349 if (node == null) {
40 return null; 350 return null;
41 } 351 }
42 return node; 352 return node;
43 } 353 }
44 354
45 void mouseOver(Event e, var detail, Node target) { 355 void mouseOver(Event e, var detail, Node target) {
46 var jt = _findJumpTarget(target); 356 var jt = _findJumpTarget(target);
47 if (jt == null) { 357 if (jt == null) {
48 return; 358 return;
49 } 359 }
50 jt.classes.add('highlight'); 360 jt.classes.add('highlight');
51 } 361 }
52 362
53 void mouseOut(Event e, var detail, Node target) { 363 void mouseOut(Event e, var detail, Node target) {
54 var jt = _findJumpTarget(target); 364 var jt = _findJumpTarget(target);
55 if (jt == null) { 365 if (jt == null) {
56 return; 366 return;
57 } 367 }
58 jt.classes.remove('highlight'); 368 jt.classes.remove('highlight');
59 } 369 }
60 } 370 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698