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

Side by Side Diff: runtime/bin/vmservice/client/lib/src/elements/heap_profile.dart

Issue 237683004: Disable applyAuthorStyles (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 8 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 'observatory_element.dart'; 8 import 'observatory_element.dart';
9 import 'package:observatory/app.dart';
9 import 'package:observatory/service.dart'; 10 import 'package:observatory/service.dart';
10 import 'package:logging/logging.dart'; 11 import 'package:logging/logging.dart';
11 import 'package:polymer/polymer.dart'; 12 import 'package:polymer/polymer.dart';
12 import 'package:observatory/app.dart';
13 13
14 /// Displays an Error response. 14 /// Displays an Error response.
15 @CustomTag('heap-profile') 15 @CustomTag('heap-profile')
16 class HeapProfileElement extends ObservatoryElement { 16 class HeapProfileElement extends ObservatoryElement {
17 // Indexes into VM provided map. 17 // Indexes into VM provided map.
18 static const ALLOCATED_BEFORE_GC = 0; 18 static const ALLOCATED_BEFORE_GC = 0;
19 static const ALLOCATED_BEFORE_GC_SIZE = 1; 19 static const ALLOCATED_BEFORE_GC_SIZE = 1;
20 static const LIVE_AFTER_GC = 2; 20 static const LIVE_AFTER_GC = 2;
21 static const LIVE_AFTER_GC_SIZE = 3; 21 static const LIVE_AFTER_GC_SIZE = 3;
22 static const ALLOCATED_SINCE_GC = 4; 22 static const ALLOCATED_SINCE_GC = 4;
23 static const ALLOCATED_SINCE_GC_SIZE = 5; 23 static const ALLOCATED_SINCE_GC_SIZE = 5;
24 static const ACCUMULATED = 6; 24 static const ACCUMULATED = 6;
25 static const ACCUMULATED_SIZE = 7; 25 static const ACCUMULATED_SIZE = 7;
26 26
27 // Pie chart of new space usage. 27 // Pie chart of new space usage.
28 var _newPieDataTable; 28 var _newPieDataTable;
29 var _newPieChart; 29 var _newPieChart;
30 30
31 // Pie chart of old space usage. 31 // Pie chart of old space usage.
32 var _oldPieDataTable; 32 var _oldPieDataTable;
33 var _oldPieChart; 33 var _oldPieChart;
34 34
35 // The combined chart has old and new space merged. 35 @observable SortedTable classTable;
36 var _combinedDataTable;
37 var _combinedChart;
38
39 // The full chart has separate columns for new and old space.
40 var _fullDataTable;
41 var _fullChart;
42 36
43 @published ServiceMap profile; 37 @published ServiceMap profile;
44 38
45 HeapProfileElement.created() : super.created() { 39 HeapProfileElement.created() : super.created() {
46 _fullDataTable = new DataTable();
47 _fullDataTable.addColumn('string', 'Class');
48 _fullDataTable.addColumn('number', 'Current (new)');
49 _fullDataTable.addColumn('number', 'Allocated Since GC (new)');
50 _fullDataTable.addColumn('number', 'Total before GC (new)');
51 _fullDataTable.addColumn('number', 'Survivors (new)');
52 _fullDataTable.addColumn('number', 'Current (old)');
53 _fullDataTable.addColumn('number', 'Allocated Since GC (old)');
54 _fullDataTable.addColumn('number', 'Total before GC (old)');
55 _fullDataTable.addColumn('number', 'Survivors (old)');
56 _newPieDataTable = new DataTable(); 40 _newPieDataTable = new DataTable();
57 _newPieDataTable.addColumn('string', 'Type'); 41 _newPieDataTable.addColumn('string', 'Type');
58 _newPieDataTable.addColumn('number', 'Size'); 42 _newPieDataTable.addColumn('number', 'Size');
59 _oldPieDataTable = new DataTable(); 43 _oldPieDataTable = new DataTable();
60 _oldPieDataTable.addColumn('string', 'Type'); 44 _oldPieDataTable.addColumn('string', 'Type');
61 _oldPieDataTable.addColumn('number', 'Size'); 45 _oldPieDataTable.addColumn('number', 'Size');
62 _combinedDataTable = new DataTable(); 46 var columns = [
63 _combinedDataTable.addColumn('string', 'Class'); 47 new SortedTableColumn('Class'),
64 _combinedDataTable.addColumn('number', 'Accumulator'); 48 new SortedTableColumn.withFormatter('Accumulator Size',
65 _combinedDataTable.addColumn('number', 'Accumulator Instances'); 49 Utils.formatSize),
66 _combinedDataTable.addColumn('number', 'Current'); 50 new SortedTableColumn.withFormatter('Accumulator Instances',
67 _combinedDataTable.addColumn('number', 'Allocated Since GC'); 51 Utils.formatCommaSeperated),
68 _combinedDataTable.addColumn('number', 'Total before GC'); 52 new SortedTableColumn.withFormatter('Current Size',
69 _combinedDataTable.addColumn('number', 'Survivors after GC'); 53 Utils.formatSize),
54 new SortedTableColumn.withFormatter('Current Instances',
55 Utils.formatCommaSeperated)
56 ];
57 classTable = new SortedTable(columns);
58 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.
70 } 59 }
71 60
72 void enteredView() { 61 void enteredView() {
73 super.enteredView(); 62 super.enteredView();
74 _fullChart = new Chart('Table',
75 shadowRoot.querySelector('#table'));
76 _fullChart.options['allowHtml'] = true;
77 _fullChart.options['sortColumn'] = 1;
78 _fullChart.options['sortAscending'] = false;
79 _newPieChart = new Chart('PieChart', 63 _newPieChart = new Chart('PieChart',
80 shadowRoot.querySelector('#newPieChart')); 64 shadowRoot.querySelector('#newPieChart'));
81 _newPieChart.options['title'] = 'New Space'; 65 _newPieChart.options['title'] = 'New Space';
82 _oldPieChart = new Chart('PieChart', 66 _oldPieChart = new Chart('PieChart',
83 shadowRoot.querySelector('#oldPieChart')); 67 shadowRoot.querySelector('#oldPieChart'));
84 _oldPieChart.options['title'] = 'Old Space'; 68 _oldPieChart.options['title'] = 'Old Space';
85 _combinedChart = new Chart('Table',
86 shadowRoot.querySelector('#simpleTable'));
87 _combinedChart.options['allowHtml'] = true;
88 _combinedChart.options['sortColumn'] = 1;
89 _combinedChart.options['sortAscending'] = false;
90 _draw(); 69 _draw();
91 } 70 }
92 71
93 bool _first = true;
94
95 void _updateChartData() { 72 void _updateChartData() {
96 if ((profile == null) || (profile['members'] is! List) || 73 if ((profile == null) || (profile['members'] is! List) ||
97 (profile['members'].length == 0)) { 74 (profile['members'].length == 0)) {
98 return; 75 return;
99 } 76 }
100 assert(_fullDataTable != null); 77 assert(classTable != null);
101 assert(_combinedDataTable != null); 78 classTable.clearRows();
102 _fullDataTable.clearRows();
103 _combinedDataTable.clearRows();
104 for (ServiceMap cls in profile['members']) { 79 for (ServiceMap cls in profile['members']) {
105 if (_classHasNoAllocations(cls)) { 80 if (_classHasNoAllocations(cls)) {
106 // If a class has no allocations, don't display it. 81 // If a class has no allocations, don't display it.
107 continue; 82 continue;
108 } 83 }
109 var vm_name = cls['class']['name']; 84 var row = [cls['class'],
110 var url = cls['class'].hashLink; 85 _combinedTableColumnValue(cls, 1),
111 _fullDataTable.addRow([ 86 _combinedTableColumnValue(cls, 2),
112 '<a title="$vm_name" href="$url">' 87 _combinedTableColumnValue(cls, 3),
113 '${_fullTableColumnValue(cls, 0)}</a>', 88 _combinedTableColumnValue(cls, 4)];
114 _fullTableColumnValue(cls, 1), 89 classTable.addRow(new SortedTableRow(row));
115 _fullTableColumnValue(cls, 2),
116 _fullTableColumnValue(cls, 3),
117 _fullTableColumnValue(cls, 4),
118 _fullTableColumnValue(cls, 5),
119 _fullTableColumnValue(cls, 6),
120 _fullTableColumnValue(cls, 7),
121 _fullTableColumnValue(cls, 8)]);
122 _combinedDataTable.addRow([
123 '<a title="$vm_name" href="$url">'
124 '${_combinedTableColumnValue(cls, 0)}</a>',
125 _combinedTableColumnValue(cls, 1),
126 _combinedTableColumnValue(cls, 2),
127 _combinedTableColumnValue(cls, 3),
128 _combinedTableColumnValue(cls, 4),
129 _combinedTableColumnValue(cls, 5),
130 _combinedTableColumnValue(cls, 6)]);
131 } 90 }
91 classTable.sort();
132 _newPieDataTable.clearRows(); 92 _newPieDataTable.clearRows();
133 var heap = profile['heaps']['new']; 93 var heap = profile['heaps']['new'];
134 _newPieDataTable.addRow(['Used', heap['used']]); 94 _newPieDataTable.addRow(['Used', heap['used']]);
135 _newPieDataTable.addRow(['Free', heap['capacity'] - heap['used']]); 95 _newPieDataTable.addRow(['Free', heap['capacity'] - heap['used']]);
136 _newPieDataTable.addRow(['External', heap['external']]); 96 _newPieDataTable.addRow(['External', heap['external']]);
137 _oldPieDataTable.clearRows(); 97 _oldPieDataTable.clearRows();
138 heap = profile['heaps']['old']; 98 heap = profile['heaps']['old'];
139 _oldPieDataTable.addRow(['Used', heap['used']]); 99 _oldPieDataTable.addRow(['Used', heap['used']]);
140 _oldPieDataTable.addRow(['Free', heap['capacity'] - heap['used']]); 100 _oldPieDataTable.addRow(['Free', heap['capacity'] - heap['used']]);
141 _oldPieDataTable.addRow(['External', heap['external']]); 101 _oldPieDataTable.addRow(['External', heap['external']]);
142 _draw(); 102 _draw();
143 } 103 }
144 104
145 void _draw() { 105 void _draw() {
146 if ((_fullChart == null) || (_combinedChart == null)) { 106 if (_newPieChart == null) {
147 return; 107 return;
148 } 108 }
149 _combinedChart.refreshOptionsSortInfo();
150 _combinedChart.draw(_combinedDataTable);
151 _fullChart.refreshOptionsSortInfo();
152 _fullChart.draw(_fullDataTable);
153 _newPieChart.draw(_newPieDataTable); 109 _newPieChart.draw(_newPieDataTable);
154 _oldPieChart.draw(_oldPieDataTable); 110 _oldPieChart.draw(_oldPieDataTable);
155 } 111 }
156 112
113 @observable void changeSort(Event e, var detail, Element target) {
114 if (target is TableCellElement) {
115 if (classTable.sortColumnIndex != target.cellIndex) {
116 classTable.sortColumnIndex = target.cellIndex;
117 classTable.sort();
118 }
119 }
120 }
121
157 bool _classHasNoAllocations(Map v) { 122 bool _classHasNoAllocations(Map v) {
158 var newSpace = v['new']; 123 var newSpace = v['new'];
159 var oldSpace = v['old']; 124 var oldSpace = v['old'];
160 for (var allocation in newSpace) { 125 for (var allocation in newSpace) {
161 if (allocation != 0) { 126 if (allocation != 0) {
162 return false; 127 return false;
163 } 128 }
164 } 129 }
165 for (var allocation in oldSpace) { 130 for (var allocation in oldSpace) {
166 if (allocation != 0) { 131 if (allocation != 0) {
167 return false; 132 return false;
168 } 133 }
169 } 134 }
170 return true; 135 return true;
171 } 136 }
172 137
173 dynamic _fullTableColumnValue(Map v, int index) {
174 assert(index >= 0);
175 assert(index < 9);
176 switch (index) {
177 case 0:
178 return v['class']['user_name'];
179 case 1:
180 return v['new'][LIVE_AFTER_GC_SIZE] + v['new'][ALLOCATED_SINCE_GC_SIZE];
181 case 2:
182 return v['new'][ALLOCATED_SINCE_GC_SIZE];
183 case 3:
184 return v['new'][ALLOCATED_BEFORE_GC_SIZE];
185 case 4:
186 return v['new'][LIVE_AFTER_GC_SIZE];
187 case 5:
188 return v['old'][LIVE_AFTER_GC_SIZE] + v['old'][ALLOCATED_SINCE_GC_SIZE];
189 case 6:
190 return v['old'][ALLOCATED_SINCE_GC_SIZE];
191 case 7:
192 return v['old'][ALLOCATED_BEFORE_GC_SIZE];
193 case 8:
194 return v['old'][LIVE_AFTER_GC_SIZE];
195 }
196 throw new FallThroughError();
197 }
198
199 dynamic _combinedTableColumnValue(Map v, int index) { 138 dynamic _combinedTableColumnValue(Map v, int index) {
200 assert(index >= 0); 139 assert(index >= 0);
201 assert(index < 7); 140 assert(index < 7);
202 switch (index) { 141 switch (index) {
203 case 0: 142 case 0:
204 return v['class']['user_name']; 143 return v['class']['user_name'];
205 case 1: 144 case 1:
206 return v['new'][ACCUMULATED_SIZE] + 145 return v['new'][ACCUMULATED_SIZE] +
207 v['old'][ACCUMULATED_SIZE]; 146 v['old'][ACCUMULATED_SIZE];
208 case 2: 147 case 2:
209 return v['new'][ACCUMULATED] + 148 return v['new'][ACCUMULATED] +
210 v['old'][ACCUMULATED]; 149 v['old'][ACCUMULATED];
211 case 3: 150 case 3:
212 return v['new'][LIVE_AFTER_GC_SIZE] + 151 return v['new'][LIVE_AFTER_GC_SIZE] +
213 v['new'][ALLOCATED_SINCE_GC_SIZE] + 152 v['new'][ALLOCATED_SINCE_GC_SIZE] +
214 v['old'][LIVE_AFTER_GC_SIZE] + 153 v['old'][LIVE_AFTER_GC_SIZE] +
215 v['old'][ALLOCATED_SINCE_GC_SIZE]; 154 v['old'][ALLOCATED_SINCE_GC_SIZE];
216 case 4: 155 case 4:
217 return v['new'][ALLOCATED_SINCE_GC_SIZE] + 156 return v['new'][LIVE_AFTER_GC] +
218 v['old'][ALLOCATED_SINCE_GC_SIZE]; 157 v['new'][ALLOCATED_SINCE_GC] +
219 case 5: 158 v['old'][LIVE_AFTER_GC] +
220 return v['new'][ALLOCATED_BEFORE_GC_SIZE] + 159 v['old'][ALLOCATED_SINCE_GC];
221 v['old'][ALLOCATED_BEFORE_GC_SIZE];
222 case 6:
223 return v['new'][LIVE_AFTER_GC_SIZE] + v['old'][LIVE_AFTER_GC_SIZE];
224 } 160 }
225 throw new FallThroughError(); 161 throw new FallThroughError();
226 } 162 }
227 163
228 void refresh(var done) { 164 void refresh(var done) {
229 if (profile == null) { 165 if (profile == null) {
230 return; 166 return;
231 } 167 }
232 profile.isolate.get('/allocationprofile').then((ServiceMap response) { 168 profile.isolate.get('/allocationprofile').then((ServiceMap response) {
233 assert(response['type'] == 'AllocationProfile'); 169 assert(response['type'] == 'AllocationProfile');
234 profile = response; 170 profile = response;
235 }).catchError((e, st) { 171 }).catchError((e, st) {
236 Logger.root.info('$e $st'); 172 Logger.root.info('$e $st');
237 }).whenComplete(done); 173 }).whenComplete(done);
238 } 174 }
239 175
240 void resetAccumulator(Event e, var detail, Node target) { 176 void resetAccumulator(var done) {
241 if (profile == null) { 177 if (profile == null) {
242 return; 178 return;
243 } 179 }
244 var isolate = profile.isolate; 180 var isolate = profile.isolate;
245 isolate.get('/allocationprofile?reset=true').then((ServiceMap response) { 181 isolate.get('/allocationprofile?reset=true').then((ServiceMap response) {
246 assert(response['type'] == 'AllocationProfile'); 182 assert(response['type'] == 'AllocationProfile');
247 profile = response; 183 profile = response;
248 }).catchError((e, st) { 184 }).catchError((e, st) {
249 Logger.root.info('$e $st'); 185 Logger.root.info('$e $st');
250 }); 186 }).whenComplete(done);
251 } 187 }
252 188
253 void profileChanged(oldValue) { 189 void profileChanged(oldValue) {
254 _updateChartData(); 190 try {
191 _updateChartData();
192 } catch (e, st) {
193 Logger.root.info('$e $st');
194 }
255 notifyPropertyChange(#formattedAverage, [], formattedAverage); 195 notifyPropertyChange(#formattedAverage, [], formattedAverage);
256 notifyPropertyChange(#formattedTotalCollectionTime, [], 196 notifyPropertyChange(#formattedTotalCollectionTime, [],
257 formattedTotalCollectionTime); 197 formattedTotalCollectionTime);
258 notifyPropertyChange(#formattedCollections, [], formattedCollections); 198 notifyPropertyChange(#formattedCollections, [], formattedCollections);
259 } 199 }
260 200
261 @observable String formattedAverage(bool newSpace) { 201 @observable String formattedAverage(bool newSpace) {
262 if (profile == null) { 202 if (profile == null) {
263 return ''; 203 return '';
264 } 204 }
(...skipping 11 matching lines...) Expand all
276 Map heap = profile['heaps'][space]; 216 Map heap = profile['heaps'][space];
277 return '${heap['collections']}'; 217 return '${heap['collections']}';
278 } 218 }
279 219
280 @observable String formattedTotalCollectionTime(bool newSpace) { 220 @observable String formattedTotalCollectionTime(bool newSpace) {
281 if (profile == null) { 221 if (profile == null) {
282 return ''; 222 return '';
283 } 223 }
284 String space = newSpace ? 'new' : 'old'; 224 String space = newSpace ? 'new' : 'old';
285 Map heap = profile['heaps'][space]; 225 Map heap = profile['heaps'][space];
286 return '${formatSeconds(heap['time'])} secs'; 226 return '${Utils.formatSeconds(heap['time'])} secs';
287 } 227 }
288 } 228 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698