Chromium Code Reviews| Index: runtime/bin/vmservice/client/lib/src/elements/heap_profile.dart |
| diff --git a/runtime/bin/vmservice/client/lib/src/elements/heap_profile.dart b/runtime/bin/vmservice/client/lib/src/elements/heap_profile.dart |
| index cd64321d4fdae122604ec370dd5f136be3373435..c682519587d66d597cd6c1a53891d8c81de5ab35 100644 |
| --- a/runtime/bin/vmservice/client/lib/src/elements/heap_profile.dart |
| +++ b/runtime/bin/vmservice/client/lib/src/elements/heap_profile.dart |
| @@ -6,10 +6,10 @@ library heap_profile_element; |
| import 'dart:html'; |
| import 'observatory_element.dart'; |
| +import 'package:observatory/app.dart'; |
| import 'package:observatory/service.dart'; |
| import 'package:logging/logging.dart'; |
| import 'package:polymer/polymer.dart'; |
| -import 'package:observatory/app.dart'; |
| /// Displays an Error response. |
| @CustomTag('heap-profile') |
| @@ -32,103 +32,63 @@ class HeapProfileElement extends ObservatoryElement { |
| var _oldPieDataTable; |
| var _oldPieChart; |
| - // The combined chart has old and new space merged. |
| - var _combinedDataTable; |
| - var _combinedChart; |
| - |
| - // The full chart has separate columns for new and old space. |
| - var _fullDataTable; |
| - var _fullChart; |
| + @observable SortedTable classTable; |
| @published ServiceMap profile; |
| HeapProfileElement.created() : super.created() { |
| - _fullDataTable = new DataTable(); |
| - _fullDataTable.addColumn('string', 'Class'); |
| - _fullDataTable.addColumn('number', 'Current (new)'); |
| - _fullDataTable.addColumn('number', 'Allocated Since GC (new)'); |
| - _fullDataTable.addColumn('number', 'Total before GC (new)'); |
| - _fullDataTable.addColumn('number', 'Survivors (new)'); |
| - _fullDataTable.addColumn('number', 'Current (old)'); |
| - _fullDataTable.addColumn('number', 'Allocated Since GC (old)'); |
| - _fullDataTable.addColumn('number', 'Total before GC (old)'); |
| - _fullDataTable.addColumn('number', 'Survivors (old)'); |
| _newPieDataTable = new DataTable(); |
| _newPieDataTable.addColumn('string', 'Type'); |
| _newPieDataTable.addColumn('number', 'Size'); |
| _oldPieDataTable = new DataTable(); |
| _oldPieDataTable.addColumn('string', 'Type'); |
| _oldPieDataTable.addColumn('number', 'Size'); |
| - _combinedDataTable = new DataTable(); |
| - _combinedDataTable.addColumn('string', 'Class'); |
| - _combinedDataTable.addColumn('number', 'Accumulator'); |
| - _combinedDataTable.addColumn('number', 'Accumulator Instances'); |
| - _combinedDataTable.addColumn('number', 'Current'); |
| - _combinedDataTable.addColumn('number', 'Allocated Since GC'); |
| - _combinedDataTable.addColumn('number', 'Total before GC'); |
| - _combinedDataTable.addColumn('number', 'Survivors after GC'); |
| + var columns = [ |
| + new SortedTableColumn('Class'), |
| + new SortedTableColumn.withFormatter('Accumulator Size', |
| + Utils.formatSize), |
| + new SortedTableColumn.withFormatter('Accumulator Instances', |
| + Utils.formatCommaSeperated), |
| + new SortedTableColumn.withFormatter('Current Size', |
| + Utils.formatSize), |
| + new SortedTableColumn.withFormatter('Current Instances', |
| + Utils.formatCommaSeperated) |
| + ]; |
| + classTable = new SortedTable(columns); |
| + classTable.sortColumnIndex = 1; |
|
turnidge
2014/04/17 20:18:54
This code seems a lot simpler now.
Cutch
2014/04/17 22:12:39
Done.
|
| } |
| void enteredView() { |
| super.enteredView(); |
| - _fullChart = new Chart('Table', |
| - shadowRoot.querySelector('#table')); |
| - _fullChart.options['allowHtml'] = true; |
| - _fullChart.options['sortColumn'] = 1; |
| - _fullChart.options['sortAscending'] = false; |
| _newPieChart = new Chart('PieChart', |
| shadowRoot.querySelector('#newPieChart')); |
| _newPieChart.options['title'] = 'New Space'; |
| _oldPieChart = new Chart('PieChart', |
| shadowRoot.querySelector('#oldPieChart')); |
| _oldPieChart.options['title'] = 'Old Space'; |
| - _combinedChart = new Chart('Table', |
| - shadowRoot.querySelector('#simpleTable')); |
| - _combinedChart.options['allowHtml'] = true; |
| - _combinedChart.options['sortColumn'] = 1; |
| - _combinedChart.options['sortAscending'] = false; |
| _draw(); |
| } |
| - bool _first = true; |
| - |
| void _updateChartData() { |
| if ((profile == null) || (profile['members'] is! List) || |
| (profile['members'].length == 0)) { |
| return; |
| } |
| - assert(_fullDataTable != null); |
| - assert(_combinedDataTable != null); |
| - _fullDataTable.clearRows(); |
| - _combinedDataTable.clearRows(); |
| + assert(classTable != null); |
| + classTable.clearRows(); |
| for (ServiceMap cls in profile['members']) { |
| if (_classHasNoAllocations(cls)) { |
| // If a class has no allocations, don't display it. |
| continue; |
| } |
| - var vm_name = cls['class']['name']; |
| - var url = cls['class'].hashLink; |
| - _fullDataTable.addRow([ |
| - '<a title="$vm_name" href="$url">' |
| - '${_fullTableColumnValue(cls, 0)}</a>', |
| - _fullTableColumnValue(cls, 1), |
| - _fullTableColumnValue(cls, 2), |
| - _fullTableColumnValue(cls, 3), |
| - _fullTableColumnValue(cls, 4), |
| - _fullTableColumnValue(cls, 5), |
| - _fullTableColumnValue(cls, 6), |
| - _fullTableColumnValue(cls, 7), |
| - _fullTableColumnValue(cls, 8)]); |
| - _combinedDataTable.addRow([ |
| - '<a title="$vm_name" href="$url">' |
| - '${_combinedTableColumnValue(cls, 0)}</a>', |
| - _combinedTableColumnValue(cls, 1), |
| - _combinedTableColumnValue(cls, 2), |
| - _combinedTableColumnValue(cls, 3), |
| - _combinedTableColumnValue(cls, 4), |
| - _combinedTableColumnValue(cls, 5), |
| - _combinedTableColumnValue(cls, 6)]); |
| + var row = [cls['class'], |
| + _combinedTableColumnValue(cls, 1), |
| + _combinedTableColumnValue(cls, 2), |
| + _combinedTableColumnValue(cls, 3), |
| + _combinedTableColumnValue(cls, 4)]; |
| + classTable.addRow(new SortedTableRow(row)); |
| } |
| + classTable.sort(); |
| _newPieDataTable.clearRows(); |
| var heap = profile['heaps']['new']; |
| _newPieDataTable.addRow(['Used', heap['used']]); |
| @@ -143,17 +103,22 @@ class HeapProfileElement extends ObservatoryElement { |
| } |
| void _draw() { |
| - if ((_fullChart == null) || (_combinedChart == null)) { |
| + if (_newPieChart == null) { |
| return; |
| } |
| - _combinedChart.refreshOptionsSortInfo(); |
| - _combinedChart.draw(_combinedDataTable); |
| - _fullChart.refreshOptionsSortInfo(); |
| - _fullChart.draw(_fullDataTable); |
| _newPieChart.draw(_newPieDataTable); |
| _oldPieChart.draw(_oldPieDataTable); |
| } |
| + @observable void changeSort(Event e, var detail, Element target) { |
| + if (target is TableCellElement) { |
| + if (classTable.sortColumnIndex != target.cellIndex) { |
| + classTable.sortColumnIndex = target.cellIndex; |
| + classTable.sort(); |
| + } |
| + } |
| + } |
| + |
| bool _classHasNoAllocations(Map v) { |
| var newSpace = v['new']; |
| var oldSpace = v['old']; |
| @@ -170,32 +135,6 @@ class HeapProfileElement extends ObservatoryElement { |
| return true; |
| } |
| - dynamic _fullTableColumnValue(Map v, int index) { |
| - assert(index >= 0); |
| - assert(index < 9); |
| - switch (index) { |
| - case 0: |
| - return v['class']['user_name']; |
| - case 1: |
| - return v['new'][LIVE_AFTER_GC_SIZE] + v['new'][ALLOCATED_SINCE_GC_SIZE]; |
| - case 2: |
| - return v['new'][ALLOCATED_SINCE_GC_SIZE]; |
| - case 3: |
| - return v['new'][ALLOCATED_BEFORE_GC_SIZE]; |
| - case 4: |
| - return v['new'][LIVE_AFTER_GC_SIZE]; |
| - case 5: |
| - return v['old'][LIVE_AFTER_GC_SIZE] + v['old'][ALLOCATED_SINCE_GC_SIZE]; |
| - case 6: |
| - return v['old'][ALLOCATED_SINCE_GC_SIZE]; |
| - case 7: |
| - return v['old'][ALLOCATED_BEFORE_GC_SIZE]; |
| - case 8: |
| - return v['old'][LIVE_AFTER_GC_SIZE]; |
| - } |
| - throw new FallThroughError(); |
| - } |
| - |
| dynamic _combinedTableColumnValue(Map v, int index) { |
| assert(index >= 0); |
| assert(index < 7); |
| @@ -214,13 +153,10 @@ class HeapProfileElement extends ObservatoryElement { |
| 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]; |
| + return v['new'][LIVE_AFTER_GC] + |
| + v['new'][ALLOCATED_SINCE_GC] + |
| + v['old'][LIVE_AFTER_GC] + |
| + v['old'][ALLOCATED_SINCE_GC]; |
| } |
| throw new FallThroughError(); |
| } |
| @@ -237,7 +173,7 @@ class HeapProfileElement extends ObservatoryElement { |
| }).whenComplete(done); |
| } |
| - void resetAccumulator(Event e, var detail, Node target) { |
| + void resetAccumulator(var done) { |
| if (profile == null) { |
| return; |
| } |
| @@ -247,11 +183,15 @@ class HeapProfileElement extends ObservatoryElement { |
| profile = response; |
| }).catchError((e, st) { |
| Logger.root.info('$e $st'); |
| - }); |
| + }).whenComplete(done); |
| } |
| void profileChanged(oldValue) { |
| - _updateChartData(); |
| + try { |
| + _updateChartData(); |
| + } catch (e, st) { |
| + Logger.root.info('$e $st'); |
| + } |
| notifyPropertyChange(#formattedAverage, [], formattedAverage); |
| notifyPropertyChange(#formattedTotalCollectionTime, [], |
| formattedTotalCollectionTime); |
| @@ -283,6 +223,6 @@ class HeapProfileElement extends ObservatoryElement { |
| } |
| String space = newSpace ? 'new' : 'old'; |
| Map heap = profile['heaps'][space]; |
| - return '${formatSeconds(heap['time'])} secs'; |
| + return '${Utils.formatSeconds(heap['time'])} secs'; |
| } |
| } |