Chromium Code Reviews| 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 |