Chromium Code Reviews| Index: runtime/bin/vmservice/client/lib/src/observatory_elements/heap_profile.dart |
| diff --git a/runtime/bin/vmservice/client/lib/src/observatory_elements/heap_profile.dart b/runtime/bin/vmservice/client/lib/src/observatory_elements/heap_profile.dart |
| index db78b94e3f0abf4a7123a01b975d45c49346fab9..442bd5171398cce99ed61b15ffd2c0ca1ca0d83e 100644 |
| --- a/runtime/bin/vmservice/client/lib/src/observatory_elements/heap_profile.dart |
| +++ b/runtime/bin/vmservice/client/lib/src/observatory_elements/heap_profile.dart |
| @@ -20,6 +20,8 @@ class HeapProfileElement extends ObservatoryElement { |
| static const LIVE_AFTER_GC_SIZE = 3; |
| static const ALLOCATED_SINCE_GC = 4; |
| static const ALLOCATED_SINCE_GC_SIZE = 5; |
| + static const ACCUMULATED = 6; |
| + static const ACCUMULATED_SIZE = 7; |
| var _newPieDataTable; |
| var _newPieChart; |
| @@ -27,6 +29,9 @@ class HeapProfileElement extends ObservatoryElement { |
| var _oldPieDataTable; |
| var _oldPieChart; |
| + var _simpleDataTable; |
| + var _simpleChart; |
|
turnidge
2014/02/27 18:29:13
Is there a better name than simpleDataTable? Tha
Cutch
2014/02/27 21:50:33
I've renamed it to "combined", which is a better n
|
| + |
| var _tableDataTable; |
| var _tableChart; |
| @@ -49,6 +54,14 @@ class HeapProfileElement extends ObservatoryElement { |
| _oldPieDataTable = new DataTable(); |
| _oldPieDataTable.addColumn('string', 'Type'); |
| _oldPieDataTable.addColumn('number', 'Size'); |
| + _simpleDataTable = new DataTable(); |
| + _simpleDataTable.addColumn('string', 'Class'); |
| + _simpleDataTable.addColumn('number', 'Accumulator'); |
| + _simpleDataTable.addColumn('number', 'Accumulator Instances'); |
| + _simpleDataTable.addColumn('number', 'Current'); |
| + _simpleDataTable.addColumn('number', 'Allocated Since GC'); |
| + _simpleDataTable.addColumn('number', 'Total before GC'); |
| + _simpleDataTable.addColumn('number', 'Survivors after GC'); |
| } |
| void enteredView() { |
| @@ -64,6 +77,11 @@ class HeapProfileElement extends ObservatoryElement { |
| _oldPieChart = new Chart('PieChart', |
| shadowRoot.querySelector('#oldPieChart')); |
| _oldPieChart.options['title'] = 'Old Space'; |
| + _simpleChart = new Chart('Table', |
| + shadowRoot.querySelector('#simpleTable')); |
| + _simpleChart.options['allowHtml'] = true; |
| + _simpleChart.options['sortColumn'] = 1; |
| + _simpleChart.options['sortAscending'] = false; |
| _draw(); |
| } |
| @@ -75,12 +93,18 @@ class HeapProfileElement extends ObservatoryElement { |
| return; |
| } |
| assert(_tableDataTable != null); |
| + assert(_simpleDataTable != null); |
| _tableDataTable.clearRows(); |
| + _simpleDataTable.clearRows(); |
| for (Map cls in profile['members']) { |
| + if (_shouldSkip(cls)) { |
| + continue; |
| + } |
| + var vm_name = cls['class']['name']; |
| var url = |
| app.locationManager.currentIsolateRelativeLink(cls['class']['id']); |
| _tableDataTable.addRow( |
| - ['<a href="$url">${_columnValue(cls, 0)}</a>', |
| + ['<a title="$vm_name" href="$url">${_columnValue(cls, 0)}</a>', |
| _columnValue(cls, 1), |
| _columnValue(cls, 2), |
| _columnValue(cls, 3), |
| @@ -89,6 +113,14 @@ class HeapProfileElement extends ObservatoryElement { |
| _columnValue(cls, 6), |
| _columnValue(cls, 7), |
| _columnValue(cls, 8)]); |
| + _simpleDataTable.addRow( |
| + ['<a title="$vm_name" href="$url">${_simpleColumnValue(cls, 0)}</a>', |
| + _simpleColumnValue(cls, 1), |
| + _simpleColumnValue(cls, 2), |
| + _simpleColumnValue(cls, 3), |
| + _simpleColumnValue(cls, 4), |
| + _simpleColumnValue(cls, 5), |
| + _simpleColumnValue(cls, 6)]); |
| } |
| _newPieDataTable.clearRows(); |
| var heap = profile['heaps']['new']; |
| @@ -102,14 +134,33 @@ class HeapProfileElement extends ObservatoryElement { |
| } |
| void _draw() { |
| - if (_tableChart == null) { |
| + if ((_tableChart == null) || (_simpleChart == null)) { |
| return; |
| } |
| + _simpleChart.refreshOptionsSortInfo(); |
| + _simpleChart.draw(_simpleDataTable); |
| + _tableChart.refreshOptionsSortInfo(); |
| _tableChart.draw(_tableDataTable); |
| _newPieChart.draw(_newPieDataTable); |
| _oldPieChart.draw(_oldPieDataTable); |
| } |
| + bool _shouldSkip(Map v) { |
|
turnidge
2014/02/27 18:29:13
This function is a bit cryptic. Should skip what?
Cutch
2014/02/27 21:50:33
Cleaned up. renamed to _classHasNoAllocations.
|
| + var n = v['new']; |
| + var o = v['old']; |
| + for (var i in n) { |
| + if (i != 0) { |
| + return false; |
| + } |
| + } |
| + for (var i in o) { |
| + if (i != 0) { |
| + return false; |
| + } |
| + } |
| + return true; |
| + } |
| + |
| dynamic _columnValue(Map v, int index) { |
| assert(index >= 0); |
| assert(index < 9); |
| @@ -133,6 +184,36 @@ class HeapProfileElement extends ObservatoryElement { |
| case 8: |
| return v['old'][LIVE_AFTER_GC_SIZE]; |
| } |
| + throw new FallThroughError(); |
| + } |
| + |
| + dynamic _simpleColumnValue(Map v, int index) { |
| + assert(index >= 0); |
| + assert(index < 7); |
| + switch (index) { |
| + case 0: |
| + return v['class']['user_name']; |
| + case 1: |
| + return v['new'][ACCUMULATED_SIZE] + |
| + v['old'][ACCUMULATED_SIZE]; |
| + case 2: |
| + return v['new'][ACCUMULATED] + |
| + v['old'][ACCUMULATED]; |
| + case 3: |
| + return v['new'][LIVE_AFTER_GC_SIZE] + |
| + v['new'][ALLOCATED_SINCE_GC_SIZE] + |
| + v['old'][LIVE_AFTER_GC_SIZE] + |
| + v['old'][ALLOCATED_SINCE_GC_SIZE]; |
| + case 4: |
| + return v['new'][ALLOCATED_SINCE_GC_SIZE] + |
| + v['old'][ALLOCATED_SINCE_GC_SIZE]; |
| + case 5: |
| + return v['new'][ALLOCATED_BEFORE_GC_SIZE] + |
| + v['old'][ALLOCATED_BEFORE_GC_SIZE]; |
| + case 6: |
| + return v['new'][LIVE_AFTER_GC_SIZE] + v['old'][LIVE_AFTER_GC_SIZE]; |
| + } |
| + throw new FallThroughError(); |
| } |
| void refreshData(Event e, var detail, Node target) { |
| @@ -151,6 +232,22 @@ class HeapProfileElement extends ObservatoryElement { |
| }); |
| } |
| + void resetAccumulator(Event e, var detail, Node target) { |
| + var isolateId = app.locationManager.currentIsolateId(); |
| + var isolate = app.isolateManager.getIsolate(isolateId); |
| + if (isolate == null) { |
| + Logger.root.info('No isolate found.'); |
| + return; |
| + } |
| + var request = '/$isolateId/allocationprofile/reset'; |
| + app.requestManager.requestMap(request).then((Map response) { |
| + assert(response['type'] == 'AllocationProfile'); |
| + profile = response; |
| + }).catchError((e, st) { |
| + Logger.root.info('$e $st'); |
| + }); |
| + } |
| + |
| void profileChanged(oldValue) { |
| _updateChartData(); |
| notifyPropertyChange(#formattedAverage, [], formattedAverage); |