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 |