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 /// Helper function for canceling a Future<StreamSubscription>. | 7 /// Helper function for canceling a Future<StreamSubscription>. |
8 Future cancelFutureSubscription( | 8 Future cancelFutureSubscription( |
9 Future<StreamSubscription> subscriptionFuture) async { | 9 Future<StreamSubscription> subscriptionFuture) async { |
10 if (subscriptionFuture != null) { | 10 if (subscriptionFuture != null) { |
(...skipping 622 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
633 final ObservableList<Isolate> isolates = new ObservableList<Isolate>(); | 633 final ObservableList<Isolate> isolates = new ObservableList<Isolate>(); |
634 | 634 |
635 @observable String version = 'unknown'; | 635 @observable String version = 'unknown'; |
636 @observable String targetCPU; | 636 @observable String targetCPU; |
637 @observable int architectureBits; | 637 @observable int architectureBits; |
638 @observable bool assertsEnabled = false; | 638 @observable bool assertsEnabled = false; |
639 @observable bool typeChecksEnabled = false; | 639 @observable bool typeChecksEnabled = false; |
640 @observable int pid = 0; | 640 @observable int pid = 0; |
641 @observable DateTime startTime; | 641 @observable DateTime startTime; |
642 @observable DateTime refreshTime; | 642 @observable DateTime refreshTime; |
643 @observable Duration get upTime => | 643 @observable Duration get upTime { |
644 (new DateTime.now().difference(startTime)); | 644 if (startTime == null) { |
| 645 return null; |
| 646 } |
| 647 return (new DateTime.now().difference(startTime)); |
| 648 } |
645 | 649 |
646 VM() : super._empty(null) { | 650 VM() : super._empty(null) { |
647 name = 'vm'; | 651 update(toObservable({'name':'vm', 'type':'@VM'})); |
648 vmName = 'vm'; | |
649 _cache['vm'] = this; | |
650 update(toObservable({'id':'vm', 'type':'@VM'})); | |
651 } | 652 } |
652 | 653 |
653 void postServiceEvent(String streamId, Map response, ByteData data) { | 654 void postServiceEvent(String streamId, Map response, ByteData data) { |
654 var map = toObservable(response); | 655 var map = toObservable(response); |
655 assert(!map.containsKey('_data')); | 656 assert(!map.containsKey('_data')); |
656 if (data != null) { | 657 if (data != null) { |
657 map['_data'] = data; | 658 map['_data'] = data; |
658 } | 659 } |
659 if (map['type'] != 'Event') { | 660 if (map['type'] != 'Event') { |
660 Logger.root.severe( | 661 Logger.root.severe( |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
726 toRemove.forEach((id) => _isolateCache.remove(id)); | 727 toRemove.forEach((id) => _isolateCache.remove(id)); |
727 _buildIsolateList(); | 728 _buildIsolateList(); |
728 } | 729 } |
729 | 730 |
730 static final String _isolateIdPrefix = 'isolates/'; | 731 static final String _isolateIdPrefix = 'isolates/'; |
731 | 732 |
732 ServiceObject getFromMap(ObservableMap map) { | 733 ServiceObject getFromMap(ObservableMap map) { |
733 if (map == null) { | 734 if (map == null) { |
734 return null; | 735 return null; |
735 } | 736 } |
| 737 var type = _stripRef(map['type']); |
| 738 if (type == 'VM') { |
| 739 // Update this VM object. |
| 740 update(map); |
| 741 return this; |
| 742 } |
| 743 |
| 744 assert(type == 'Isolate'); |
736 String id = map['id']; | 745 String id = map['id']; |
737 if (!id.startsWith(_isolateIdPrefix)) { | 746 if (!id.startsWith(_isolateIdPrefix)) { |
738 // Currently the VM only supports upgrading Isolate ServiceObjects. | 747 // Currently the VM only supports upgrading Isolate ServiceObjects. |
739 throw new UnimplementedError(); | 748 throw new UnimplementedError(); |
740 } | 749 } |
741 | 750 |
742 // Check cache. | 751 // Check cache. |
743 var isolate = _isolateCache[id]; | 752 var isolate = _isolateCache[id]; |
744 if (isolate == null) { | 753 if (isolate == null) { |
745 // Add new isolate to the cache. | 754 // Add new isolate to the cache. |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
809 } | 818 } |
810 | 819 |
811 Future restart() { | 820 Future restart() { |
812 return invokeRpc('_restartVM', {}); | 821 return invokeRpc('_restartVM', {}); |
813 } | 822 } |
814 | 823 |
815 Future<ObservableMap> _fetchDirect() async { | 824 Future<ObservableMap> _fetchDirect() async { |
816 if (!loaded) { | 825 if (!loaded) { |
817 // The vm service relies on these events to keep the VM and | 826 // The vm service relies on these events to keep the VM and |
818 // Isolate types up to date. | 827 // Isolate types up to date. |
| 828 await listenEventStream(kVMStream, _dispatchEventToIsolate); |
819 await listenEventStream(kIsolateStream, _dispatchEventToIsolate); | 829 await listenEventStream(kIsolateStream, _dispatchEventToIsolate); |
820 await listenEventStream(kDebugStream, _dispatchEventToIsolate); | 830 await listenEventStream(kDebugStream, _dispatchEventToIsolate); |
821 await listenEventStream(_kGraphStream, _dispatchEventToIsolate); | 831 await listenEventStream(_kGraphStream, _dispatchEventToIsolate); |
822 } | 832 } |
823 return await invokeRpcNoUpgrade('getVM', {}); | 833 return await invokeRpcNoUpgrade('getVM', {}); |
824 } | 834 } |
825 | 835 |
| 836 Future setName(String newName) { |
| 837 return invokeRpc('setVMName', { 'name': newName }); |
| 838 } |
| 839 |
826 Future<ServiceObject> getFlagList() { | 840 Future<ServiceObject> getFlagList() { |
827 return invokeRpc('getFlagList', {}); | 841 return invokeRpc('getFlagList', {}); |
828 } | 842 } |
829 | 843 |
830 Future<ServiceObject> _streamListen(String streamId) { | 844 Future<ServiceObject> _streamListen(String streamId) { |
831 Map params = { | 845 Map params = { |
832 'streamId': streamId, | 846 'streamId': streamId, |
833 }; | 847 }; |
834 return invokeRpc('streamListen', params); | 848 return invokeRpc('streamListen', params); |
835 } | 849 } |
836 | 850 |
837 Future<ServiceObject> _streamCancel(String streamId) { | 851 Future<ServiceObject> _streamCancel(String streamId) { |
838 Map params = { | 852 Map params = { |
839 'streamId': streamId, | 853 'streamId': streamId, |
840 }; | 854 }; |
841 return invokeRpc('streamCancel', params); | 855 return invokeRpc('streamCancel', params); |
842 } | 856 } |
843 | 857 |
844 // A map from stream id to event stream state. | 858 // A map from stream id to event stream state. |
845 Map<String,_EventStreamState> _eventStreams = {}; | 859 Map<String,_EventStreamState> _eventStreams = {}; |
846 | 860 |
847 // Well-known stream ids. | 861 // Well-known stream ids. |
| 862 static const kVMStream = 'VM'; |
848 static const kIsolateStream = 'Isolate'; | 863 static const kIsolateStream = 'Isolate'; |
849 static const kDebugStream = 'Debug'; | 864 static const kDebugStream = 'Debug'; |
850 static const kGCStream = 'GC'; | 865 static const kGCStream = 'GC'; |
851 static const kStdoutStream = 'Stdout'; | 866 static const kStdoutStream = 'Stdout'; |
852 static const kStderrStream = 'Stderr'; | 867 static const kStderrStream = 'Stderr'; |
853 static const _kGraphStream = '_Graph'; | 868 static const _kGraphStream = '_Graph'; |
854 | 869 |
855 /// Returns a single-subscription Stream object for a VM event stream. | 870 /// Returns a single-subscription Stream object for a VM event stream. |
856 Future<Stream> getEventStream(String streamId) async { | 871 Future<Stream> getEventStream(String streamId) async { |
857 var eventStream = _eventStreams.putIfAbsent( | 872 var eventStream = _eventStreams.putIfAbsent( |
(...skipping 10 matching lines...) Expand all Loading... |
868 } | 883 } |
869 | 884 |
870 /// Force the VM to disconnect. | 885 /// Force the VM to disconnect. |
871 void disconnect(); | 886 void disconnect(); |
872 /// Completes when the VM first connects. | 887 /// Completes when the VM first connects. |
873 Future get onConnect; | 888 Future get onConnect; |
874 /// Completes when the VM disconnects or there was an error connecting. | 889 /// Completes when the VM disconnects or there was an error connecting. |
875 Future get onDisconnect; | 890 Future get onDisconnect; |
876 | 891 |
877 void _update(ObservableMap map, bool mapIsRef) { | 892 void _update(ObservableMap map, bool mapIsRef) { |
| 893 name = map['name']; |
| 894 vmName = map.containsKey('_vmName') ? map['_vmName'] : name; |
878 if (mapIsRef) { | 895 if (mapIsRef) { |
879 return; | 896 return; |
880 } | 897 } |
881 // Note that upgrading the collection creates any isolates in the | 898 // Note that upgrading the collection creates any isolates in the |
882 // isolate list which are new. | 899 // isolate list which are new. |
883 _upgradeCollection(map, vm); | 900 _upgradeCollection(map, vm); |
884 | 901 |
885 _loaded = true; | 902 _loaded = true; |
886 version = map['version']; | 903 version = map['version']; |
887 targetCPU = map['targetCPU']; | 904 targetCPU = map['targetCPU']; |
(...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1104 } | 1121 } |
1105 | 1122 |
1106 /// State for a running isolate. | 1123 /// State for a running isolate. |
1107 class Isolate extends ServiceObjectOwner with Coverage { | 1124 class Isolate extends ServiceObjectOwner with Coverage { |
1108 static const kLoggingStream = '_Logging'; | 1125 static const kLoggingStream = '_Logging'; |
1109 @reflectable VM get vm => owner; | 1126 @reflectable VM get vm => owner; |
1110 @reflectable Isolate get isolate => this; | 1127 @reflectable Isolate get isolate => this; |
1111 @observable int number; | 1128 @observable int number; |
1112 @observable int originNumber; | 1129 @observable int originNumber; |
1113 @observable DateTime startTime; | 1130 @observable DateTime startTime; |
1114 @observable Duration get upTime => | 1131 @observable Duration get upTime { |
1115 (new DateTime.now().difference(startTime)); | 1132 if (startTime == null) { |
| 1133 return null; |
| 1134 } |
| 1135 return (new DateTime.now().difference(startTime)); |
| 1136 } |
1116 | 1137 |
1117 @observable ObservableMap counters = new ObservableMap(); | 1138 @observable ObservableMap counters = new ObservableMap(); |
1118 | 1139 |
1119 void _updateRunState() { | 1140 void _updateRunState() { |
1120 topFrame = (pauseEvent != null ? pauseEvent.topFrame : null); | 1141 topFrame = (pauseEvent != null ? pauseEvent.topFrame : null); |
1121 paused = (pauseEvent != null && | 1142 paused = (pauseEvent != null && |
1122 pauseEvent.kind != ServiceEvent.kResume); | 1143 pauseEvent.kind != ServiceEvent.kResume); |
1123 running = (!paused && topFrame != null); | 1144 running = (!paused && topFrame != null); |
1124 idle = (!paused && topFrame == null); | 1145 idle = (!paused && topFrame == null); |
1125 notifyPropertyChange(#topFrame, 0, 1); | 1146 notifyPropertyChange(#topFrame, 0, 1); |
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1334 return _snapshotFetch.stream; | 1355 return _snapshotFetch.stream; |
1335 } | 1356 } |
1336 | 1357 |
1337 void updateHeapsFromMap(ObservableMap map) { | 1358 void updateHeapsFromMap(ObservableMap map) { |
1338 newSpace.update(map['new']); | 1359 newSpace.update(map['new']); |
1339 oldSpace.update(map['old']); | 1360 oldSpace.update(map['old']); |
1340 } | 1361 } |
1341 | 1362 |
1342 void _update(ObservableMap map, bool mapIsRef) { | 1363 void _update(ObservableMap map, bool mapIsRef) { |
1343 name = map['name']; | 1364 name = map['name']; |
1344 vmName = map['name']; | 1365 vmName = map.containsKey('_vmName') ? map['_vmName'] : name; |
1345 number = int.parse(map['number'], onError:(_) => null); | 1366 number = int.parse(map['number'], onError:(_) => null); |
1346 if (mapIsRef) { | 1367 if (mapIsRef) { |
1347 return; | 1368 return; |
1348 } | 1369 } |
1349 _loaded = true; | 1370 _loaded = true; |
1350 loading = false; | 1371 loading = false; |
1351 | 1372 |
1352 _upgradeCollection(map, isolate); | 1373 _upgradeCollection(map, isolate); |
1353 originNumber = int.parse(map['_originNumber'], onError:(_) => null); | 1374 originNumber = int.parse(map['_originNumber'], onError:(_) => null); |
1354 rootLibrary = map['rootLib']; | 1375 rootLibrary = map['rootLib']; |
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1478 | 1499 |
1479 case ServiceEvent.kGraph: | 1500 case ServiceEvent.kGraph: |
1480 _loadHeapSnapshot(event); | 1501 _loadHeapSnapshot(event); |
1481 break; | 1502 break; |
1482 | 1503 |
1483 case ServiceEvent.kGC: | 1504 case ServiceEvent.kGC: |
1484 // Ignore GC events for now. | 1505 // Ignore GC events for now. |
1485 break; | 1506 break; |
1486 | 1507 |
1487 default: | 1508 default: |
1488 // Log unrecognized events. | 1509 // Log unexpected events. |
1489 Logger.root.severe('Unrecognized event: $event'); | 1510 Logger.root.severe('Unexpected event: $event'); |
1490 break; | 1511 break; |
1491 } | 1512 } |
1492 } | 1513 } |
1493 | 1514 |
1494 Future<ServiceObject> addBreakpoint( | 1515 Future<ServiceObject> addBreakpoint( |
1495 Script script, int line, [int col]) async { | 1516 Script script, int line, [int col]) async { |
1496 // TODO(turnidge): Pass line as an int instead of a string. | 1517 // TODO(turnidge): Pass line as an int instead of a string. |
1497 try { | 1518 try { |
1498 Map params = { | 1519 Map params = { |
1499 'scriptId': script.id, | 1520 'scriptId': script.id, |
(...skipping 329 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1829 if (level.value == value) { | 1850 if (level.value == value) { |
1830 return level; | 1851 return level; |
1831 } | 1852 } |
1832 } | 1853 } |
1833 return new Level('$value', value); | 1854 return new Level('$value', value); |
1834 } | 1855 } |
1835 | 1856 |
1836 /// A [ServiceEvent] is an asynchronous event notification from the vm. | 1857 /// A [ServiceEvent] is an asynchronous event notification from the vm. |
1837 class ServiceEvent extends ServiceObject { | 1858 class ServiceEvent extends ServiceObject { |
1838 /// The possible 'kind' values. | 1859 /// The possible 'kind' values. |
| 1860 static const kVMUpdate = 'VMUpdate'; |
1839 static const kIsolateStart = 'IsolateStart'; | 1861 static const kIsolateStart = 'IsolateStart'; |
1840 static const kIsolateRunnable = 'IsolateRunnable'; | 1862 static const kIsolateRunnable = 'IsolateRunnable'; |
1841 static const kIsolateExit = 'IsolateExit'; | 1863 static const kIsolateExit = 'IsolateExit'; |
1842 static const kIsolateUpdate = 'IsolateUpdate'; | 1864 static const kIsolateUpdate = 'IsolateUpdate'; |
1843 static const kPauseStart = 'PauseStart'; | 1865 static const kPauseStart = 'PauseStart'; |
1844 static const kPauseExit = 'PauseExit'; | 1866 static const kPauseExit = 'PauseExit'; |
1845 static const kPauseBreakpoint = 'PauseBreakpoint'; | 1867 static const kPauseBreakpoint = 'PauseBreakpoint'; |
1846 static const kPauseInterrupted = 'PauseInterrupted'; | 1868 static const kPauseInterrupted = 'PauseInterrupted'; |
1847 static const kPauseException = 'PauseException'; | 1869 static const kPauseException = 'PauseException'; |
1848 static const kResume = 'Resume'; | 1870 static const kResume = 'Resume'; |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1946 } | 1968 } |
1947 if (map['logRecord'] != null) { | 1969 if (map['logRecord'] != null) { |
1948 logRecord = map['logRecord']; | 1970 logRecord = map['logRecord']; |
1949 logRecord['time'] = | 1971 logRecord['time'] = |
1950 new DateTime.fromMillisecondsSinceEpoch(logRecord['time']); | 1972 new DateTime.fromMillisecondsSinceEpoch(logRecord['time']); |
1951 logRecord['level'] = _findLogLevel(logRecord['level']); | 1973 logRecord['level'] = _findLogLevel(logRecord['level']); |
1952 } | 1974 } |
1953 } | 1975 } |
1954 | 1976 |
1955 String toString() { | 1977 String toString() { |
| 1978 var ownerName = owner.id != null ? owner.id.toString() : owner.name; |
1956 if (data == null) { | 1979 if (data == null) { |
1957 return "ServiceEvent(owner='${owner.id}', kind='${kind}', " | 1980 return "ServiceEvent(owner='${ownerName}', kind='${kind}', " |
1958 "time=${timestamp})"; | 1981 "time=${timestamp})"; |
1959 } else { | 1982 } else { |
1960 return "ServiceEvent(owner='${owner.id}', kind='${kind}', " | 1983 return "ServiceEvent(owner='${ownerName}', kind='${kind}', " |
1961 "data.lengthInBytes=${data.lengthInBytes}, time=${timestamp})"; | 1984 "data.lengthInBytes=${data.lengthInBytes}, time=${timestamp})"; |
1962 } | 1985 } |
1963 } | 1986 } |
1964 } | 1987 } |
1965 | 1988 |
1966 class Breakpoint extends ServiceObject { | 1989 class Breakpoint extends ServiceObject { |
1967 Breakpoint._empty(ServiceObjectOwner owner) : super._empty(owner); | 1990 Breakpoint._empty(ServiceObjectOwner owner) : super._empty(owner); |
1968 | 1991 |
1969 // TODO(turnidge): Add state to track if a breakpoint has been | 1992 // TODO(turnidge): Add state to track if a breakpoint has been |
1970 // removed from the program. Remove from the cache when deleted. | 1993 // removed from the program. Remove from the cache when deleted. |
(...skipping 1970 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3941 var v = list[i]; | 3964 var v = list[i]; |
3942 if ((v is ObservableMap) && _isServiceMap(v)) { | 3965 if ((v is ObservableMap) && _isServiceMap(v)) { |
3943 list[i] = owner.getFromMap(v); | 3966 list[i] = owner.getFromMap(v); |
3944 } else if (v is ObservableList) { | 3967 } else if (v is ObservableList) { |
3945 _upgradeObservableList(v, owner); | 3968 _upgradeObservableList(v, owner); |
3946 } else if (v is ObservableMap) { | 3969 } else if (v is ObservableMap) { |
3947 _upgradeObservableMap(v, owner); | 3970 _upgradeObservableMap(v, owner); |
3948 } | 3971 } |
3949 } | 3972 } |
3950 } | 3973 } |
OLD | NEW |