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

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

Issue 196173022: Fix PrintToJSONStream for oddball functions (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 9 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_map_element; 5 library heap_map_element;
6 6
7 import 'dart:async'; 7 import 'dart:async';
8 import 'dart:html'; 8 import 'dart:html';
9 import 'dart:math'; 9 import 'dart:math';
10 import 'observatory_element.dart'; 10 import 'observatory_element.dart';
11 import 'package:observatory/service.dart'; 11 import 'package:observatory/service.dart';
12 import 'package:logging/logging.dart'; 12 import 'package:logging/logging.dart';
13 import 'package:polymer/polymer.dart'; 13 import 'package:polymer/polymer.dart';
14 import 'package:observatory/app.dart';
15 14
16 // A reference to a particular pixel of ImageData. 15 // A reference to a particular pixel of ImageData.
17 class PixelReference { 16 class PixelReference {
18 final _data; 17 final _data;
19 var _dataIndex; 18 var _dataIndex;
20 static const NUM_COLOR_COMPONENTS = 4; 19 static const NUM_COLOR_COMPONENTS = 4;
21 20
22 PixelReference(ImageData data, Point<int> point) 21 PixelReference(ImageData data, Point<int> point)
23 : _data = data, 22 : _data = data,
24 _dataIndex = (point.y * data.width + point.x) * NUM_COLOR_COMPONENTS; 23 _dataIndex = (point.y * data.width + point.x) * NUM_COLOR_COMPONENTS;
25 24
26 PixelReference._fromDataIndex(this._data, this._dataIndex); 25 PixelReference._fromDataIndex(this._data, this._dataIndex);
27 26
28 Point<int> get point => 27 Point<int> get point =>
29 new Point(index % _data.width, index ~/ _data.width); 28 new Point(index % _data.width, index ~/ _data.width);
30 29
31 void set color(Iterable<int> color) { 30 void set color(Iterable<int> color) {
32 _data.data.setRange( 31 _data.data.setRange(
33 _dataIndex, _dataIndex + NUM_COLOR_COMPONENTS, color); 32 _dataIndex, _dataIndex + NUM_COLOR_COMPONENTS, color);
34 } 33 }
35 34
36 Iterable<int> get color => 35 Iterable<int> get color =>
37 _data.data.getRange(_dataIndex, _dataIndex + NUM_COLOR_COMPONENTS); 36 _data.data.getRange(_dataIndex, _dataIndex + NUM_COLOR_COMPONENTS);
38 37
39 // Returns the next pixel in row-major order. 38 // Returns the next pixel in row-major order.
40 PixelReference next() => new PixelReference._fromDataIndex( 39 PixelReference next() => new PixelReference._fromDataIndex(
41 _data, _dataIndex + NUM_COLOR_COMPONENTS); 40 _data, _dataIndex + NUM_COLOR_COMPONENTS);
42 41
43 // The row-major index of this pixel. 42 // The row-major index of this pixel.
44 int get index => _dataIndex ~/ NUM_COLOR_COMPONENTS; 43 int get index => _dataIndex ~/ NUM_COLOR_COMPONENTS;
45 } 44 }
46 45
47 @CustomTag('heap-map') 46 @CustomTag('heap-map')
48 class HeapMapElement extends ObservatoryElement { 47 class HeapMapElement extends ObservatoryElement {
49 var _fragmentationCanvas; 48 var _fragmentationCanvas;
50 var _fragmentationData; 49 var _fragmentationData;
51 var _pageHeight; 50 var _pageHeight;
52 var _classIdToColor = {}; 51 var _classIdToColor = {};
53 var _colorToClassId = {}; 52 var _colorToClassId = {};
54 var _classIdToName = {}; 53 var _classIdToName = {};
55 54
56 static final _freeColor = [255, 255, 255, 255]; 55 static final _freeColor = [255, 255, 255, 255];
57 static final _pageSeparationColor = [0, 0, 0, 255]; 56 static final _pageSeparationColor = [0, 0, 0, 255];
58 static const _PAGE_SEPARATION_HEIGHT = 4; 57 static const _PAGE_SEPARATION_HEIGHT = 4;
59 58
60 @observable String status; 59 @observable String status;
61 @published ServiceMap fragmentation; 60 @published ServiceMap fragmentation;
62 61
63 HeapMapElement.created() : super.created() { 62 HeapMapElement.created() : super.created() {
64 } 63 }
65 64
66 void enteredView() { 65 void enteredView() {
67 super.enteredView(); 66 super.enteredView();
68 _fragmentationCanvas = shadowRoot.querySelector("#fragmentation"); 67 _fragmentationCanvas = shadowRoot.querySelector("#fragmentation");
69 _fragmentationCanvas.onMouseMove.listen(_handleMouseMove); 68 _fragmentationCanvas.onMouseMove.listen(_handleMouseMove);
70 } 69 }
71 70
72 // Encode color as single integer, to enable using it as a map key. 71 // Encode color as single integer, to enable using it as a map key.
73 int _packColor(Iterable<int> color) { 72 int _packColor(Iterable<int> color) {
74 int packed = 0; 73 int packed = 0;
75 for (var component in color) { 74 for (var component in color) {
76 packed = packed * 256 + component; 75 packed = packed * 256 + component;
77 } 76 }
78 return packed; 77 return packed;
79 } 78 }
80 79
81 void _addClass(int classId, String name, Iterable<int> color) { 80 void _addClass(int classId, String name, Iterable<int> color) {
82 _classIdToName[classId] = name; 81 _classIdToName[classId] = name;
83 _classIdToColor[classId] = color; 82 _classIdToColor[classId] = color;
84 _colorToClassId[_packColor(color)] = classId; 83 _colorToClassId[_packColor(color)] = classId;
85 } 84 }
86 85
87 void _updateClassList(classList, int freeClassId) { 86 void _updateClassList(classList, int freeClassId) {
88 for (var member in classList['members']) { 87 for (var member in classList['members']) {
89 if (member['type'] != '@Class') { 88 if (member['type'] != '@Class') {
90 Logger.root.info('$member'); 89 Logger.root.info('$member');
91 continue; 90 continue;
92 } 91 }
93 var classId = int.parse(member['id'].split('/').last); 92 var classId = int.parse(member['id'].split('/').last);
94 var color = _classIdToRGBA(classId); 93 var color = _classIdToRGBA(classId);
95 _addClass(classId, member['user_name'], color); 94 _addClass(classId, member['user_name'], color);
96 } 95 }
97 _addClass(freeClassId, 'Free', _freeColor); 96 _addClass(freeClassId, 'Free', _freeColor);
98 _addClass(0, '', _pageSeparationColor); 97 _addClass(0, '', _pageSeparationColor);
99 } 98 }
100 99
101 Iterable<int> _classIdToRGBA(int classId) { 100 Iterable<int> _classIdToRGBA(int classId) {
102 // TODO(koda): Pick random hue, but fixed saturation and value. 101 // TODO(koda): Pick random hue, but fixed saturation and value.
103 var rng = new Random(classId); 102 var rng = new Random(classId);
104 return [rng.nextInt(128), rng.nextInt(128), rng.nextInt(128), 255]; 103 return [rng.nextInt(128), rng.nextInt(128), rng.nextInt(128), 255];
105 } 104 }
106 105
107 String _classNameAt(Point<int> point) { 106 String _classNameAt(Point<int> point) {
108 var color = new PixelReference(_fragmentationData, point).color; 107 var color = new PixelReference(_fragmentationData, point).color;
109 return _classIdToName[_colorToClassId[_packColor(color)]]; 108 return _classIdToName[_colorToClassId[_packColor(color)]];
110 } 109 }
111 110
112 // TODO(koda): Find start of object. 111 // TODO(koda): Find start of object.
113 int _addressAt(Point<int> point) { 112 int _addressAt(Point<int> point) {
114 var pagePixels = _pageHeight * _fragmentationData.width; 113 var pagePixels = _pageHeight * _fragmentationData.width;
115 var index = new PixelReference(_fragmentationData, point).index; 114 var index = new PixelReference(_fragmentationData, point).index;
116 var pageIndex = index ~/ pagePixels; 115 var pageIndex = index ~/ pagePixels;
117 var pageOffset = index % pagePixels; 116 var pageOffset = index % pagePixels;
118 var pages = fragmentation['pages']; 117 var pages = fragmentation['pages'];
119 if (0 <= pageIndex && pageIndex < pages.length) { 118 if (0 <= pageIndex && pageIndex < pages.length) {
120 return int.parse(pages[pageIndex]['object_start']) + 119 return int.parse(pages[pageIndex]['object_start']) +
121 pageOffset * fragmentation['unit_size_bytes']; 120 pageOffset * fragmentation['unit_size_bytes'];
122 } else { 121 } else {
123 return 0; 122 return 0;
124 } 123 }
125 } 124 }
126 125
127 void _handleMouseMove(MouseEvent event) { 126 void _handleMouseMove(MouseEvent event) {
128 var addressString = '@ 0x${_addressAt(event.offset).toRadixString(16)}'; 127 var addressString = '@ 0x${_addressAt(event.offset).toRadixString(16)}';
129 var className = _classNameAt(event.offset); 128 var className = _classNameAt(event.offset);
130 status = (className == '') ? '-' : '$className $addressString'; 129 status = (className == '') ? '-' : '$className $addressString';
131 } 130 }
132 131
133 void _updateFragmentationData() { 132 void _updateFragmentationData() {
134 if (fragmentation == null || _fragmentationCanvas == null) { 133 if (fragmentation == null || _fragmentationCanvas == null) {
135 return; 134 return;
136 } 135 }
137 _updateClassList( 136 _updateClassList(
138 fragmentation['class_list'], fragmentation['free_class_id']); 137 fragmentation['class_list'], fragmentation['free_class_id']);
139 var pages = fragmentation['pages']; 138 var pages = fragmentation['pages'];
140 var width = _fragmentationCanvas.parent.client.width; 139 var width = _fragmentationCanvas.parent.client.width;
141 _pageHeight = _PAGE_SEPARATION_HEIGHT + 140 _pageHeight = _PAGE_SEPARATION_HEIGHT +
142 fragmentation['page_size_bytes'] ~/ 141 fragmentation['page_size_bytes'] ~/
143 fragmentation['unit_size_bytes'] ~/ width; 142 fragmentation['unit_size_bytes'] ~/ width;
144 var height = _pageHeight * pages.length; 143 var height = _pageHeight * pages.length;
145 _fragmentationData = 144 _fragmentationData =
146 _fragmentationCanvas.context2D.createImageData(width, height); 145 _fragmentationCanvas.context2D.createImageData(width, height);
147 _fragmentationCanvas.width = _fragmentationData.width; 146 _fragmentationCanvas.width = _fragmentationData.width;
148 _fragmentationCanvas.height = _fragmentationData.height; 147 _fragmentationCanvas.height = _fragmentationData.height;
149 _renderPages(0); 148 _renderPages(0);
150 } 149 }
151 150
152 // Renders and draws asynchronously, one page at a time to avoid 151 // Renders and draws asynchronously, one page at a time to avoid
153 // blocking the UI. 152 // blocking the UI.
154 void _renderPages(int startPage) { 153 void _renderPages(int startPage) {
155 var pages = fragmentation['pages']; 154 var pages = fragmentation['pages'];
156 status = 'Loaded $startPage of ${pages.length} pages'; 155 status = 'Loaded $startPage of ${pages.length} pages';
157 if (startPage >= pages.length) { 156 if (startPage >= pages.length) {
158 return; 157 return;
159 } 158 }
160 var startY = startPage * _pageHeight; 159 var startY = startPage * _pageHeight;
161 var pixel = new PixelReference(_fragmentationData, new Point(0, startY)); 160 var pixel = new PixelReference(_fragmentationData, new Point(0, startY));
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
194 }).whenComplete(done); 193 }).whenComplete(done);
195 } 194 }
196 195
197 void fragmentationChanged(oldValue) { 196 void fragmentationChanged(oldValue) {
198 // Async, in case enteredView has not yet run (observed in JS version). 197 // Async, in case enteredView has not yet run (observed in JS version).
199 new Future(() { 198 new Future(() {
200 _updateFragmentationData(); 199 _updateFragmentationData();
201 }); 200 });
202 } 201 }
203 } 202 }
OLDNEW
« no previous file with comments | « runtime/bin/vmservice/client/lib/service.dart ('k') | runtime/bin/vmservice/client/lib/src/elements/vm_view.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698