Chromium Code Reviews| 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 |