| 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:html'; | 7 import 'dart:html'; |
| 8 import 'isolate_element.dart'; | 8 import 'observatory_element.dart'; |
| 9 import 'package:observatory/service.dart'; |
| 9 import 'package:logging/logging.dart'; | 10 import 'package:logging/logging.dart'; |
| 10 import 'package:polymer/polymer.dart'; | 11 import 'package:polymer/polymer.dart'; |
| 11 import 'package:observatory/app.dart'; | 12 import 'package:observatory/app.dart'; |
| 12 | 13 |
| 13 /// Displays an Error response. | 14 /// Displays an Error response. |
| 14 @CustomTag('heap-profile') | 15 @CustomTag('heap-profile') |
| 15 class HeapProfileElement extends IsolateElement { | 16 class HeapProfileElement extends ObservatoryElement { |
| 16 // Indexes into VM provided map. | 17 // Indexes into VM provided map. |
| 17 static const ALLOCATED_BEFORE_GC = 0; | 18 static const ALLOCATED_BEFORE_GC = 0; |
| 18 static const ALLOCATED_BEFORE_GC_SIZE = 1; | 19 static const ALLOCATED_BEFORE_GC_SIZE = 1; |
| 19 static const LIVE_AFTER_GC = 2; | 20 static const LIVE_AFTER_GC = 2; |
| 20 static const LIVE_AFTER_GC_SIZE = 3; | 21 static const LIVE_AFTER_GC_SIZE = 3; |
| 21 static const ALLOCATED_SINCE_GC = 4; | 22 static const ALLOCATED_SINCE_GC = 4; |
| 22 static const ALLOCATED_SINCE_GC_SIZE = 5; | 23 static const ALLOCATED_SINCE_GC_SIZE = 5; |
| 23 static const ACCUMULATED = 6; | 24 static const ACCUMULATED = 6; |
| 24 static const ACCUMULATED_SIZE = 7; | 25 static const ACCUMULATED_SIZE = 7; |
| 25 | 26 |
| 26 // Pie chart of new space usage. | 27 // Pie chart of new space usage. |
| 27 var _newPieDataTable; | 28 var _newPieDataTable; |
| 28 var _newPieChart; | 29 var _newPieChart; |
| 29 | 30 |
| 30 // Pie chart of old space usage. | 31 // Pie chart of old space usage. |
| 31 var _oldPieDataTable; | 32 var _oldPieDataTable; |
| 32 var _oldPieChart; | 33 var _oldPieChart; |
| 33 | 34 |
| 34 // The combined chart has old and new space merged. | 35 // The combined chart has old and new space merged. |
| 35 var _combinedDataTable; | 36 var _combinedDataTable; |
| 36 var _combinedChart; | 37 var _combinedChart; |
| 37 | 38 |
| 38 // The full chart has separate columns for new and old space. | 39 // The full chart has separate columns for new and old space. |
| 39 var _fullDataTable; | 40 var _fullDataTable; |
| 40 var _fullChart; | 41 var _fullChart; |
| 41 | 42 |
| 42 @published Map profile; | 43 @published ServiceMap profile; |
| 43 | 44 |
| 44 HeapProfileElement.created() : super.created() { | 45 HeapProfileElement.created() : super.created() { |
| 45 _fullDataTable = new DataTable(); | 46 _fullDataTable = new DataTable(); |
| 46 _fullDataTable.addColumn('string', 'Class'); | 47 _fullDataTable.addColumn('string', 'Class'); |
| 47 _fullDataTable.addColumn('number', 'Current (new)'); | 48 _fullDataTable.addColumn('number', 'Current (new)'); |
| 48 _fullDataTable.addColumn('number', 'Allocated Since GC (new)'); | 49 _fullDataTable.addColumn('number', 'Allocated Since GC (new)'); |
| 49 _fullDataTable.addColumn('number', 'Total before GC (new)'); | 50 _fullDataTable.addColumn('number', 'Total before GC (new)'); |
| 50 _fullDataTable.addColumn('number', 'Survivors (new)'); | 51 _fullDataTable.addColumn('number', 'Survivors (new)'); |
| 51 _fullDataTable.addColumn('number', 'Current (old)'); | 52 _fullDataTable.addColumn('number', 'Current (old)'); |
| 52 _fullDataTable.addColumn('number', 'Allocated Since GC (old)'); | 53 _fullDataTable.addColumn('number', 'Allocated Since GC (old)'); |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 93 | 94 |
| 94 void _updateChartData() { | 95 void _updateChartData() { |
| 95 if ((profile == null) || (profile['members'] is! List) || | 96 if ((profile == null) || (profile['members'] is! List) || |
| 96 (profile['members'].length == 0)) { | 97 (profile['members'].length == 0)) { |
| 97 return; | 98 return; |
| 98 } | 99 } |
| 99 assert(_fullDataTable != null); | 100 assert(_fullDataTable != null); |
| 100 assert(_combinedDataTable != null); | 101 assert(_combinedDataTable != null); |
| 101 _fullDataTable.clearRows(); | 102 _fullDataTable.clearRows(); |
| 102 _combinedDataTable.clearRows(); | 103 _combinedDataTable.clearRows(); |
| 103 for (Map cls in profile['members']) { | 104 for (ServiceMap cls in profile['members']) { |
| 104 if (_classHasNoAllocations(cls)) { | 105 if (_classHasNoAllocations(cls)) { |
| 105 // If a class has no allocations, don't display it. | 106 // If a class has no allocations, don't display it. |
| 106 continue; | 107 continue; |
| 107 } | 108 } |
| 108 var vm_name = cls['class']['name']; | 109 var vm_name = cls['class']['name']; |
| 109 var url = isolate.relativeLink(cls['class']['id']); | 110 var url = cls['class'].hashLink; |
| 110 _fullDataTable.addRow([ | 111 _fullDataTable.addRow([ |
| 111 '<a title="$vm_name" href="$url">' | 112 '<a title="$vm_name" href="$url">' |
| 112 '${_fullTableColumnValue(cls, 0)}</a>', | 113 '${_fullTableColumnValue(cls, 0)}</a>', |
| 113 _fullTableColumnValue(cls, 1), | 114 _fullTableColumnValue(cls, 1), |
| 114 _fullTableColumnValue(cls, 2), | 115 _fullTableColumnValue(cls, 2), |
| 115 _fullTableColumnValue(cls, 3), | 116 _fullTableColumnValue(cls, 3), |
| 116 _fullTableColumnValue(cls, 4), | 117 _fullTableColumnValue(cls, 4), |
| 117 _fullTableColumnValue(cls, 5), | 118 _fullTableColumnValue(cls, 5), |
| 118 _fullTableColumnValue(cls, 6), | 119 _fullTableColumnValue(cls, 6), |
| 119 _fullTableColumnValue(cls, 7), | 120 _fullTableColumnValue(cls, 7), |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 216 case 5: | 217 case 5: |
| 217 return v['new'][ALLOCATED_BEFORE_GC_SIZE] + | 218 return v['new'][ALLOCATED_BEFORE_GC_SIZE] + |
| 218 v['old'][ALLOCATED_BEFORE_GC_SIZE]; | 219 v['old'][ALLOCATED_BEFORE_GC_SIZE]; |
| 219 case 6: | 220 case 6: |
| 220 return v['new'][LIVE_AFTER_GC_SIZE] + v['old'][LIVE_AFTER_GC_SIZE]; | 221 return v['new'][LIVE_AFTER_GC_SIZE] + v['old'][LIVE_AFTER_GC_SIZE]; |
| 221 } | 222 } |
| 222 throw new FallThroughError(); | 223 throw new FallThroughError(); |
| 223 } | 224 } |
| 224 | 225 |
| 225 void refresh(var done) { | 226 void refresh(var done) { |
| 226 isolate.getMap('/allocationprofile').then((Map response) { | 227 if (profile == null) { |
| 228 return; |
| 229 } |
| 230 profile.isolate.get('/allocationprofile').then((ServiceMap response) { |
| 227 assert(response['type'] == 'AllocationProfile'); | 231 assert(response['type'] == 'AllocationProfile'); |
| 228 profile = response; | 232 profile = response; |
| 229 }).catchError((e, st) { | 233 }).catchError((e, st) { |
| 230 Logger.root.info('$e $st'); | 234 Logger.root.info('$e $st'); |
| 231 }).whenComplete(done); | 235 }).whenComplete(done); |
| 232 } | 236 } |
| 233 | 237 |
| 234 void resetAccumulator(Event e, var detail, Node target) { | 238 void resetAccumulator(Event e, var detail, Node target) { |
| 235 isolate.getMap('/allocationprofile/reset').then((Map response) { | 239 if (profile == null) { |
| 240 return; |
| 241 } |
| 242 profile.isolate.get('/allocationprofile/reset').then((ServiceMap response) { |
| 236 assert(response['type'] == 'AllocationProfile'); | 243 assert(response['type'] == 'AllocationProfile'); |
| 237 profile = response; | 244 profile = response; |
| 238 }).catchError((e, st) { | 245 }).catchError((e, st) { |
| 239 Logger.root.info('$e $st'); | 246 Logger.root.info('$e $st'); |
| 240 }); | 247 }); |
| 241 } | 248 } |
| 242 | 249 |
| 243 void profileChanged(oldValue) { | 250 void profileChanged(oldValue) { |
| 244 _updateChartData(); | 251 _updateChartData(); |
| 245 notifyPropertyChange(#formattedAverage, [], formattedAverage); | 252 notifyPropertyChange(#formattedAverage, [], formattedAverage); |
| (...skipping 20 matching lines...) Expand all Loading... |
| 266 Map heap = profile['heaps'][space]; | 273 Map heap = profile['heaps'][space]; |
| 267 return '${heap['collections']}'; | 274 return '${heap['collections']}'; |
| 268 } | 275 } |
| 269 | 276 |
| 270 @observable String formattedTotalCollectionTime(bool newSpace) { | 277 @observable String formattedTotalCollectionTime(bool newSpace) { |
| 271 if (profile == null) { | 278 if (profile == null) { |
| 272 return ''; | 279 return ''; |
| 273 } | 280 } |
| 274 String space = newSpace ? 'new' : 'old'; | 281 String space = newSpace ? 'new' : 'old'; |
| 275 Map heap = profile['heaps'][space]; | 282 Map heap = profile['heaps'][space]; |
| 276 return '${ObservatoryApplication.timeUnits(heap['time'])} secs'; | 283 return '${formatSeconds(heap['time'])} secs'; |
| 277 } | 284 } |
| 278 } | 285 } |
| OLD | NEW |