| OLD | NEW |
| 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, 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 heap_profile_element; | 5 library heap_profile_element; |
| 6 | 6 |
| 7 import 'dart:async'; |
| 7 import 'dart:html'; | 8 import 'dart:html'; |
| 8 import 'observatory_element.dart'; | 9 import 'observatory_element.dart'; |
| 9 import 'package:observatory/app.dart'; | 10 import 'package:observatory/app.dart'; |
| 10 import 'package:observatory/service.dart'; | 11 import 'package:observatory/service.dart'; |
| 11 import 'package:observatory/elements.dart'; | 12 import 'package:observatory/elements.dart'; |
| 12 import 'package:polymer/polymer.dart'; | 13 import 'package:polymer/polymer.dart'; |
| 13 | 14 |
| 14 class ClassSortedTable extends SortedTable { | 15 class ClassSortedTable extends SortedTable { |
| 15 | 16 |
| 16 ClassSortedTable(columns) : super(columns); | 17 ClassSortedTable(columns) : super(columns); |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 92 shadowRoot.querySelector('#newPieChart')); | 93 shadowRoot.querySelector('#newPieChart')); |
| 93 _oldPieChart = new Chart('PieChart', | 94 _oldPieChart = new Chart('PieChart', |
| 94 shadowRoot.querySelector('#oldPieChart')); | 95 shadowRoot.querySelector('#oldPieChart')); |
| 95 _classTableBody = shadowRoot.querySelector('#classTableBody'); | 96 _classTableBody = shadowRoot.querySelector('#classTableBody'); |
| 96 _subscription = app.vm.events.stream.where( | 97 _subscription = app.vm.events.stream.where( |
| 97 (event) => event.isolate == isolate).listen(_onEvent); | 98 (event) => event.isolate == isolate).listen(_onEvent); |
| 98 } | 99 } |
| 99 | 100 |
| 100 @override | 101 @override |
| 101 void detached() { | 102 void detached() { |
| 102 _subscription.cancel((){}); | 103 _subscription.cancel(); |
| 103 super.detached(); | 104 super.detached(); |
| 104 } | 105 } |
| 105 | 106 |
| 106 // Keep at most one outstanding auto-refresh RPC. | 107 // Keep at most one outstanding auto-refresh RPC. |
| 107 bool refreshAutoPending = false; | 108 bool refreshAutoPending = false; |
| 108 bool refreshAutoQueued = false; | 109 bool refreshAutoQueued = false; |
| 109 | 110 |
| 110 void _onEvent(ServiceEvent event) { | 111 void _onEvent(ServiceEvent event) { |
| 111 if (autoRefresh && event.eventType == 'GC') { | 112 if (autoRefresh && event.eventType == 'GC') { |
| 112 if (!refreshAutoPending) { | 113 if (!refreshAutoPending) { |
| 113 refreshAuto(); | 114 refreshAuto(); |
| 114 } else { | 115 } else { |
| 115 // Remember to refresh once more, to ensure latest profile. | 116 // Remember to refresh once more, to ensure latest profile. |
| 116 refreshAutoQueued = true; | 117 refreshAutoQueued = true; |
| 117 } | 118 } |
| 118 } | 119 } |
| 119 } | 120 } |
| 120 | 121 |
| 121 void refreshAuto() { | 122 void refreshAuto() { |
| 122 refreshAutoPending = true; | 123 refreshAutoPending = true; |
| 123 refreshAutoQueued = false; | 124 refreshAutoQueued = false; |
| 124 refresh(() { | 125 refresh().then((_) { |
| 125 refreshAutoPending = false; | 126 refreshAutoPending = false; |
| 126 // Keep refreshing if at least one GC event was received while waiting. | 127 // Keep refreshing if at least one GC event was received while waiting. |
| 127 if (refreshAutoQueued) { | 128 if (refreshAutoQueued) { |
| 128 refreshAuto(); | 129 refreshAuto(); |
| 129 } | 130 } |
| 130 }); | 131 }).catchError(app.handleException); |
| 131 } | 132 } |
| 132 | 133 |
| 133 void _updatePieCharts() { | 134 void _updatePieCharts() { |
| 134 assert(profile != null); | 135 assert(profile != null); |
| 135 _newPieDataTable.clearRows(); | 136 _newPieDataTable.clearRows(); |
| 136 _newPieDataTable.addRow(['Used', isolate.newSpace.used]); | 137 _newPieDataTable.addRow(['Used', isolate.newSpace.used]); |
| 137 _newPieDataTable.addRow(['Free', | 138 _newPieDataTable.addRow(['Free', |
| 138 isolate.newSpace.capacity - isolate.newSpace.used]); | 139 isolate.newSpace.capacity - isolate.newSpace.used]); |
| 139 _newPieDataTable.addRow(['External', isolate.newSpace.external]); | 140 _newPieDataTable.addRow(['External', isolate.newSpace.external]); |
| 140 _oldPieDataTable.clearRows(); | 141 _oldPieDataTable.clearRows(); |
| (...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 277 classTable.sort(); | 278 classTable.sort(); |
| 278 _updateClassTableInDom(); | 279 _updateClassTableInDom(); |
| 279 } | 280 } |
| 280 } | 281 } |
| 281 | 282 |
| 282 void isolateChanged(oldValue) { | 283 void isolateChanged(oldValue) { |
| 283 if (isolate == null) { | 284 if (isolate == null) { |
| 284 profile = null; | 285 profile = null; |
| 285 return; | 286 return; |
| 286 } | 287 } |
| 287 isolate.invokeRpc('_getAllocationProfile', {}).then(_update); | 288 isolate.invokeRpc('_getAllocationProfile', {}) |
| 289 .then(_update) |
| 290 .catchError(app.handleException); |
| 288 } | 291 } |
| 289 | 292 |
| 290 void refresh(var done) { | 293 Future refresh() { |
| 291 if (isolate == null) { | 294 if (isolate == null) { |
| 292 return; | 295 return new Future.value(null); |
| 293 } | 296 } |
| 294 isolate.invokeRpc('_getAllocationProfile', {}) | 297 return isolate.invokeRpc('_getAllocationProfile', {}) |
| 295 .then(_update).whenComplete(done); | 298 .then(_update); |
| 296 } | 299 } |
| 297 | 300 |
| 298 void refreshGC(var done) { | 301 Future refreshGC() { |
| 299 if (isolate == null) { | 302 if (isolate == null) { |
| 300 return; | 303 return new Future.value(null); |
| 301 } | 304 } |
| 302 isolate.invokeRpc('_getAllocationProfile', { 'gc': 'full' }) | 305 return isolate.invokeRpc('_getAllocationProfile', { 'gc': 'full' }) |
| 303 .then(_update).whenComplete(done); | 306 .then(_update); |
| 304 } | 307 } |
| 305 | 308 |
| 306 void resetAccumulator(var done) { | 309 Future resetAccumulator() { |
| 307 if (isolate == null) { | 310 if (isolate == null) { |
| 308 return; | 311 return new Future.value(null); |
| 309 } | 312 } |
| 310 isolate.invokeRpc('_getAllocationProfile', { 'reset': 'true' }) | 313 return isolate.invokeRpc('_getAllocationProfile', { 'reset': 'true' }) |
| 311 .then(_update).whenComplete(done); | 314 .then(_update); |
| 312 } | 315 } |
| 313 | 316 |
| 314 void _update(ServiceMap newProfile) { | 317 void _update(ServiceMap newProfile) { |
| 315 profile = newProfile; | 318 profile = newProfile; |
| 316 } | 319 } |
| 317 | 320 |
| 318 void profileChanged(oldValue) { | 321 void profileChanged(oldValue) { |
| 319 if (profile == null) { | 322 if (profile == null) { |
| 320 return; | 323 return; |
| 321 } | 324 } |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 358 } | 361 } |
| 359 | 362 |
| 360 @observable String formattedTotalCollectionTime(bool newSpace) { | 363 @observable String formattedTotalCollectionTime(bool newSpace) { |
| 361 if (profile == null) { | 364 if (profile == null) { |
| 362 return ''; | 365 return ''; |
| 363 } | 366 } |
| 364 var heap = newSpace ? isolate.newSpace : isolate.oldSpace; | 367 var heap = newSpace ? isolate.newSpace : isolate.oldSpace; |
| 365 return '${Utils.formatSeconds(heap.totalCollectionTimeInSeconds)} secs'; | 368 return '${Utils.formatSeconds(heap.totalCollectionTimeInSeconds)} secs'; |
| 366 } | 369 } |
| 367 } | 370 } |
| OLD | NEW |