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

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

Issue 443713004: Rename vmservice/client to vmservice/observatory to match package name. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 years, 4 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
(Empty)
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
3 // BSD-style license that can be found in the LICENSE file.
4
5 library heap_profile_element;
6
7 import 'dart:html';
8 import 'observatory_element.dart';
9 import 'package:observatory/app.dart';
10 import 'package:observatory/service.dart';
11 import 'package:observatory/elements.dart';
12 import 'package:polymer/polymer.dart';
13
14 class ClassSortedTable extends SortedTable {
15
16 ClassSortedTable(columns) : super(columns);
17
18 @override
19 dynamic getSortKeyFor(int row, int col) {
20 if (col == 0) {
21 // Use class name as sort key.
22 return rows[row].values[col].name;
23 }
24 return super.getSortKeyFor(row, col);
25 }
26 }
27
28 /// Displays an Error response.
29 @CustomTag('heap-profile')
30 class HeapProfileElement extends ObservatoryElement {
31 @observable String lastServiceGC = '---';
32 @observable String lastAccumulatorReset = '---';
33
34 // Pie chart of new space usage.
35 var _newPieDataTable;
36 var _newPieChart;
37
38 // Pie chart of old space usage.
39 var _oldPieDataTable;
40 var _oldPieChart;
41
42 @observable ClassSortedTable classTable;
43 var _classTableBody;
44
45 @published ServiceMap profile;
46
47 @observable Isolate isolate;
48
49 HeapProfileElement.created() : super.created() {
50 // Create pie chart models.
51 _newPieDataTable = new DataTable();
52 _newPieDataTable.addColumn('string', 'Type');
53 _newPieDataTable.addColumn('number', 'Size');
54 _oldPieDataTable = new DataTable();
55 _oldPieDataTable.addColumn('string', 'Type');
56 _oldPieDataTable.addColumn('number', 'Size');
57
58 // Create class table model.
59 var columns = [
60 new SortedTableColumn('Class'),
61 new SortedTableColumn(''), // Spacer column.
62 new SortedTableColumn.withFormatter('Accumulated Size (New)',
63 Utils.formatSize),
64 new SortedTableColumn.withFormatter('Accumulated Instances',
65 Utils.formatCommaSeparated),
66 new SortedTableColumn.withFormatter('Current Size',
67 Utils.formatSize),
68 new SortedTableColumn.withFormatter('Current Instances',
69 Utils.formatCommaSeparated),
70 new SortedTableColumn(''), // Spacer column.
71 new SortedTableColumn.withFormatter('Accumulator Size (Old)',
72 Utils.formatSize),
73 new SortedTableColumn.withFormatter('Accumulator Instances',
74 Utils.formatCommaSeparated),
75 new SortedTableColumn.withFormatter('Current Size',
76 Utils.formatSize),
77 new SortedTableColumn.withFormatter('Current Instances',
78 Utils.formatCommaSeparated)
79 ];
80 classTable = new ClassSortedTable(columns);
81 // By default, start with accumulated new space bytes.
82 classTable.sortColumnIndex = 2;
83 }
84
85 @override
86 void attached() {
87 super.attached();
88 // Grab the pie chart divs.
89 _newPieChart = new Chart('PieChart',
90 shadowRoot.querySelector('#newPieChart'));
91 _oldPieChart = new Chart('PieChart',
92 shadowRoot.querySelector('#oldPieChart'));
93 _classTableBody = shadowRoot.querySelector('#classTableBody');
94 }
95
96 void _updatePieCharts() {
97 assert(profile != null);
98 _newPieDataTable.clearRows();
99 var isolate = profile.isolate;
100 _newPieDataTable.addRow(['Used', isolate.newSpace.used]);
101 _newPieDataTable.addRow(['Free',
102 isolate.newSpace.capacity - isolate.newSpace.used]);
103 _newPieDataTable.addRow(['External', isolate.newSpace.external]);
104 _oldPieDataTable.clearRows();
105 _oldPieDataTable.addRow(['Used', isolate.oldSpace.used]);
106 _oldPieDataTable.addRow(['Free',
107 isolate.oldSpace.capacity - isolate.oldSpace.used]);
108 _oldPieDataTable.addRow(['External', isolate.oldSpace.external]);
109 }
110
111 void _updateClasses() {
112 for (ServiceMap clsAllocations in profile['members']) {
113 Class cls = clsAllocations['class'];
114 if (cls == null) {
115 continue;
116 }
117 cls.newSpace.update(clsAllocations['new']);
118 cls.oldSpace.update(clsAllocations['old']);
119 }
120 }
121
122 void _updateClassTable() {
123 classTable.clearRows();
124 for (ServiceMap clsAllocations in profile['members']) {
125 Class cls = clsAllocations['class'];
126 if (cls == null) {
127 continue;
128 }
129 if (cls.hasNoAllocations) {
130 // If a class has no allocations, don't display it.
131 continue;
132 }
133 var row = [cls,
134 '', // Spacer column.
135 cls.newSpace.accumulated.bytes,
136 cls.newSpace.accumulated.instances,
137 cls.newSpace.current.bytes,
138 cls.newSpace.current.instances,
139 '', // Spacer column.
140 cls.oldSpace.accumulated.bytes,
141 cls.oldSpace.accumulated.instances,
142 cls.oldSpace.current.bytes,
143 cls.oldSpace.current.instances];
144 classTable.addRow(new SortedTableRow(row));
145 }
146 classTable.sort();
147 }
148
149 void _addClassTableDomRow() {
150 assert(_classTableBody != null);
151 var tr = new TableRowElement();
152
153 // Add class ref.
154 var cell = tr.insertCell(-1);
155 ClassRefElement classRef = new Element.tag('class-ref');
156 cell.children.add(classRef);
157
158 // Add spacer.
159 cell = tr.insertCell(-1);
160 cell.classes.add('left-border-spacer');
161
162 // Add new space.
163 cell = tr.insertCell(-1);
164 cell = tr.insertCell(-1);
165 cell = tr.insertCell(-1);
166 cell = tr.insertCell(-1);
167
168 // Add spacer.
169 cell = tr.insertCell(-1);
170 cell.classes.add('left-border-spacer');
171
172 // Add old space.
173 cell = tr.insertCell(-1);
174 cell = tr.insertCell(-1);
175 cell = tr.insertCell(-1);
176 cell = tr.insertCell(-1);
177
178 // Add row to table.
179 _classTableBody.children.add(tr);
180 }
181
182 void _fillClassTableDomRow(TableRowElement tr, int rowIndex) {
183 const SPACER_COLUMNS = const [1, 6];
184
185 var row = classTable.rows[rowIndex];
186 // Add class ref.
187 ClassRefElement classRef = tr.children[0].children[0];
188 classRef.ref = row.values[0];
189
190 for (var i = 1; i < row.values.length; i++) {
191 if (SPACER_COLUMNS.contains(i)) {
192 // Skip spacer columns.
193 continue;
194 }
195 var cell = tr.children[i];
196 cell.title = row.values[i].toString();
197 cell.text = classTable.getFormattedValue(rowIndex, i);
198 }
199 }
200
201 void _updateClassTableInDom() {
202 assert(_classTableBody != null);
203 // Resize DOM table.
204 if (_classTableBody.children.length > classTable.sortedRows.length) {
205 // Shrink the table.
206 var deadRows =
207 _classTableBody.children.length - classTable.sortedRows.length;
208 for (var i = 0; i < deadRows; i++) {
209 _classTableBody.children.removeLast();
210 }
211 } else if (_classTableBody.children.length < classTable.sortedRows.length) {
212 // Grow table.
213 var newRows =
214 classTable.sortedRows.length - _classTableBody.children.length;
215 for (var i = 0; i < newRows; i++) {
216 _addClassTableDomRow();
217 }
218 }
219 assert(_classTableBody.children.length == classTable.sortedRows.length);
220 // Fill table.
221 for (var i = 0; i < classTable.sortedRows.length; i++) {
222 var rowIndex = classTable.sortedRows[i];
223 var tr = _classTableBody.children[i];
224 _fillClassTableDomRow(tr, rowIndex);
225 }
226 }
227
228 void _drawCharts() {
229 _newPieChart.draw(_newPieDataTable);
230 _oldPieChart.draw(_oldPieDataTable);
231 }
232
233 @observable void changeSort(Event e, var detail, Element target) {
234 if (target is TableCellElement) {
235 if (classTable.sortColumnIndex != target.cellIndex) {
236 classTable.sortColumnIndex = target.cellIndex;
237 classTable.sortDescending = true;
238 } else {
239 classTable.sortDescending = !classTable.sortDescending;
240 }
241 classTable.sort();
242 _updateClassTableInDom();
243 }
244 }
245
246 void refresh(var done) {
247 if (profile == null) {
248 return;
249 }
250 var isolate = profile.isolate;
251 isolate.get('/allocationprofile').then(_update).whenComplete(done);
252 }
253
254 void refreshGC(var done) {
255 if (profile == null) {
256 return;
257 }
258 var isolate = profile.isolate;
259 isolate.get('/allocationprofile?gc=full').then(_update).whenComplete(done);
260 }
261
262 void resetAccumulator(var done) {
263 if (profile == null) {
264 return;
265 }
266 var isolate = profile.isolate;
267 isolate.get('/allocationprofile?reset=true').then(_update).
268 whenComplete(done);
269 }
270
271 void _update(ServiceMap newProfile) {
272 profile = newProfile;
273 }
274
275 void profileChanged(oldValue) {
276 if (profile == null) {
277 return;
278 }
279 isolate = profile.isolate;
280 isolate.updateHeapsFromMap(profile['heaps']);
281 var millis = int.parse(profile['dateLastAccumulatorReset']);
282 if (millis != 0) {
283 lastAccumulatorReset =
284 new DateTime.fromMillisecondsSinceEpoch(millis).toString();
285 }
286 millis = int.parse(profile['dateLastServiceGC']);
287 if (millis != 0) {
288 lastServiceGC =
289 new DateTime.fromMillisecondsSinceEpoch(millis).toString();
290 }
291 _updatePieCharts();
292 _updateClasses();
293 _updateClassTable();
294 _updateClassTableInDom();
295 _drawCharts();
296 notifyPropertyChange(#formattedAverage, 0, 1);
297 notifyPropertyChange(#formattedTotalCollectionTime, 0, 1);
298 notifyPropertyChange(#formattedCollections, 0, 1);
299 }
300
301 @observable String formattedAverage(bool newSpace) {
302 if (profile == null) {
303 return '';
304 }
305 var heap = newSpace ? profile.isolate.newSpace : profile.isolate.oldSpace;
306 var avg = ((heap.totalCollectionTimeInSeconds * 1000.0) / heap.collections);
307 return '${avg.toStringAsFixed(2)} ms';
308 }
309
310 @observable String formattedCollections(bool newSpace) {
311 if (profile == null) {
312 return '';
313 }
314 var heap = newSpace ? profile.isolate.newSpace : profile.isolate.oldSpace;
315 return heap.collections.toString();
316 }
317
318 @observable String formattedTotalCollectionTime(bool newSpace) {
319 if (profile == null) {
320 return '';
321 }
322 var heap = newSpace ? profile.isolate.newSpace : profile.isolate.oldSpace;
323 return '${Utils.formatSeconds(heap.totalCollectionTimeInSeconds)} secs';
324 }
325 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698