OLD | NEW |
---|---|
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 | |
12 @CustomTag('code-view') | 18 @CustomTag('code-view') |
13 class CodeViewElement extends ObservatoryElement { | 19 class CodeViewElement extends ObservatoryElement { |
14 @published Code code; | 20 @published Code code; |
15 CodeViewElement.created() : super.created(); | 21 @observable DisassemblyTable disassemblyTable; |
22 | |
23 CodeViewElement.created() : super.created() { | |
24 // Create table model. | |
25 var columns = [ | |
26 new SortedTableColumn('Inclusive'), | |
27 new SortedTableColumn('Exclusive'), | |
28 new SortedTableColumn('Address'), | |
29 new SortedTableColumn('Disassembly'), | |
30 ]; | |
31 disassemblyTable = new DisassemblyTable(columns); | |
32 } | |
16 | 33 |
17 @override | 34 @override |
18 void attached() { | 35 void attached() { |
19 super.attached(); | 36 super.attached(); |
20 if (code == null) { | 37 if (code == null) { |
21 return; | 38 return; |
22 } | 39 } |
23 code.load().then((Code c) { | 40 code.load().then((Code c) { |
24 c.loadScript(); | 41 c.loadScript(); |
25 }); | 42 }); |
43 _updateDisassembly(); | |
26 } | 44 } |
27 | 45 |
28 void refresh(var done) { | 46 void refresh(var done) { |
29 code.reload().whenComplete(done); | 47 code.reload().whenComplete(done); |
30 } | 48 } |
31 | 49 |
50 void refreshTicks(var done) { | |
51 var isolate = code.isolate; | |
52 isolate.invokeRpc('getCpuProfile', { 'tags': 'None' }) | |
53 .then((ServiceMap response) { | |
54 new CpuProfile()..load(isolate, response); | |
rmacnak
2015/02/19 23:49:53
No need to cascade.
Cutch
2015/02/20 01:49:56
Done.
| |
55 _updateDisassembly(); | |
56 }).whenComplete(done); | |
57 } | |
58 | |
59 String formattedAddress(CodeInstruction instruction) { | |
60 if (instruction.address == 0) { | |
61 return ''; | |
62 } | |
63 return '0x${instruction.address.toRadixString(16)}'; | |
64 } | |
65 | |
66 String formattedInclusive(CodeInstruction instruction) { | |
67 if (code == null) { | |
68 return ''; | |
69 } | |
70 if (code.profile == null) { | |
71 return ''; | |
72 } | |
73 var tick = code.profile.addressTicks[instruction.address]; | |
74 if (tick == null) { | |
75 return ''; | |
76 } | |
77 // Don't show inclusive ticks if they are the same as exclusive ticks. | |
78 if (tick.inclusiveTicks == tick.exclusiveTicks) { | |
79 return ''; | |
80 } | |
81 var pcent = Utils.formatPercent(tick.inclusiveTicks, | |
82 code.profile.profile.sampleCount); | |
83 return '$pcent (${tick.inclusiveTicks})'; | |
84 } | |
85 | |
86 String formattedExclusive(CodeInstruction instruction) { | |
87 if (code == null) { | |
88 return ''; | |
89 } | |
90 if (code.profile == null) { | |
91 return ''; | |
92 } | |
93 var tick = code.profile.addressTicks[instruction.address]; | |
94 if (tick == null) { | |
95 return ''; | |
96 } | |
97 var pcent = Utils.formatPercent(tick.exclusiveTicks, | |
98 code.profile.profile.sampleCount); | |
99 return '$pcent (${tick.exclusiveTicks})'; | |
100 } | |
101 | |
102 void _updateTable() { | |
103 disassemblyTable.clearRows(); | |
104 if (code == null) { | |
105 return; | |
106 } | |
107 for (CodeInstruction instruction in code.instructions) { | |
108 var row = [formattedInclusive(instruction), | |
109 formattedExclusive(instruction), | |
110 formattedAddress(instruction), | |
111 instruction.human]; | |
112 disassemblyTable.addRow(new SortedTableRow(row)); | |
113 } | |
114 } | |
115 | |
116 void _addDOMRow() { | |
117 var tableBody = $['disassemblyTableBody']; | |
118 assert(tableBody != null); | |
119 var tr = new TableRowElement(); | |
120 | |
121 var cell; | |
122 | |
123 // Add new space. | |
124 cell = tr.insertCell(-1); | |
125 cell.classes.add('monospace'); | |
126 cell = tr.insertCell(-1); | |
127 cell.classes.add('monospace'); | |
128 cell = tr.insertCell(-1); | |
129 cell.classes.add('monospace'); | |
130 cell = tr.insertCell(-1); | |
131 cell.classes.add('monospace'); | |
132 | |
133 tableBody.children.add(tr); | |
134 } | |
135 | |
136 void _fillDOMRow(TableRowElement tr, int rowIndex) { | |
137 var row = disassemblyTable.rows[rowIndex]; | |
138 for (var i = 0; i < row.values.length; i++) { | |
139 var cell = tr.children[i]; | |
140 cell.title = row.values[i].toString(); | |
rmacnak
2015/02/19 23:49:53
Why set the tooltip if it is the same?
Cutch
2015/02/20 01:49:56
Acknowledged.
| |
141 cell.text = row.values[i].toString(); | |
142 } | |
143 } | |
144 | |
145 void _updateDOMTable() { | |
146 var tableBody = $['disassemblyTableBody']; | |
147 assert(tableBody != null); | |
148 // Resize DOM table. | |
149 if (tableBody.children.length > disassemblyTable.sortedRows.length) { | |
150 // Shrink the table. | |
151 var deadRows = | |
152 tableBody.children.length - disassemblyTable.sortedRows.length; | |
153 for (var i = 0; i < deadRows; i++) { | |
154 tableBody.children.removeLast(); | |
155 } | |
156 } else if (tableBody.children.length < disassemblyTable.sortedRows.length) { | |
157 // Grow table. | |
158 var newRows = | |
159 disassemblyTable.sortedRows.length - tableBody.children.length; | |
160 for (var i = 0; i < newRows; i++) { | |
161 _addDOMRow(); | |
162 } | |
163 } | |
164 | |
165 assert(tableBody.children.length == disassemblyTable.sortedRows.length); | |
166 // Fill table. | |
167 for (var i = 0; i < disassemblyTable.sortedRows.length; i++) { | |
168 var rowIndex = disassemblyTable.sortedRows[i]; | |
169 var tr = tableBody.children[i]; | |
170 _fillDOMRow(tr, rowIndex); | |
171 } | |
172 } | |
173 | |
174 void _updateDisassembly() { | |
175 notifyPropertyChange(#code, true, false); | |
176 _updateTable(); | |
177 _updateDOMTable(); | |
178 } | |
179 | |
32 Element _findJumpTarget(Element target) { | 180 Element _findJumpTarget(Element target) { |
33 var jumpTarget = target.attributes['data-jump-target']; | 181 var jumpTarget = target.attributes['data-jump-target']; |
34 if (jumpTarget == '') { | 182 if (jumpTarget == '') { |
35 return null; | 183 return null; |
36 } | 184 } |
37 var address = int.parse(jumpTarget); | 185 var address = int.parse(jumpTarget); |
38 var node = shadowRoot.querySelector('#addr-$address'); | 186 var node = shadowRoot.querySelector('#addr-$address'); |
39 if (node == null) { | 187 if (node == null) { |
40 return null; | 188 return null; |
41 } | 189 } |
42 return node; | 190 return node; |
43 } | 191 } |
44 | 192 |
45 void mouseOver(Event e, var detail, Node target) { | 193 void mouseOver(Event e, var detail, Node target) { |
46 var jt = _findJumpTarget(target); | 194 var jt = _findJumpTarget(target); |
47 if (jt == null) { | 195 if (jt == null) { |
48 return; | 196 return; |
49 } | 197 } |
50 jt.classes.add('highlight'); | 198 jt.classes.add('highlight'); |
51 } | 199 } |
52 | 200 |
53 void mouseOut(Event e, var detail, Node target) { | 201 void mouseOut(Event e, var detail, Node target) { |
54 var jt = _findJumpTarget(target); | 202 var jt = _findJumpTarget(target); |
55 if (jt == null) { | 203 if (jt == null) { |
56 return; | 204 return; |
57 } | 205 } |
58 jt.classes.remove('highlight'); | 206 jt.classes.remove('highlight'); |
59 } | 207 } |
60 } | 208 } |
OLD | NEW |