OLD | NEW |
---|---|
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 /// The owner of this [ServiceObject]. This can be an [Isolate], a | 10 /// The owner of this [ServiceObject]. This can be an [Isolate], a |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
65 case 'Class': | 65 case 'Class': |
66 obj = new Class._empty(owner); | 66 obj = new Class._empty(owner); |
67 break; | 67 break; |
68 case 'Code': | 68 case 'Code': |
69 obj = new Code._empty(owner); | 69 obj = new Code._empty(owner); |
70 break; | 70 break; |
71 case 'Error': | 71 case 'Error': |
72 obj = new DartError._empty(owner); | 72 obj = new DartError._empty(owner); |
73 break; | 73 break; |
74 case 'Isolate': | 74 case 'Isolate': |
75 obj = new Isolate._empty(owner); | 75 obj = new Isolate._empty(owner.vm); |
76 break; | 76 break; |
77 case 'Library': | 77 case 'Library': |
78 obj = new Library._empty(owner); | 78 obj = new Library._empty(owner); |
79 break; | 79 break; |
80 case 'ServiceError': | 80 case 'ServiceError': |
81 obj = new ServiceError._empty(owner); | 81 obj = new ServiceError._empty(owner); |
82 break; | 82 break; |
83 case 'ServiceEvent': | |
84 obj = new ServiceEvent._empty(owner); | |
85 break; | |
83 case 'ServiceException': | 86 case 'ServiceException': |
84 obj = new ServiceException._empty(owner); | 87 obj = new ServiceException._empty(owner); |
85 break; | 88 break; |
86 case 'Script': | 89 case 'Script': |
87 obj = new Script._empty(owner); | 90 obj = new Script._empty(owner); |
88 break; | 91 break; |
89 case 'Socket': | 92 case 'Socket': |
90 obj = new Socket._empty(owner); | 93 obj = new Socket._empty(owner); |
91 break; | 94 break; |
92 default: | 95 default: |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
197 name = 'vm'; | 200 name = 'vm'; |
198 vmName = 'vm'; | 201 vmName = 'vm'; |
199 _cache['vm'] = this; | 202 _cache['vm'] = this; |
200 update(toObservable({'id':'vm', 'type':'@VM'})); | 203 update(toObservable({'id':'vm', 'type':'@VM'})); |
201 } | 204 } |
202 | 205 |
203 final StreamController<ServiceException> exceptions = | 206 final StreamController<ServiceException> exceptions = |
204 new StreamController.broadcast(); | 207 new StreamController.broadcast(); |
205 final StreamController<ServiceError> errors = | 208 final StreamController<ServiceError> errors = |
206 new StreamController.broadcast(); | 209 new StreamController.broadcast(); |
210 final StreamController<ServiceEvent> events = | |
211 new StreamController.broadcast(); | |
212 | |
213 void postEventMessage(String eventMessage) { | |
Cutch
2014/06/27 16:03:49
Why isn't the event just upgraded like other servi
turnidge
2014/06/27 18:15:06
I don't understand. Let's chat in person.
| |
214 var map; | |
215 try { | |
216 map = _parseJSON(eventMessage); | |
217 } catch (e, st) { | |
218 Logger.root.severe('Ignoring malformed event message: ${eventMessage}'); | |
219 return; | |
220 } | |
221 if (map['type'] != 'ServiceEvent') { | |
222 Logger.root.severe( | |
223 "Expected 'ServiceEvent' but found '${map['type']}'"); | |
224 return; | |
225 } | |
226 // Extract the owning isolate from the event itself. | |
227 String owningIsolateId = map['isolate']['id']; | |
228 _getIsolate(owningIsolateId).then((owningIsolate) { | |
229 var event = new ServiceObject._fromMap(owningIsolate, map); | |
230 events.add(event); | |
231 }); | |
232 } | |
207 | 233 |
208 static final RegExp _currentIsolateMatcher = new RegExp(r'isolates/\d+'); | 234 static final RegExp _currentIsolateMatcher = new RegExp(r'isolates/\d+'); |
209 static final RegExp _currentObjectMatcher = new RegExp(r'isolates/\d+/'); | 235 static final RegExp _currentObjectMatcher = new RegExp(r'isolates/\d+/'); |
210 static final String _isolatesPrefix = 'isolates/'; | 236 static final String _isolatesPrefix = 'isolates/'; |
211 | 237 |
212 String _parseObjectId(String id) { | 238 String _parseObjectId(String id) { |
213 Match m = _currentObjectMatcher.matchAsPrefix(id); | 239 Match m = _currentObjectMatcher.matchAsPrefix(id); |
214 if (m == null) { | 240 if (m == null) { |
215 return null; | 241 return null; |
216 } | 242 } |
(...skipping 289 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
506 } | 532 } |
507 | 533 |
508 /// State for a running isolate. | 534 /// State for a running isolate. |
509 class Isolate extends ServiceObjectOwner { | 535 class Isolate extends ServiceObjectOwner { |
510 @reflectable VM get vm => owner; | 536 @reflectable VM get vm => owner; |
511 @reflectable Isolate get isolate => this; | 537 @reflectable Isolate get isolate => this; |
512 @observable ObservableMap counters = new ObservableMap(); | 538 @observable ObservableMap counters = new ObservableMap(); |
513 | 539 |
514 String get link => '/${_id}'; | 540 String get link => '/${_id}'; |
515 | 541 |
516 @observable ServiceMap pauseEvent = null; | 542 @observable ServiceEvent pauseEvent = null; |
517 bool get _isPaused => pauseEvent != null; | 543 bool get _isPaused => pauseEvent != null; |
518 | 544 |
519 @observable bool running = false; | 545 @observable bool running = false; |
520 @observable bool idle = false; | 546 @observable bool idle = false; |
521 @observable bool loading = true; | 547 @observable bool loading = true; |
522 @observable bool ioEnabled = false; | 548 @observable bool ioEnabled = false; |
523 | 549 |
524 Map<String,ServiceObject> _cache = new Map<String,ServiceObject>(); | 550 Map<String,ServiceObject> _cache = new Map<String,ServiceObject>(); |
525 final TagProfile tagProfile = new TagProfile(20); | 551 final TagProfile tagProfile = new TagProfile(20); |
526 | 552 |
(...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
762 ioEnabled = true; | 788 ioEnabled = true; |
763 } | 789 } |
764 } | 790 } |
765 } | 791 } |
766 // Isolate status | 792 // Isolate status |
767 pauseEvent = map['pauseEvent']; | 793 pauseEvent = map['pauseEvent']; |
768 running = (!_isPaused && map['topFrame'] != null); | 794 running = (!_isPaused && map['topFrame'] != null); |
769 idle = (!_isPaused && map['topFrame'] == null); | 795 idle = (!_isPaused && map['topFrame'] == null); |
770 error = map['error']; | 796 error = map['error']; |
771 | 797 |
798 // Synthesize a resume event if this isolate is not paused. | |
799 if (pauseEvent == null) { | |
800 var event = new ServiceObject._fromMap(this, toObservable({ | |
801 'type': 'ServiceEvent', | |
802 'id': '', | |
803 'eventType': 'IsolateResumed', | |
804 'isolate': id, | |
805 })); | |
806 vm.events.add(event); | |
Cutch
2014/06/27 16:03:49
Why do we synthesize a resume event every time we
turnidge
2014/06/27 18:15:06
I was using a fake resume event to clear out any p
| |
807 } | |
808 | |
772 libraries.clear(); | 809 libraries.clear(); |
773 for (var lib in map['libraries']) { | 810 for (var lib in map['libraries']) { |
774 libraries.add(lib); | 811 libraries.add(lib); |
775 } | 812 } |
776 libraries.sort((a,b) => a.name.compareTo(b.name)); | 813 libraries.sort((a,b) => a.name.compareTo(b.name)); |
777 } | 814 } |
778 | 815 |
779 Future<TagProfile> updateTagProfile() { | 816 Future<TagProfile> updateTagProfile() { |
780 return vm.getAsMap(relativeLink('profile/tag')).then((ObservableMap m) { | 817 return vm.getAsMap(relativeLink('profile/tag')).then((ObservableMap m) { |
781 var seconds = new DateTime.now().millisecondsSinceEpoch / 1000.0; | 818 var seconds = new DateTime.now().millisecondsSinceEpoch / 1000.0; |
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
943 | 980 |
944 void _update(ObservableMap map, bool mapIsRef) { | 981 void _update(ObservableMap map, bool mapIsRef) { |
945 kind = map['kind']; | 982 kind = map['kind']; |
946 message = map['message']; | 983 message = map['message']; |
947 response = map['response']; | 984 response = map['response']; |
948 name = 'ServiceException $kind'; | 985 name = 'ServiceException $kind'; |
949 vmName = name; | 986 vmName = name; |
950 } | 987 } |
951 } | 988 } |
952 | 989 |
990 /// A [ServiceEvent] is an asynchronous event notification from the vm. | |
991 class ServiceEvent extends ServiceObject { | |
992 ServiceEvent._empty(ServiceObjectOwner owner) : super._empty(owner); | |
993 | |
994 @observable String eventType; | |
995 @observable ServiceMap breakpoint; | |
996 @observable ServiceMap exception; | |
997 | |
998 void _update(ObservableMap map, bool mapIsRef) { | |
999 _loaded = true; | |
1000 _upgradeCollection(map, owner); | |
1001 eventType = map['eventType']; | |
1002 name = 'ServiceEvent $eventType'; | |
1003 vmName = name; | |
1004 if (map['breakpoint'] != null) { | |
1005 breakpoint = map['breakpoint']; | |
1006 } | |
1007 if (map['exception'] != null) { | |
1008 exception = map['exception']; | |
1009 } | |
1010 } | |
1011 } | |
1012 | |
953 class Library extends ServiceObject { | 1013 class Library extends ServiceObject { |
954 @observable String url; | 1014 @observable String url; |
955 @reflectable final imports = new ObservableList<Library>(); | 1015 @reflectable final imports = new ObservableList<Library>(); |
956 @reflectable final scripts = new ObservableList<Script>(); | 1016 @reflectable final scripts = new ObservableList<Script>(); |
957 @reflectable final classes = new ObservableList<Class>(); | 1017 @reflectable final classes = new ObservableList<Class>(); |
958 @reflectable final variables = new ObservableList<ServiceMap>(); | 1018 @reflectable final variables = new ObservableList<ServiceMap>(); |
959 @reflectable final functions = new ObservableList<ServiceMap>(); | 1019 @reflectable final functions = new ObservableList<ServiceMap>(); |
960 | 1020 |
961 bool get canCache => true; | 1021 bool get canCache => true; |
962 bool get immutable => false; | 1022 bool get immutable => false; |
(...skipping 412 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1375 } | 1435 } |
1376 } | 1436 } |
1377 | 1437 |
1378 void _resolveJumpTarget(List<CodeInstruction> instructions) { | 1438 void _resolveJumpTarget(List<CodeInstruction> instructions) { |
1379 if (!_isJumpInstruction()) { | 1439 if (!_isJumpInstruction()) { |
1380 return; | 1440 return; |
1381 } | 1441 } |
1382 int address = _getJumpAddress(); | 1442 int address = _getJumpAddress(); |
1383 if (address == 0) { | 1443 if (address == 0) { |
1384 // Could not determine jump address. | 1444 // Could not determine jump address. |
1385 print('Could not determine jump address for $human'); | 1445 Logger.root.severe('Could not determine jump address for $human'); |
1386 return; | 1446 return; |
1387 } | 1447 } |
1388 for (var i = 0; i < instructions.length; i++) { | 1448 for (var i = 0; i < instructions.length; i++) { |
1389 var instruction = instructions[i]; | 1449 var instruction = instructions[i]; |
1390 if (instruction.address == address) { | 1450 if (instruction.address == address) { |
1391 jumpTarget = instruction; | 1451 jumpTarget = instruction; |
1392 return; | 1452 return; |
1393 } | 1453 } |
1394 } | 1454 } |
1395 print('Could not find instruction at ${address.toRadixString(16)}'); | 1455 Logger.root.severe( |
1456 'Could not find instruction at ${address.toRadixString(16)}'); | |
1396 } | 1457 } |
1397 } | 1458 } |
1398 | 1459 |
1399 class CodeKind { | 1460 class CodeKind { |
1400 final _value; | 1461 final _value; |
1401 const CodeKind._internal(this._value); | 1462 const CodeKind._internal(this._value); |
1402 String toString() => '$_value'; | 1463 String toString() => '$_value'; |
1403 | 1464 |
1404 static CodeKind fromString(String s) { | 1465 static CodeKind fromString(String s) { |
1405 if (s == 'Native') { | 1466 if (s == 'Native') { |
(...skipping 421 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1827 var v = list[i]; | 1888 var v = list[i]; |
1828 if ((v is ObservableMap) && _isServiceMap(v)) { | 1889 if ((v is ObservableMap) && _isServiceMap(v)) { |
1829 list[i] = owner.getFromMap(v); | 1890 list[i] = owner.getFromMap(v); |
1830 } else if (v is ObservableList) { | 1891 } else if (v is ObservableList) { |
1831 _upgradeObservableList(v, owner); | 1892 _upgradeObservableList(v, owner); |
1832 } else if (v is ObservableMap) { | 1893 } else if (v is ObservableMap) { |
1833 _upgradeObservableMap(v, owner); | 1894 _upgradeObservableMap(v, owner); |
1834 } | 1895 } |
1835 } | 1896 } |
1836 } | 1897 } |
OLD | NEW |