Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(179)

Unified Diff: runtime/bin/vmservice/client/lib/src/observatory_elements/heap_profile.dart

Issue 148153007: Add Google Charts to Observatory and use it in allocation profiler (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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 15eb2d609e3d04403240bd165fdc8898082e63c5..af84aa3648e74e1e4b3d82812c97c7d212fdb64c 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
@@ -4,7 +4,9 @@
library heap_profile_element;
+import 'dart:async';
import 'dart:html';
+import 'dart:js';
import 'package:logging/logging.dart';
import 'package:polymer/polymer.dart';
import 'observatory_element.dart';
@@ -20,26 +22,108 @@ class HeapProfileElement extends ObservatoryElement {
static const ALLOCATED_SINCE_GC = 4;
static const ALLOCATED_SINCE_GC_SIZE = 5;
+ var _newPieOptions;
+ var _newPieDataTable;
+ var _newPieChart;
turnidge 2014/01/28 18:28:08 Instead of a making Chart all static, why not make
Cutch 2014/01/28 23:23:19 Refactored Chart wrapper.
+
+ var _oldPieOptions;
+ var _oldPieDataTable;
+ var _oldPieChart;
+
+ var _tableOptions;
+ var _tableDataTable;
+ var _tableChart;
+
@published Map profile;
@published List sortedProfile;
int _sortColumnIndex = 1;
- HeapProfileElement.created() : super.created();
-
- // Display columns.
- @observable final List<String> columns = [
- 'Class',
- 'Current (new)',
- 'Allocated Since GC (new)',
- 'Total before GC (new)',
- 'Survivors (new)',
- 'Current (old)',
- 'Allocated Since GC (old)',
- 'Total before GC (old)',
- 'Survivors (old)',
- ];
+ HeapProfileElement.created() : super.created() {
+ _tableOptions = new JsObject.jsify({
+ 'allowHtml': 'true',
+ 'sortColumn': 1,
+ 'sortAscending': false,
+ });
+ _newPieOptions = new JsObject.jsify({
+ 'title': 'New Space'
+ });
+ _oldPieOptions = new JsObject.jsify({
+ 'title': 'Old Space'
+ });
+ _tableDataTable = Chart.createDataTable();
+ Chart.addColumn(_tableDataTable, 'string', 'Class');
+ Chart.addColumn(_tableDataTable, 'number', 'Current (new)');
+ Chart.addColumn(_tableDataTable, 'number', 'Allocated Since GC (new)');
+ Chart.addColumn(_tableDataTable, 'number', 'Total before GC (new)');
+ Chart.addColumn(_tableDataTable, 'number', 'Survivors (new)');
+ Chart.addColumn(_tableDataTable, 'number', 'Current (old)');
+ Chart.addColumn(_tableDataTable, 'number', 'Allocated Since GC (old)');
+ Chart.addColumn(_tableDataTable, 'number', 'Total before GC (old)');
+ Chart.addColumn(_tableDataTable, 'number', 'Survivors (old)');
+ _newPieDataTable = Chart.createDataTable();
+ Chart.addColumn(_newPieDataTable, 'string', 'Type');
+ Chart.addColumn(_newPieDataTable, 'number', 'Size');
+ _oldPieDataTable = Chart.createDataTable();
+ Chart.addColumn(_oldPieDataTable, 'string', 'Type');
+ Chart.addColumn(_oldPieDataTable, 'number', 'Size');
+ }
+
+ void enteredView() {
+ super.enteredView();
+ _tableChart = Chart.createChart('Table',
+ shadowRoot.querySelector('#table'));
+ _newPieChart = Chart.createChart('PieChart',
+ shadowRoot.querySelector('#newPieChart'));
+ _oldPieChart = Chart.createChart('PieChart',
+ shadowRoot.querySelector('#oldPieChart'));
+ _draw();
+ }
+
+ void _updateChartData() {
+ if ((profile == null) || (profile['members'] is! List) ||
+ (profile['members'].length == 0)) {
+ sortedProfile = toObservable([]);
+ return;
+ }
+ assert(_tableDataTable != null);
+ Chart.clearRows(_tableDataTable);
+ for (Map cls in profile['members']) {
+ var url =
+ app.locationManager.currentIsolateRelativeLink(cls['class']['id']);
+ Chart.addRow(_tableDataTable,
+ ['<a href="$url">${_columnValue(cls, 0)}</a>',
+ _columnValue(cls, 1),
+ _columnValue(cls, 2),
+ _columnValue(cls, 3),
+ _columnValue(cls, 4),
+ _columnValue(cls, 5),
+ _columnValue(cls, 6),
+ _columnValue(cls, 7),
+ _columnValue(cls, 8)]);
+ }
+ Chart.clearRows(_newPieDataTable);
+ var heap = profile['heaps']['new'];
+ Chart.addRow(_newPieDataTable, ['Used', heap['used']]);
+ Chart.addRow(_newPieDataTable, ['Free', heap['capacity'] - heap['used']]);
+ Chart.clearRows(_oldPieDataTable);
+ heap = profile['heaps']['old'];
+ Chart.addRow(_oldPieDataTable, ['Used', heap['used']]);
+ Chart.addRow(_oldPieDataTable, ['Free', heap['capacity'] - heap['used']]);
+ _draw();
+ }
+
+ void _draw() {
+ if (_tableChart == null) {
+ return;
+ }
+ Chart.refreshTableChartDrawOptions(_tableChart, _tableOptions);
+ Chart.draw(_tableChart, _tableDataTable, _tableOptions);
+ Chart.draw(_newPieChart, _newPieDataTable, _newPieOptions);
+ Chart.draw(_oldPieChart, _oldPieDataTable, _oldPieOptions);
+ }
dynamic _columnValue(Map v, int index) {
- assert(columns.length == 9);
+ assert(index >= 0);
+ assert(index < 9);
switch (index) {
case 0:
return v['class']['user_name'];
@@ -62,43 +146,6 @@ class HeapProfileElement extends ObservatoryElement {
}
}
- int _sortColumn(Map a, Map b, int index) {
- var aValue = _columnValue(a, index);
- var bValue = _columnValue(b, index);
- return Comparable.compare(bValue, aValue);
- }
-
- _sort() {
- if ((profile == null) || (profile['members'] is! List) ||
- (profile['members'].length == 0)) {
- sortedProfile = toObservable([]);
- return;
- }
- sortedProfile = profile['members'].toList();
- sortedProfile.sort((a, b) => _sortColumn(a, b, _sortColumnIndex));
- sortedProfile = toObservable(sortedProfile);
- notifyPropertyChange(#sortedProfile, [], sortedProfile);
- notifyPropertyChange(#current, 0, 1);
- notifyPropertyChange(#allocated, 0, 1);
- notifyPropertyChange(#beforeGC, 0, 1);
- notifyPropertyChange(#afterGC, 0, 1);
- }
-
- void changeSortColumn(Event e, var detail, Element target) {
- var message = target.attributes['data-msg'];
- var index;
- try {
- index = int.parse(message);
- } catch (e) {
- return;
- }
- assert(index is int);
- assert(index > 0);
- assert(index < columns.length);
- _sortColumnIndex = index;
- _sort();
- }
-
void refreshData(Event e, var detail, Node target) {
var isolateId = app.locationManager.currentIsolateId();
var isolate = app.isolateManager.getIsolate(isolateId);
@@ -116,84 +163,38 @@ class HeapProfileElement extends ObservatoryElement {
}
void profileChanged(oldValue) {
- _sort();
- notifyPropertyChange(#status, [], status);
+ _updateChartData();
+ notifyPropertyChange(#formattedAverage, [], formattedAverage);
+ notifyPropertyChange(#formattedTotalCollectionTime, [],
+ formattedTotalCollectionTime);
+ notifyPropertyChange(#formattedCollections, [], formattedCollections);
}
- String status(bool new_space) {
+ @observable String formattedAverage(bool newSpace) {
if (profile == null) {
return '';
}
- String space = new_space ? 'new' : 'old';
+ String space = newSpace ? 'new' : 'old';
Map heap = profile['heaps'][space];
- var usage = '${ObservatoryApplication.scaledSizeUnits(heap['used'])} / '
- '${ObservatoryApplication.scaledSizeUnits(heap['capacity'])}';
- var timings = '${ObservatoryApplication.timeUnits(heap['time'])} secs';
- var collections = '${heap['collections']} collections';
- var avgTime = '${(heap['time'] * 1000.0) / heap['collections']} ms';
- return '$usage ($timings) [$collections] $avgTime';
- }
-
- String current(Map cls, bool new_space, [bool instances = false]) {
- if (cls is !Map) {
- return '';
- }
- List data = cls[new_space ? 'new' : 'old'];
- if (data == null) {
- return '';
- }
- int current = data[instances ? LIVE_AFTER_GC : LIVE_AFTER_GC_SIZE] +
- data[instances ? ALLOCATED_SINCE_GC : ALLOCATED_SINCE_GC_SIZE];
- if (instances) {
- return '$current';
- }
- return ObservatoryApplication.scaledSizeUnits(current);
- }
-
- String allocated(Map cls, bool new_space, [bool instances = false]) {
- if (cls is !Map) {
- return '';
- }
- List data = cls[new_space ? 'new' : 'old'];
- if (data == null) {
- return '';
- }
- int current =
- data[instances ? ALLOCATED_SINCE_GC : ALLOCATED_SINCE_GC_SIZE];
- if (instances) {
- return '$current';
- }
- return ObservatoryApplication.scaledSizeUnits(current);
+ var r = ((heap['time'] * 1000.0) / heap['collections']).toStringAsFixed(2);
+ return '$r ms';
}
- String beforeGC(Map cls, bool new_space, [bool instances = false]) {
- if (cls is! Map) {
- return '';
- }
- List data = cls[new_space ? 'new' : 'old'];
- if (data == null) {
+ @observable String formattedCollections(bool newSpace) {
+ if (profile == null) {
return '';
}
- int current =
- data[instances ? ALLOCATED_BEFORE_GC : ALLOCATED_BEFORE_GC_SIZE];
- if (instances) {
- return '$current';
- }
- return ObservatoryApplication.scaledSizeUnits(current);
+ String space = newSpace ? 'new' : 'old';
+ Map heap = profile['heaps'][space];
+ return '${heap['collections']}';
}
- String afterGC(Map cls, bool new_space, [bool instances = false]) {
- if (cls is! Map) {
- return '';
- }
- List data = cls[new_space ? 'new' : 'old'];
- if (data == null) {
+ @observable String formattedTotalCollectionTime(bool newSpace) {
+ if (profile == null) {
return '';
}
- int current = data[instances ? LIVE_AFTER_GC : LIVE_AFTER_GC_SIZE];
- if (instances) {
- return '$current';
- }
- return ObservatoryApplication.scaledSizeUnits(current);
+ String space = newSpace ? 'new' : 'old';
+ Map heap = profile['heaps'][space];
+ return '${ObservatoryApplication.timeUnits(heap['time'])} secs';
}
}

Powered by Google App Engine
This is Rietveld 408576698