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

Side by Side Diff: runtime/bin/vmservice/observatory/lib/src/service/object.dart

Issue 515303005: Allow observatory to distinguish between user-level and vm-level types. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: gen js, fix test Created 6 years, 3 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 part of service; 5 part of service;
6 6
7 /// A [ServiceObject] is an object known to the VM service and is tied 7 /// A [ServiceObject] is an object known to the VM service and is tied
8 /// to an owning [Isolate]. 8 /// to an owning [Isolate].
9 abstract class ServiceObject extends Observable { 9 abstract class ServiceObject extends Observable {
10 static int LexicalSortName(ServiceObject o1, ServiceObject o2) { 10 static int LexicalSortName(ServiceObject o1, ServiceObject o2) {
(...skipping 12 matching lines...) Expand all
23 /// The [VM] which owns this [ServiceObject]. 23 /// The [VM] which owns this [ServiceObject].
24 @reflectable VM get vm => _owner.vm; 24 @reflectable VM get vm => _owner.vm;
25 25
26 /// The [Isolate] which owns this [ServiceObject]. May be null. 26 /// The [Isolate] which owns this [ServiceObject]. May be null.
27 @reflectable Isolate get isolate => _owner.isolate; 27 @reflectable Isolate get isolate => _owner.isolate;
28 28
29 /// The id of this object. 29 /// The id of this object.
30 @reflectable String get id => _id; 30 @reflectable String get id => _id;
31 String _id; 31 String _id;
32 32
33 /// The service type of this object. 33 /// The user-level type of this object.
34 @reflectable String get serviceType => _serviceType; 34 @reflectable String get type => _type;
35 String _serviceType; 35 String _type;
36
37 /// The vm type of this object.
38 @reflectable String get vmType => _vmType;
39 String _vmType;
36 40
37 /// The complete service url of this object. 41 /// The complete service url of this object.
38 @reflectable String get link => _owner.relativeLink(_id); 42 @reflectable String get link => _owner.relativeLink(_id);
39 43
40 /// Has this object been fully loaded? 44 /// Has this object been fully loaded?
41 bool get loaded => _loaded; 45 bool get loaded => _loaded;
42 bool _loaded = false; 46 bool _loaded = false;
43 // TODO(turnidge): Make loaded observable and get rid of loading 47 // TODO(turnidge): Make loaded observable and get rid of loading
44 // from Isolate. 48 // from Isolate.
45 49
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
126 return reload(); 130 return reload();
127 } 131 }
128 132
129 Future<ServiceObject> _inProgressReload; 133 Future<ServiceObject> _inProgressReload;
130 134
131 /// Reload [this]. Returns a future which completes to [this] or 135 /// Reload [this]. Returns a future which completes to [this] or
132 /// a [ServiceError]. 136 /// a [ServiceError].
133 Future<ServiceObject> reload() { 137 Future<ServiceObject> reload() {
134 if (id == '') { 138 if (id == '') {
135 // Errors don't have ids. 139 // Errors don't have ids.
136 assert(serviceType == 'Error'); 140 assert(type == 'Error');
137 return new Future.value(this); 141 return new Future.value(this);
138 } 142 }
139 if (loaded && immutable) { 143 if (loaded && immutable) {
140 return new Future.value(this); 144 return new Future.value(this);
141 } 145 }
142 if (_inProgressReload == null) { 146 if (_inProgressReload == null) {
143 _inProgressReload = vm.getAsMap(link).then((ObservableMap map) { 147 _inProgressReload = vm.getAsMap(link).then((ObservableMap map) {
144 var mapType = _stripRef(map['type']); 148 var mapType = _stripRef(map['type']);
145 if (mapType != _serviceType) { 149 if (mapType != _type) {
146 // If the type changes, return a new object instead of 150 // If the type changes, return a new object instead of
147 // updating the existing one. 151 // updating the existing one.
152 //
153 // TODO(turnidge): Check for vmType changing as well?
148 assert(mapType == 'Error' || mapType == 'Null'); 154 assert(mapType == 'Error' || mapType == 'Null');
149 return new ServiceObject._fromMap(owner, map); 155 return new ServiceObject._fromMap(owner, map);
150 } 156 }
151 update(map); 157 update(map);
152 return this; 158 return this;
153 }).whenComplete(() { 159 }).whenComplete(() {
154 // This reload is complete. 160 // This reload is complete.
155 _inProgressReload = null; 161 _inProgressReload = null;
156 }); 162 });
157 } 163 }
158 return _inProgressReload; 164 return _inProgressReload;
159 } 165 }
160 166
161 /// Update [this] using [map] as a source. [map] can be a reference. 167 /// Update [this] using [map] as a source. [map] can be a reference.
162 void update(ObservableMap map) { 168 void update(ObservableMap map) {
163 assert(_isServiceMap(map)); 169 assert(_isServiceMap(map));
164 170
165 // Don't allow the type to change on an object update. 171 // Don't allow the type to change on an object update.
166 // TODO(turnidge): Make this a ServiceError? 172 // TODO(turnidge): Make this a ServiceError?
167 var mapIsRef = _hasRef(map['type']); 173 var mapIsRef = _hasRef(map['type']);
168 var mapType = _stripRef(map['type']); 174 var mapType = _stripRef(map['type']);
169 assert(_serviceType == null || _serviceType == mapType); 175 assert(_type == null || _type == mapType);
170 176
171 if (_id != null && _id != map['id']) { 177 if (_id != null && _id != map['id']) {
172 // It is only safe to change an id when the object isn't cacheable. 178 // It is only safe to change an id when the object isn't cacheable.
173 assert(!canCache); 179 assert(!canCache);
174 } 180 }
175 _id = map['id']; 181 _id = map['id'];
176 182
177 _serviceType = mapType; 183 _type = mapType;
184
185 // When the response specifies a specific vmType, use it.
186 // Otherwise the vmType of the response is the same as the 'user'
187 // type.
188 if (map.containsKey('vmType')) {
189 _vmType = _stripRef(map['vmType']);
190 } else {
191 _vmType = _type;
192 }
193
178 _update(map, mapIsRef); 194 _update(map, mapIsRef);
179 } 195 }
180 196
181 // Updates internal state from [map]. [map] can be a reference. 197 // Updates internal state from [map]. [map] can be a reference.
182 void _update(ObservableMap map, bool mapIsRef); 198 void _update(ObservableMap map, bool mapIsRef);
183 199
184 String relativeLink(String id) { 200 String relativeLink(String id) {
185 assert(id != null); 201 assert(id != null);
186 return "${link}/${id}"; 202 return "${link}/${id}";
187 } 203 }
188 } 204 }
189 205
190 abstract class Coverage { 206 abstract class Coverage {
191 // Following getters and functions will be provided by [ServiceObject]. 207 // Following getters and functions will be provided by [ServiceObject].
192 ServiceObjectOwner get owner; 208 ServiceObjectOwner get owner;
193 String get serviceType; 209 String get type;
194 VM get vm; 210 VM get vm;
195 String relativeLink(String id); 211 String relativeLink(String id);
196 212
197 /// Default handler for coverage data. 213 /// Default handler for coverage data.
198 void processCoverageData(List coverageData) { 214 void processCoverageData(List coverageData) {
199 coverageData.forEach((scriptCoverage) { 215 coverageData.forEach((scriptCoverage) {
200 assert(scriptCoverage['script'] != null); 216 assert(scriptCoverage['script'] != null);
201 scriptCoverage['script']._processHits(scriptCoverage['hits']); 217 scriptCoverage['script']._processHits(scriptCoverage['hits']);
202 }); 218 });
203 } 219 }
204 220
205 Future refreshCoverage() { 221 Future refreshCoverage() {
206 return vm.getAsMap(relativeLink('coverage')).then((ObservableMap map) { 222 return vm.getAsMap(relativeLink('coverage')).then((ObservableMap map) {
207 var coverageOwner = (serviceType == 'Isolate') ? this : owner; 223 var coverageOwner = (type == 'Isolate') ? this : owner;
208 var coverage = new ServiceObject._fromMap(coverageOwner, map); 224 var coverage = new ServiceObject._fromMap(coverageOwner, map);
209 assert(coverage.serviceType == 'CodeCoverage'); 225 assert(coverage.type == 'CodeCoverage');
210 var coverageList = coverage['coverage']; 226 var coverageList = coverage['coverage'];
211 assert(coverageList != null); 227 assert(coverageList != null);
212 processCoverageData(coverageList); 228 processCoverageData(coverageList);
213 }); 229 });
214 } 230 }
215 } 231 }
216 232
217 abstract class ServiceObjectOwner extends ServiceObject { 233 abstract class ServiceObjectOwner extends ServiceObject {
218 /// Creates an empty [ServiceObjectOwner]. 234 /// Creates an empty [ServiceObjectOwner].
219 ServiceObjectOwner._empty(ServiceObjectOwner owner) : super._empty(owner); 235 ServiceObjectOwner._empty(ServiceObjectOwner owner) : super._empty(owner);
(...skipping 404 matching lines...) Expand 10 before | Expand all | Expand 10 after
624 640
625 static const TAG_ROOT_ID = 'code/tag-0'; 641 static const TAG_ROOT_ID = 'code/tag-0';
626 642
627 /// Returns the Code object for the root tag. 643 /// Returns the Code object for the root tag.
628 Code tagRoot() { 644 Code tagRoot() {
629 // TODO(turnidge): Use get() here instead? 645 // TODO(turnidge): Use get() here instead?
630 return _cache[TAG_ROOT_ID]; 646 return _cache[TAG_ROOT_ID];
631 } 647 }
632 648
633 void processProfile(ServiceMap profile) { 649 void processProfile(ServiceMap profile) {
634 assert(profile.serviceType == 'Profile'); 650 assert(profile.type == 'Profile');
635 var codeTable = new List<Code>(); 651 var codeTable = new List<Code>();
636 var codeRegions = profile['codes']; 652 var codeRegions = profile['codes'];
637 for (var codeRegion in codeRegions) { 653 for (var codeRegion in codeRegions) {
638 Code code = codeRegion['code']; 654 Code code = codeRegion['code'];
639 assert(code != null); 655 assert(code != null);
640 codeTable.add(code); 656 codeTable.add(code);
641 } 657 }
642 _resetProfileData(); 658 _resetProfileData();
643 _updateProfileData(profile, codeTable); 659 _updateProfileData(profile, codeTable);
644 var exclusiveTrie = profile['exclusive_trie']; 660 var exclusiveTrie = profile['exclusive_trie'];
(...skipping 21 matching lines...) Expand all
666 } 682 }
667 683
668 /// Fetches and builds the class hierarchy for this isolate. Returns the 684 /// Fetches and builds the class hierarchy for this isolate. Returns the
669 /// Object class object. 685 /// Object class object.
670 Future<Class> getClassHierarchy() { 686 Future<Class> getClassHierarchy() {
671 return get('classes').then(_loadClasses).then(_buildClassHierarchy); 687 return get('classes').then(_loadClasses).then(_buildClassHierarchy);
672 } 688 }
673 689
674 /// Given the class list, loads each class. 690 /// Given the class list, loads each class.
675 Future<List<Class>> _loadClasses(ServiceMap classList) { 691 Future<List<Class>> _loadClasses(ServiceMap classList) {
676 assert(classList.serviceType == 'ClassList'); 692 assert(classList.type == 'ClassList');
677 var futureClasses = []; 693 var futureClasses = [];
678 for (var cls in classList['members']) { 694 for (var cls in classList['members']) {
679 // Skip over non-class classes. 695 // Skip over non-class classes.
680 if (cls is Class) { 696 if (cls is Class) {
681 futureClasses.add(cls.load()); 697 futureClasses.add(cls.load());
682 } 698 }
683 } 699 }
684 return Future.wait(futureClasses); 700 return Future.wait(futureClasses);
685 } 701 }
686 702
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
767 mainPort = map['mainPort']; 783 mainPort = map['mainPort'];
768 name = map['name']; 784 name = map['name'];
769 vmName = map['name']; 785 vmName = map['name'];
770 if (mapIsRef) { 786 if (mapIsRef) {
771 return; 787 return;
772 } 788 }
773 _loaded = true; 789 _loaded = true;
774 loading = false; 790 loading = false;
775 791
776 reloadBreakpoints(); 792 reloadBreakpoints();
777
778 // Remap DebuggerEvent to ServiceEvent so that the observatory can
779 // work against 1.5 vms in the short term.
780 //
781 // TODO(turnidge): Remove this when no longer needed.
782 var pause = map['pauseEvent'];
783 if (pause != null) {
784 if (pause['type'] == 'DebuggerEvent') {
785 pause['type'] = 'ServiceEvent';
786 }
787 }
788
789 _upgradeCollection(map, isolate); 793 _upgradeCollection(map, isolate);
790 if (map['rootLib'] == null || 794 if (map['rootLib'] == null ||
791 map['timers'] == null || 795 map['timers'] == null ||
792 map['heaps'] == null) { 796 map['heaps'] == null) {
793 Logger.root.severe("Malformed 'Isolate' response: $map"); 797 Logger.root.severe("Malformed 'Isolate' response: $map");
794 return; 798 return;
795 } 799 }
796 rootLib = map['rootLib']; 800 rootLib = map['rootLib'];
797 if (map['entry'] != null) { 801 if (map['entry'] != null) {
798 entry = map['entry']; 802 entry = map['entry'];
(...skipping 290 matching lines...) Expand 10 before | Expand all | Expand 10 after
1089 1093
1090 String toString() => "Isolate($_id)"; 1094 String toString() => "Isolate($_id)";
1091 } 1095 }
1092 1096
1093 /// A [ServiceObject] which implements [ObservableMap]. 1097 /// A [ServiceObject] which implements [ObservableMap].
1094 class ServiceMap extends ServiceObject implements ObservableMap { 1098 class ServiceMap extends ServiceObject implements ObservableMap {
1095 final ObservableMap _map = new ObservableMap(); 1099 final ObservableMap _map = new ObservableMap();
1096 static String objectIdRingPrefix = 'objects/'; 1100 static String objectIdRingPrefix = 'objects/';
1097 1101
1098 bool get canCache { 1102 bool get canCache {
1099 return (_serviceType == 'Class' || 1103 return (_type == 'Class' ||
1100 _serviceType == 'Function' || 1104 _type == 'Function' ||
1101 _serviceType == 'Field') && 1105 _type == 'Field') &&
1102 !_id.startsWith(objectIdRingPrefix); 1106 !_id.startsWith(objectIdRingPrefix);
1103 } 1107 }
1104 bool get immutable => false; 1108 bool get immutable => false;
1105 1109
1106 ServiceMap._empty(ServiceObjectOwner owner) : super._empty(owner); 1110 ServiceMap._empty(ServiceObjectOwner owner) : super._empty(owner);
1107 1111
1108 void _upgradeValues() { 1112 void _upgradeValues() {
1109 assert(owner != null); 1113 assert(owner != null);
1110 _upgradeCollection(_map, owner); 1114 _upgradeCollection(_map, owner);
1111 } 1115 }
(...skipping 1238 matching lines...) Expand 10 before | Expand all | Expand 10 after
2350 metric.reload().then((m) { 2354 metric.reload().then((m) {
2351 m.addSample(new MetricSample(m.value)); 2355 m.addSample(new MetricSample(m.value));
2352 }); 2356 });
2353 } 2357 }
2354 } 2358 }
2355 } 2359 }
2356 2360
2357 // Convert any ServiceMaps representing a null instance into an actual null. 2361 // Convert any ServiceMaps representing a null instance into an actual null.
2358 _convertNull(obj) { 2362 _convertNull(obj) {
2359 if (obj is ServiceMap && 2363 if (obj is ServiceMap &&
2360 obj.serviceType == 'Null') { 2364 obj.type == 'Null') {
2361 return null; 2365 return null;
2362 } 2366 }
2363 return obj; 2367 return obj;
2364 } 2368 }
2365 2369
2366 // Returns true if [map] is a service map. i.e. it has the following keys: 2370 // Returns true if [map] is a service map. i.e. it has the following keys:
2367 // 'id' and a 'type'. 2371 // 'id' and a 'type'.
2368 bool _isServiceMap(ObservableMap m) { 2372 bool _isServiceMap(ObservableMap m) {
2369 return (m != null) && (m['id'] != null) && (m['type'] != null); 2373 return (m != null) && (m['id'] != null) && (m['type'] != null);
2370 } 2374 }
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
2403 var v = list[i]; 2407 var v = list[i];
2404 if ((v is ObservableMap) && _isServiceMap(v)) { 2408 if ((v is ObservableMap) && _isServiceMap(v)) {
2405 list[i] = owner.getFromMap(v); 2409 list[i] = owner.getFromMap(v);
2406 } else if (v is ObservableList) { 2410 } else if (v is ObservableList) {
2407 _upgradeObservableList(v, owner); 2411 _upgradeObservableList(v, owner);
2408 } else if (v is ObservableMap) { 2412 } else if (v is ObservableMap) {
2409 _upgradeObservableMap(v, owner); 2413 _upgradeObservableMap(v, owner);
2410 } 2414 }
2411 } 2415 }
2412 } 2416 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698