| 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 cpu_profile_element; | 5 library cpu_profile_element; |
| 6 | 6 |
| 7 import 'dart:html'; | 7 import 'dart:html'; |
| 8 import 'observatory_element.dart'; | 8 import 'observatory_element.dart'; |
| 9 import 'package:logging/logging.dart'; | 9 import 'package:logging/logging.dart'; |
| 10 import 'package:observatory/service.dart'; | 10 import 'package:observatory/service.dart'; |
| (...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 133 | 133 |
| 134 bool hasChildren() { | 134 bool hasChildren() { |
| 135 return node.children.length > 0; | 135 return node.children.length > 0; |
| 136 } | 136 } |
| 137 } | 137 } |
| 138 | 138 |
| 139 /// Displays a CpuProfile | 139 /// Displays a CpuProfile |
| 140 @CustomTag('cpu-profile') | 140 @CustomTag('cpu-profile') |
| 141 class CpuProfileElement extends ObservatoryElement { | 141 class CpuProfileElement extends ObservatoryElement { |
| 142 CpuProfileElement.created() : super.created(); | 142 CpuProfileElement.created() : super.created(); |
| 143 @published ServiceMap profile; | 143 @published Isolate isolate; |
| 144 |
| 145 @observable ServiceMap profile; |
| 144 @observable bool hideTagsChecked; | 146 @observable bool hideTagsChecked; |
| 145 @observable String sampleCount = ''; | 147 @observable String sampleCount = ''; |
| 146 @observable String refreshTime = ''; | 148 @observable String refreshTime = ''; |
| 147 @observable String sampleRate = ''; | 149 @observable String sampleRate = ''; |
| 148 @observable String sampleDepth = ''; | 150 @observable String sampleDepth = ''; |
| 149 @observable String displayCutoff = ''; | 151 @observable String displayCutoff = ''; |
| 150 @observable String timeSpan = ''; | 152 @observable String timeSpan = ''; |
| 151 @reflectable double displayThreshold = 0.0002; // 0.02%. | 153 @reflectable double displayThreshold = 0.0002; // 0.02%. |
| 152 | 154 |
| 153 @observable String tagSelector = 'uv'; | 155 @observable String tagSelector = 'UserVM'; |
| 154 | 156 |
| 155 final _id = '#tableTree'; | 157 final _id = '#tableTree'; |
| 156 TableTree tree; | 158 TableTree tree; |
| 157 | 159 |
| 158 static const MICROSECONDS_PER_SECOND = 1000000.0; | 160 static const MICROSECONDS_PER_SECOND = 1000000.0; |
| 159 | 161 |
| 160 void profileChanged(oldValue) { | 162 void isolateChanged(oldValue) { |
| 161 if (profile == null) { | 163 if (isolate == null) { |
| 164 profile = null; |
| 162 return; | 165 return; |
| 163 } | 166 } |
| 164 var totalSamples = profile['samples']; | 167 isolate.invokeRpc('getCpuProfile', { 'tags': tagSelector }) |
| 165 var now = new DateTime.now(); | 168 .then((ServiceObject obj) { |
| 166 sampleCount = totalSamples.toString(); | 169 print(obj); |
| 167 refreshTime = now.toString(); | 170 // Assert we got back the a profile. |
| 168 sampleDepth = profile['depth'].toString(); | 171 assert(obj.type == 'CpuProfile'); |
| 169 var period = profile['period']; | 172 profile = obj; |
| 170 sampleRate = (MICROSECONDS_PER_SECOND / period).toStringAsFixed(0); | 173 _update(); |
| 171 timeSpan = formatTime(profile['timeSpan']); | 174 }); |
| 172 displayCutoff = '${(displayThreshold * 100.0).toString()}%'; | |
| 173 profile.isolate.processProfile(profile); | |
| 174 profile['threshold'] = displayThreshold; | |
| 175 _update(); | |
| 176 } | 175 } |
| 177 | 176 |
| 178 | |
| 179 @override | 177 @override |
| 180 void attached() { | 178 void attached() { |
| 181 super.attached(); | 179 super.attached(); |
| 182 var tableBody = shadowRoot.querySelector('#tableTreeBody'); | 180 var tableBody = shadowRoot.querySelector('#tableTreeBody'); |
| 183 assert(tableBody != null); | 181 assert(tableBody != null); |
| 184 tree = new TableTree(tableBody, 2); | 182 tree = new TableTree(tableBody, 2); |
| 185 _update(); | 183 _update(); |
| 186 } | 184 } |
| 187 | 185 |
| 188 void tagSelectorChanged(oldValue) { | 186 void tagSelectorChanged(oldValue) { |
| 189 refresh(null); | 187 isolateChanged(null); |
| 190 } | 188 } |
| 191 | 189 |
| 192 void refresh(var done) { | 190 void refresh(var done) { |
| 193 var request = 'profile?tags=$tagSelector'; | 191 isolate.invokeRpc('getCpuProfile', { 'tags': tagSelector }) |
| 194 profile.isolate.get(request).then((ServiceMap m) { | 192 .then((ServiceObject obj) { |
| 195 // Assert we got back the a profile. | 193 // Assert we got back the a profile. |
| 196 assert(m.type == 'Profile'); | 194 assert(obj.type == 'CpuProfile'); |
| 197 profile = m; | 195 profile = obj; |
| 198 }).whenComplete(done); | 196 _update(); |
| 197 }).whenComplete(done); |
| 199 } | 198 } |
| 200 | 199 |
| 201 void _update() { | 200 void _update() { |
| 202 if (profile == null) { | 201 if (profile == null) { |
| 203 return; | 202 return; |
| 204 } | 203 } |
| 204 var totalSamples = profile['samples']; |
| 205 var now = new DateTime.now(); |
| 206 sampleCount = totalSamples.toString(); |
| 207 refreshTime = now.toString(); |
| 208 sampleDepth = profile['depth'].toString(); |
| 209 var period = profile['period']; |
| 210 sampleRate = (MICROSECONDS_PER_SECOND / period).toStringAsFixed(0); |
| 211 timeSpan = formatTime(profile['timeSpan']); |
| 212 displayCutoff = '${(displayThreshold * 100.0).toString()}%'; |
| 213 profile.isolate.processProfile(profile); |
| 214 profile['threshold'] = displayThreshold; |
| 205 _buildTree(); | 215 _buildTree(); |
| 206 } | 216 } |
| 207 | 217 |
| 208 void _buildStackTree() { | 218 void _buildStackTree() { |
| 209 var root = profile.isolate.profileTrieRoot; | 219 var root = profile.isolate.profileTrieRoot; |
| 210 if (root == null) { | 220 if (root == null) { |
| 211 return; | 221 return; |
| 212 } | 222 } |
| 213 try { | 223 try { |
| 214 tree.initialize( | 224 tree.initialize( |
| 215 new ProfileCodeTrieNodeTreeRow(profile, root, root, tree, null)); | 225 new ProfileCodeTrieNodeTreeRow(profile, root, root, tree, null)); |
| 216 } catch (e, stackTrace) { | 226 } catch (e, stackTrace) { |
| 217 print(e); | 227 print(e); |
| 218 print(stackTrace); | 228 print(stackTrace); |
| 219 Logger.root.warning('_buildStackTree', e, stackTrace); | 229 Logger.root.warning('_buildStackTree', e, stackTrace); |
| 220 } | 230 } |
| 221 // Check if we only have one node at the root and expand it. | 231 // Check if we only have one node at the root and expand it. |
| 222 if (tree.rows.length == 1) { | 232 if (tree.rows.length == 1) { |
| 223 tree.toggle(tree.rows[0]); | 233 tree.toggle(tree.rows[0]); |
| 224 } | 234 } |
| 225 notifyPropertyChange(#tree, null, tree); | 235 notifyPropertyChange(#tree, null, tree); |
| 226 } | 236 } |
| 227 | 237 |
| 228 void _buildTree() { | 238 void _buildTree() { |
| 229 _buildStackTree(); | 239 _buildStackTree(); |
| 230 } | 240 } |
| 231 } | 241 } |
| OLD | NEW |