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 // Some value smaller than the object ring, so requesting a large array | 7 // Some value smaller than the object ring, so requesting a large array |
8 // doesn't result in an expired ref because the elements lapped it in the | 8 // doesn't result in an expired ref because the elements lapped it in the |
9 // object ring. | 9 // object ring. |
10 const int kDefaultFieldLimit = 100; | 10 const int kDefaultFieldLimit = 100; |
(...skipping 13 matching lines...) Expand all Loading... |
24 /// while invoking an rpc. | 24 /// while invoking an rpc. |
25 abstract class RpcException implements Exception, M.BasicException { | 25 abstract class RpcException implements Exception, M.BasicException { |
26 RpcException(this.message); | 26 RpcException(this.message); |
27 | 27 |
28 String message; | 28 String message; |
29 } | 29 } |
30 | 30 |
31 /// A ServerRpcException represents an error returned by the VM. | 31 /// A ServerRpcException represents an error returned by the VM. |
32 class ServerRpcException extends RpcException implements M.RequestException { | 32 class ServerRpcException extends RpcException implements M.RequestException { |
33 /// A list of well-known server error codes. | 33 /// A list of well-known server error codes. |
34 static const kParseError = -32700; | 34 static const kParseError = -32700; |
35 static const kInvalidRequest = -32600; | 35 static const kInvalidRequest = -32600; |
36 static const kMethodNotFound = -32601; | 36 static const kMethodNotFound = -32601; |
37 static const kInvalidParams = -32602; | 37 static const kInvalidParams = -32602; |
38 static const kInternalError = -32603; | 38 static const kInternalError = -32603; |
39 static const kFeatureDisabled = 100; | 39 static const kFeatureDisabled = 100; |
40 static const kCannotAddBreakpoint = 102; | 40 static const kCannotAddBreakpoint = 102; |
41 static const kStreamAlreadySubscribed = 103; | 41 static const kStreamAlreadySubscribed = 103; |
42 static const kStreamNotSubscribed = 104; | 42 static const kStreamNotSubscribed = 104; |
43 static const kIsolateMustBeRunnable = 105; | 43 static const kIsolateMustBeRunnable = 105; |
44 static const kIsolateMustBePaused = 106; | 44 static const kIsolateMustBePaused = 106; |
45 static const kIsolateIsReloading = 1000; | 45 static const kIsolateIsReloading = 1000; |
46 static const kFileSystemAlreadyExists = 1001; | 46 static const kFileSystemAlreadyExists = 1001; |
47 static const kFileSystemDoesNotExist = 1002; | 47 static const kFileSystemDoesNotExist = 1002; |
48 static const kFileDoesNotExist = 1003; | 48 static const kFileDoesNotExist = 1003; |
49 static const kIsolateReloadFailed = 1004; | 49 static const kIsolateReloadFailed = 1004; |
50 | 50 |
51 int code; | 51 int code; |
52 Map data; | 52 Map data; |
53 | 53 |
54 static _getMessage(Map errorMap) { | 54 static _getMessage(Map errorMap) { |
55 Map data = errorMap['data']; | 55 Map data = errorMap['data']; |
56 if (data != null && data['details'] != null) { | 56 if (data != null && data['details'] != null) { |
57 return data['details']; | 57 return data['details']; |
58 } else { | 58 } else { |
59 return errorMap['message']; | 59 return errorMap['message']; |
60 } | 60 } |
61 } | 61 } |
62 | 62 |
63 ServerRpcException.fromMap(Map errorMap) : super(_getMessage(errorMap)) { | 63 ServerRpcException.fromMap(Map errorMap) : super(_getMessage(errorMap)) { |
64 code = errorMap['code']; | 64 code = errorMap['code']; |
65 data = errorMap['data']; | 65 data = errorMap['data']; |
66 } | 66 } |
67 | 67 |
68 String toString() => 'ServerRpcException(${message})'; | 68 String toString() => 'ServerRpcException(${message})'; |
69 } | 69 } |
70 | 70 |
71 /// A NetworkRpcException is used to indicate that an rpc has | 71 /// A NetworkRpcException is used to indicate that an rpc has |
72 /// been canceled due to network error. | 72 /// been canceled due to network error. |
73 class NetworkRpcException extends RpcException | 73 class NetworkRpcException extends RpcException |
74 implements M.ConnectionException { | 74 implements M.ConnectionException { |
75 NetworkRpcException(String message) : super(message); | 75 NetworkRpcException(String message) : super(message); |
76 | 76 |
77 String toString() => 'NetworkRpcException(${message})'; | 77 String toString() => 'NetworkRpcException(${message})'; |
78 } | 78 } |
79 | 79 |
80 class MalformedResponseRpcException extends RpcException { | 80 class MalformedResponseRpcException extends RpcException { |
81 MalformedResponseRpcException(String message, this.response) | 81 MalformedResponseRpcException(String message, this.response) : super(message); |
82 : super(message); | |
83 | 82 |
84 Map response; | 83 Map response; |
85 | 84 |
86 String toString() => 'MalformedResponseRpcException(${message})'; | 85 String toString() => 'MalformedResponseRpcException(${message})'; |
87 } | 86 } |
88 | 87 |
89 class FakeVMRpcException extends RpcException { | 88 class FakeVMRpcException extends RpcException { |
90 FakeVMRpcException(String message) : super(message); | 89 FakeVMRpcException(String message) : super(message); |
91 | 90 |
92 String toString() => 'FakeVMRpcException(${message})'; | 91 String toString() => 'FakeVMRpcException(${message})'; |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
167 /// Is this object immutable after it is [loaded]? | 166 /// Is this object immutable after it is [loaded]? |
168 bool get immutable => false; | 167 bool get immutable => false; |
169 | 168 |
170 String name; | 169 String name; |
171 String vmName; | 170 String vmName; |
172 | 171 |
173 /// Creates an empty [ServiceObject]. | 172 /// Creates an empty [ServiceObject]. |
174 ServiceObject._empty(this._owner); | 173 ServiceObject._empty(this._owner); |
175 | 174 |
176 /// Creates a [ServiceObject] initialized from [map]. | 175 /// Creates a [ServiceObject] initialized from [map]. |
177 factory ServiceObject._fromMap(ServiceObjectOwner owner, | 176 factory ServiceObject._fromMap(ServiceObjectOwner owner, Map map) { |
178 Map map) { | |
179 if (map == null) { | 177 if (map == null) { |
180 return null; | 178 return null; |
181 } | 179 } |
182 if (!_isServiceMap(map)) { | 180 if (!_isServiceMap(map)) { |
183 Logger.root.severe('Malformed service object: $map'); | 181 Logger.root.severe('Malformed service object: $map'); |
184 } | 182 } |
185 assert(_isServiceMap(map)); | 183 assert(_isServiceMap(map)); |
186 var type = _stripRef(map['type']); | 184 var type = _stripRef(map['type']); |
187 var vmType = map['_vmType'] != null ? map['_vmType'] : type; | 185 var vmType = map['_vmType'] != null ? map['_vmType'] : type; |
188 var obj = null; | 186 var obj = null; |
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
327 var mapType = _stripRef(map['type']); | 325 var mapType = _stripRef(map['type']); |
328 if (mapType == 'Sentinel') { | 326 if (mapType == 'Sentinel') { |
329 // An object may have been collected, etc. | 327 // An object may have been collected, etc. |
330 completer.complete(new ServiceObject._fromMap(owner, map)); | 328 completer.complete(new ServiceObject._fromMap(owner, map)); |
331 } else { | 329 } else { |
332 // TODO(turnidge): Check for vmType changing as well? | 330 // TODO(turnidge): Check for vmType changing as well? |
333 assert(mapType == _type); | 331 assert(mapType == _type); |
334 update(map); | 332 update(map); |
335 completer.complete(this); | 333 completer.complete(this); |
336 } | 334 } |
337 | |
338 }).catchError((e, st) { | 335 }).catchError((e, st) { |
339 Logger.root.severe("Unable to reload object: $e\n$st"); | 336 Logger.root.severe("Unable to reload object: $e\n$st"); |
340 _inProgressReload = null; | 337 _inProgressReload = null; |
341 completer.completeError(e, st); | 338 completer.completeError(e, st); |
342 }).whenComplete(() { | 339 }).whenComplete(() { |
343 // This reload is complete. | 340 // This reload is complete. |
344 _inProgressReload = null; | 341 _inProgressReload = null; |
345 }); | 342 }); |
346 } | 343 } |
347 return _inProgressReload; | 344 return _inProgressReload; |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
429 /// be [loaded]. | 426 /// be [loaded]. |
430 ServiceObject getFromMap(Map map); | 427 ServiceObject getFromMap(Map map); |
431 } | 428 } |
432 | 429 |
433 abstract class Location implements M.Location { | 430 abstract class Location implements M.Location { |
434 Script get script; | 431 Script get script; |
435 int get tokenPos; | 432 int get tokenPos; |
436 } | 433 } |
437 | 434 |
438 /// A [SourceLocation] represents a location or range in the source code. | 435 /// A [SourceLocation] represents a location or range in the source code. |
439 class SourceLocation extends ServiceObject implements Location, | 436 class SourceLocation extends ServiceObject |
440 M.SourceLocation { | 437 implements Location, M.SourceLocation { |
441 Script script; | 438 Script script; |
442 int tokenPos; | 439 int tokenPos; |
443 int endTokenPos; | 440 int endTokenPos; |
444 | 441 |
445 Future<int> getLine() async { | 442 Future<int> getLine() async { |
446 await script.load(); | 443 await script.load(); |
447 return script.tokenToLine(tokenPos); | 444 return script.tokenToLine(tokenPos); |
448 } | 445 } |
449 | 446 |
450 Future<int> getColumn() async { | 447 Future<int> getColumn() async { |
(...skipping 24 matching lines...) Expand all Loading... |
475 return '${script.name}:token(${tokenPos})'; | 472 return '${script.name}:token(${tokenPos})'; |
476 } else { | 473 } else { |
477 return '${script.name}:tokens(${tokenPos}-${endTokenPos})'; | 474 return '${script.name}:tokens(${tokenPos}-${endTokenPos})'; |
478 } | 475 } |
479 } | 476 } |
480 } | 477 } |
481 | 478 |
482 /// An [UnresolvedSourceLocation] represents a location in the source | 479 /// An [UnresolvedSourceLocation] represents a location in the source |
483 // code which has not been precisely mapped to a token position. | 480 // code which has not been precisely mapped to a token position. |
484 class UnresolvedSourceLocation extends ServiceObject | 481 class UnresolvedSourceLocation extends ServiceObject |
485 implements Location, | 482 implements Location, M.UnresolvedSourceLocation { |
486 M.UnresolvedSourceLocation { | |
487 Script script; | 483 Script script; |
488 String scriptUri; | 484 String scriptUri; |
489 int line; | 485 int line; |
490 int column; | 486 int column; |
491 int tokenPos; | 487 int tokenPos; |
492 | 488 |
493 Future<int> getLine() async { | 489 Future<int> getLine() async { |
494 if (tokenPos != null) { | 490 if (tokenPos != null) { |
495 await script.load(); | 491 await script.load(); |
496 return script.tokenToLine(tokenPos); | 492 return script.tokenToLine(tokenPos); |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
592 }).catchError((e) { | 588 }).catchError((e) { |
593 /* ignore */ | 589 /* ignore */ |
594 }); | 590 }); |
595 } | 591 } |
596 // No need to wait for _cancelFuture here. | 592 // No need to wait for _cancelFuture here. |
597 return new Future.value(null); | 593 return new Future.value(null); |
598 } | 594 } |
599 | 595 |
600 Future<Stream> addStream() async { | 596 Future<Stream> addStream() async { |
601 var controller; | 597 var controller; |
602 controller = new StreamController( | 598 controller = |
603 onCancel:() => _cancelController(controller)); | 599 new StreamController(onCancel: () => _cancelController(controller)); |
604 _controllers.add(controller); | 600 _controllers.add(controller); |
605 if (_cancelFuture != null) { | 601 if (_cancelFuture != null) { |
606 try { | 602 try { |
607 await _cancelFuture; | 603 await _cancelFuture; |
608 } on NetworkRpcException catch (_) { /* ignore */ } | 604 } on NetworkRpcException catch (_) {/* ignore */} |
609 } | 605 } |
610 if (_listenFuture == null) { | 606 if (_listenFuture == null) { |
611 _listenFuture = _vm._streamListen(streamId); | 607 _listenFuture = _vm._streamListen(streamId); |
612 } | 608 } |
613 try { | 609 try { |
614 await _listenFuture; | 610 await _listenFuture; |
615 } on NetworkRpcException catch (_) { /* ignore */ } | 611 } on NetworkRpcException catch (_) {/* ignore */} |
616 return controller.stream; | 612 return controller.stream; |
617 } | 613 } |
618 | 614 |
619 void addEvent(ServiceEvent event) { | 615 void addEvent(ServiceEvent event) { |
620 for (var controller in _controllers) { | 616 for (var controller in _controllers) { |
621 controller.add(event); | 617 controller.add(event); |
622 } | 618 } |
623 } | 619 } |
624 } | 620 } |
625 | 621 |
626 /// State for a VM being inspected. | 622 /// State for a VM being inspected. |
627 abstract class VM extends ServiceObjectOwner implements M.VM { | 623 abstract class VM extends ServiceObjectOwner implements M.VM { |
628 VM get vm => this; | 624 VM get vm => this; |
629 Isolate get isolate => null; | 625 Isolate get isolate => null; |
630 | 626 |
631 // TODO(turnidge): The connection should not be stored in the VM object. | 627 // TODO(turnidge): The connection should not be stored in the VM object. |
632 bool get isDisconnected; | 628 bool get isDisconnected; |
633 bool get isConnected; | 629 bool get isConnected; |
634 | 630 |
635 // Used for verbose logging. | 631 // Used for verbose logging. |
636 bool verbose = false; | 632 bool verbose = false; |
637 | 633 |
638 // TODO(johnmccutchan): Ensure that isolates do not end up in _cache. | 634 // TODO(johnmccutchan): Ensure that isolates do not end up in _cache. |
639 Map<String,ServiceObject> _cache = new Map<String,ServiceObject>(); | 635 Map<String, ServiceObject> _cache = new Map<String, ServiceObject>(); |
640 final Map<String,Isolate> _isolateCache = <String,Isolate>{}; | 636 final Map<String, Isolate> _isolateCache = <String, Isolate>{}; |
641 | 637 |
642 // The list of live isolates, ordered by isolate start time. | 638 // The list of live isolates, ordered by isolate start time. |
643 final List<Isolate> isolates = <Isolate>[]; | 639 final List<Isolate> isolates = <Isolate>[]; |
644 | 640 |
645 String version = 'unknown'; | 641 String version = 'unknown'; |
646 String hostCPU; | 642 String hostCPU; |
647 String targetCPU; | 643 String targetCPU; |
648 int architectureBits; | 644 int architectureBits; |
649 bool assertsEnabled = false; | 645 bool assertsEnabled = false; |
650 bool typeChecksEnabled = false; | 646 bool typeChecksEnabled = false; |
651 int pid = 0; | 647 int pid = 0; |
652 int maxRSS = 0; | 648 int maxRSS = 0; |
653 bool profileVM = false; | 649 bool profileVM = false; |
654 DateTime startTime; | 650 DateTime startTime; |
655 DateTime refreshTime; | 651 DateTime refreshTime; |
656 Duration get upTime { | 652 Duration get upTime { |
657 if (startTime == null) { | 653 if (startTime == null) { |
658 return null; | 654 return null; |
659 } | 655 } |
660 return (new DateTime.now().difference(startTime)); | 656 return (new DateTime.now().difference(startTime)); |
661 } | 657 } |
662 | 658 |
663 VM() : super._empty(null) { | 659 VM() : super._empty(null) { |
664 update({'name':'vm', 'type':'@VM'}); | 660 update({'name': 'vm', 'type': '@VM'}); |
665 } | 661 } |
666 | 662 |
667 void postServiceEvent(String streamId, Map response, ByteData data) { | 663 void postServiceEvent(String streamId, Map response, ByteData data) { |
668 var map = response; | 664 var map = response; |
669 assert(!map.containsKey('_data')); | 665 assert(!map.containsKey('_data')); |
670 if (data != null) { | 666 if (data != null) { |
671 map['_data'] = data; | 667 map['_data'] = data; |
672 } | 668 } |
673 if (map['type'] != 'Event') { | 669 if (map['type'] != 'Event') { |
674 Logger.root.severe( | 670 Logger.root.severe("Expected 'Event' but found '${map['type']}'"); |
675 "Expected 'Event' but found '${map['type']}'"); | |
676 return; | 671 return; |
677 } | 672 } |
678 | 673 |
679 var eventIsolate = map['isolate']; | 674 var eventIsolate = map['isolate']; |
680 var event; | 675 var event; |
681 if (eventIsolate == null) { | 676 if (eventIsolate == null) { |
682 event = new ServiceObject._fromMap(vm, map); | 677 event = new ServiceObject._fromMap(vm, map); |
683 } else { | 678 } else { |
684 // getFromMap creates the Isolate if it hasn't been seen already. | 679 // getFromMap creates the Isolate if it hasn't been seen already. |
685 var isolate = getFromMap(map['isolate']); | 680 var isolate = getFromMap(map['isolate']); |
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
789 return new Future.value(_isolateCache[isolateId]); | 784 return new Future.value(_isolateCache[isolateId]); |
790 } | 785 } |
791 | 786 |
792 // Implemented in subclass. | 787 // Implemented in subclass. |
793 Future<Map> invokeRpcRaw(String method, Map params); | 788 Future<Map> invokeRpcRaw(String method, Map params); |
794 | 789 |
795 Future<Map> invokeRpcNoUpgrade(String method, Map params) { | 790 Future<Map> invokeRpcNoUpgrade(String method, Map params) { |
796 return invokeRpcRaw(method, params).then((Map response) { | 791 return invokeRpcRaw(method, params).then((Map response) { |
797 var map = response; | 792 var map = response; |
798 if (Tracer.current != null) { | 793 if (Tracer.current != null) { |
799 Tracer.current.trace("Received response for ${method}/${params}}", | 794 Tracer.current |
800 map:map); | 795 .trace("Received response for ${method}/${params}}", map: map); |
801 } | 796 } |
802 if (!_isServiceMap(map)) { | 797 if (!_isServiceMap(map)) { |
803 var exception = | 798 var exception = new MalformedResponseRpcException( |
804 new MalformedResponseRpcException( | 799 "Response is missing the 'type' field", map); |
805 "Response is missing the 'type' field", map); | |
806 return new Future.error(exception); | 800 return new Future.error(exception); |
807 } | 801 } |
808 return new Future.value(map); | 802 return new Future.value(map); |
809 }).catchError((e) { | 803 }).catchError((e) { |
810 // Errors pass through. | 804 // Errors pass through. |
811 return new Future.error(e); | 805 return new Future.error(e); |
812 }); | 806 }); |
813 } | 807 } |
814 | 808 |
815 Future<ServiceObject> invokeRpc(String method, Map params) { | 809 Future<ServiceObject> invokeRpc(String method, Map params) { |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
848 } on FakeVMRpcException catch (_) { | 842 } on FakeVMRpcException catch (_) { |
849 // ignore FakeVMRpcExceptions here. | 843 // ignore FakeVMRpcExceptions here. |
850 } on NetworkRpcException catch (_) { | 844 } on NetworkRpcException catch (_) { |
851 // ignore network errors here. | 845 // ignore network errors here. |
852 } | 846 } |
853 } | 847 } |
854 return await invokeRpcNoUpgrade('getVM', {}); | 848 return await invokeRpcNoUpgrade('getVM', {}); |
855 } | 849 } |
856 | 850 |
857 Future setName(String newName) { | 851 Future setName(String newName) { |
858 return invokeRpc('setVMName', { 'name': newName }); | 852 return invokeRpc('setVMName', {'name': newName}); |
859 } | 853 } |
860 | 854 |
861 Future<ServiceObject> getFlagList() { | 855 Future<ServiceObject> getFlagList() { |
862 return invokeRpc('getFlagList', {}); | 856 return invokeRpc('getFlagList', {}); |
863 } | 857 } |
864 | 858 |
865 Future<ServiceObject> _streamListen(String streamId) { | 859 Future<ServiceObject> _streamListen(String streamId) { |
866 Map params = { | 860 Map params = { |
867 'streamId': streamId, | 861 'streamId': streamId, |
868 }; | 862 }; |
(...skipping 11 matching lines...) Expand all Loading... |
880 }; | 874 }; |
881 return invokeRpc('streamCancel', params).catchError((e) { | 875 return invokeRpc('streamCancel', params).catchError((e) { |
882 // Ignore network errors on stream cancel. | 876 // Ignore network errors on stream cancel. |
883 if (e is NetworkRpcException) { | 877 if (e is NetworkRpcException) { |
884 return null; | 878 return null; |
885 } | 879 } |
886 }); | 880 }); |
887 } | 881 } |
888 | 882 |
889 // A map from stream id to event stream state. | 883 // A map from stream id to event stream state. |
890 Map<String,_EventStreamState> _eventStreams = {}; | 884 Map<String, _EventStreamState> _eventStreams = {}; |
891 | 885 |
892 // Well-known stream ids. | 886 // Well-known stream ids. |
893 static const kVMStream = 'VM'; | 887 static const kVMStream = 'VM'; |
894 static const kIsolateStream = 'Isolate'; | 888 static const kIsolateStream = 'Isolate'; |
895 static const kTimelineStream = 'Timeline'; | 889 static const kTimelineStream = 'Timeline'; |
896 static const kDebugStream = 'Debug'; | 890 static const kDebugStream = 'Debug'; |
897 static const kGCStream = 'GC'; | 891 static const kGCStream = 'GC'; |
898 static const kStdoutStream = 'Stdout'; | 892 static const kStdoutStream = 'Stdout'; |
899 static const kStderrStream = 'Stderr'; | 893 static const kStderrStream = 'Stderr'; |
900 static const _kGraphStream = '_Graph'; | 894 static const _kGraphStream = '_Graph'; |
901 | 895 |
902 /// Returns a single-subscription Stream object for a VM event stream. | 896 /// Returns a single-subscription Stream object for a VM event stream. |
903 Future<Stream> getEventStream(String streamId) async { | 897 Future<Stream> getEventStream(String streamId) async { |
904 var eventStream = _eventStreams.putIfAbsent( | 898 var eventStream = _eventStreams.putIfAbsent( |
905 streamId, () => new _EventStreamState( | 899 streamId, |
| 900 () => new _EventStreamState( |
906 this, streamId, () => _eventStreams.remove(streamId))); | 901 this, streamId, () => _eventStreams.remove(streamId))); |
907 Stream stream = await eventStream.addStream(); | 902 Stream stream = await eventStream.addStream(); |
908 return stream; | 903 return stream; |
909 } | 904 } |
910 | 905 |
911 /// Helper function for listening to an event stream. | 906 /// Helper function for listening to an event stream. |
912 Future<StreamSubscription> listenEventStream(String streamId, | 907 Future<StreamSubscription> listenEventStream( |
913 Function function) async { | 908 String streamId, Function function) async { |
914 var stream = await getEventStream(streamId); | 909 var stream = await getEventStream(streamId); |
915 return stream.listen(function); | 910 return stream.listen(function); |
916 } | 911 } |
917 | 912 |
918 /// Force the VM to disconnect. | 913 /// Force the VM to disconnect. |
919 void disconnect(); | 914 void disconnect(); |
| 915 |
920 /// Completes when the VM first connects. | 916 /// Completes when the VM first connects. |
921 Future get onConnect; | 917 Future get onConnect; |
| 918 |
922 /// Completes when the VM disconnects or there was an error connecting. | 919 /// Completes when the VM disconnects or there was an error connecting. |
923 Future get onDisconnect; | 920 Future get onDisconnect; |
924 | 921 |
925 void _update(Map map, bool mapIsRef) { | 922 void _update(Map map, bool mapIsRef) { |
926 name = map['name']; | 923 name = map['name']; |
927 vmName = map.containsKey('_vmName') ? map['_vmName'] : name; | 924 vmName = map.containsKey('_vmName') ? map['_vmName'] : name; |
928 if (mapIsRef) { | 925 if (mapIsRef) { |
929 return; | 926 return; |
930 } | 927 } |
931 // Note that upgrading the collection creates any isolates in the | 928 // Note that upgrading the collection creates any isolates in the |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1002 | 999 |
1003 // Always connected. | 1000 // Always connected. |
1004 Future _onConnect; | 1001 Future _onConnect; |
1005 Future get onConnect { | 1002 Future get onConnect { |
1006 if (_onConnect != null) { | 1003 if (_onConnect != null) { |
1007 return _onConnect; | 1004 return _onConnect; |
1008 } | 1005 } |
1009 _onConnect = new Future.value(this); | 1006 _onConnect = new Future.value(this); |
1010 return _onConnect; | 1007 return _onConnect; |
1011 } | 1008 } |
| 1009 |
1012 bool get isConnected => !isDisconnected; | 1010 bool get isConnected => !isDisconnected; |
1013 // Only complete when requested. | 1011 // Only complete when requested. |
1014 Completer _onDisconnect = new Completer(); | 1012 Completer _onDisconnect = new Completer(); |
1015 Future get onDisconnect => _onDisconnect.future; | 1013 Future get onDisconnect => _onDisconnect.future; |
1016 bool get isDisconnected => _onDisconnect.isCompleted; | 1014 bool get isDisconnected => _onDisconnect.isCompleted; |
1017 | 1015 |
1018 Future<Map> invokeRpcRaw(String method, Map params) { | 1016 Future<Map> invokeRpcRaw(String method, Map params) { |
1019 if (params.isEmpty) { | 1017 if (params.isEmpty) { |
1020 params = null; | 1018 params = null; |
1021 } | 1019 } |
1022 var key = _canonicalizeUri(new Uri(path: method, queryParameters: params)); | 1020 var key = _canonicalizeUri(new Uri(path: method, queryParameters: params)); |
1023 var response = _responses[key]; | 1021 var response = _responses[key]; |
1024 if (response == null) { | 1022 if (response == null) { |
1025 return new Future.error(new FakeVMRpcException( | 1023 return new Future.error(new FakeVMRpcException( |
1026 "Unable to find key '${key}' in cached response set")); | 1024 "Unable to find key '${key}' in cached response set")); |
1027 } | 1025 } |
1028 return new Future.value(response); | 1026 return new Future.value(response); |
1029 } | 1027 } |
1030 } | 1028 } |
1031 | 1029 |
1032 | |
1033 /// Snapshot in time of tag counters. | 1030 /// Snapshot in time of tag counters. |
1034 class TagProfileSnapshot { | 1031 class TagProfileSnapshot { |
1035 final double seconds; | 1032 final double seconds; |
1036 final List<int> counters; | 1033 final List<int> counters; |
1037 int get sum => _sum; | 1034 int get sum => _sum; |
1038 int _sum = 0; | 1035 int _sum = 0; |
1039 TagProfileSnapshot(this.seconds, int countersLength) | 1036 TagProfileSnapshot(this.seconds, int countersLength) |
1040 : counters = new List<int>(countersLength); | 1037 : counters = new List<int>(countersLength); |
1041 | 1038 |
1042 /// Set [counters] and update [sum]. | 1039 /// Set [counters] and update [sum]. |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1110 if (snapshots.length > _historySize) { | 1107 if (snapshots.length > _historySize) { |
1111 snapshots.removeAt(0); | 1108 snapshots.removeAt(0); |
1112 } | 1109 } |
1113 } | 1110 } |
1114 } | 1111 } |
1115 | 1112 |
1116 class InboundReferences implements M.InboundReferences { | 1113 class InboundReferences implements M.InboundReferences { |
1117 final Iterable<InboundReference> elements; | 1114 final Iterable<InboundReference> elements; |
1118 | 1115 |
1119 InboundReferences(ServiceMap map) | 1116 InboundReferences(ServiceMap map) |
1120 : this.elements = map['references'] | 1117 : this.elements = |
1121 .map((rmap) => new InboundReference(rmap)); | 1118 map['references'].map((rmap) => new InboundReference(rmap)); |
1122 } | 1119 } |
1123 | 1120 |
1124 class InboundReference implements M.InboundReference { | 1121 class InboundReference implements M.InboundReference { |
1125 final HeapObject source; | 1122 final HeapObject source; |
1126 final Instance parentField; | 1123 final Instance parentField; |
1127 final int parentListIndex; | 1124 final int parentListIndex; |
1128 final int parentWordOffset; | 1125 final int parentWordOffset; |
1129 | 1126 |
1130 InboundReference(ServiceMap map) | 1127 InboundReference(ServiceMap map) |
1131 : source = map['source'], | 1128 : source = map['source'], |
1132 parentField = map['parentField'], | 1129 parentField = map['parentField'], |
1133 parentListIndex = map['parentListIndex'], | 1130 parentListIndex = map['parentListIndex'], |
1134 parentWordOffset = map['_parentWordOffset']; | 1131 parentWordOffset = map['_parentWordOffset']; |
1135 } | 1132 } |
1136 | 1133 |
1137 class RetainingPath implements M.RetainingPath { | 1134 class RetainingPath implements M.RetainingPath { |
1138 final Iterable<RetainingPathItem> elements; | 1135 final Iterable<RetainingPathItem> elements; |
1139 | 1136 |
1140 RetainingPath(ServiceMap map) | 1137 RetainingPath(ServiceMap map) |
1141 : this.elements = map['elements'] | 1138 : this.elements = |
1142 .map((rmap) => new RetainingPathItem(rmap)); | 1139 map['elements'].map((rmap) => new RetainingPathItem(rmap)); |
1143 } | 1140 } |
1144 | 1141 |
1145 class RetainingPathItem implements M.RetainingPathItem { | 1142 class RetainingPathItem implements M.RetainingPathItem { |
1146 final HeapObject source; | 1143 final HeapObject source; |
1147 final Instance parentField; | 1144 final Instance parentField; |
1148 final int parentListIndex; | 1145 final int parentListIndex; |
1149 final int parentWordOffset; | 1146 final int parentWordOffset; |
1150 | 1147 |
1151 RetainingPathItem(ServiceMap map) | 1148 RetainingPathItem(ServiceMap map) |
1152 : source = map['value'], | 1149 : source = map['value'], |
1153 parentField = map['parentField'], | 1150 parentField = map['parentField'], |
1154 parentListIndex = map['parentListIndex'], | 1151 parentListIndex = map['parentListIndex'], |
1155 parentWordOffset = map['_parentWordOffset']; | 1152 parentWordOffset = map['_parentWordOffset']; |
1156 } | 1153 } |
1157 | 1154 |
1158 class Ports implements M.Ports { | 1155 class Ports implements M.Ports { |
1159 final Iterable<Port> elements; | 1156 final Iterable<Port> elements; |
1160 | 1157 |
1161 Ports(ServiceMap map) | 1158 Ports(ServiceMap map) |
1162 : this.elements = map['ports'] | 1159 : this.elements = map['ports'].map((rmap) => new Port(rmap)); |
1163 .map((rmap) => new Port(rmap)); | |
1164 } | 1160 } |
1165 | 1161 |
1166 class Port implements M.Port { | 1162 class Port implements M.Port { |
1167 final String name; | 1163 final String name; |
1168 final HeapObject handler; | 1164 final HeapObject handler; |
1169 | 1165 |
1170 Port(ServiceMap map) | 1166 Port(ServiceMap map) |
1171 : name = map['name'], | 1167 : name = map['name'], |
1172 handler = map['handler']; | 1168 handler = map['handler']; |
1173 } | 1169 } |
1174 | 1170 |
1175 class PersistentHandles implements M.PersistentHandles { | 1171 class PersistentHandles implements M.PersistentHandles { |
1176 final Iterable<PersistentHandle> elements; | 1172 final Iterable<PersistentHandle> elements; |
1177 final Iterable<WeakPersistentHandle> weakElements; | 1173 final Iterable<WeakPersistentHandle> weakElements; |
1178 | 1174 |
1179 PersistentHandles(ServiceMap map) | 1175 PersistentHandles(ServiceMap map) |
1180 : this.elements = map['persistentHandles'] | 1176 : this.elements = |
1181 .map((rmap) => new PersistentHandle(rmap)), | 1177 map['persistentHandles'].map((rmap) => new PersistentHandle(rmap)), |
1182 this.weakElements = map['weakPersistentHandles'] | 1178 this.weakElements = map['weakPersistentHandles'] |
1183 .map((rmap) => new WeakPersistentHandle(rmap)); | 1179 .map((rmap) => new WeakPersistentHandle(rmap)); |
1184 } | 1180 } |
1185 | 1181 |
1186 class PersistentHandle implements M.PersistentHandle { | 1182 class PersistentHandle implements M.PersistentHandle { |
1187 final HeapObject object; | 1183 final HeapObject object; |
1188 | 1184 |
1189 PersistentHandle(ServiceMap map) | 1185 PersistentHandle(ServiceMap map) : object = map['object']; |
1190 : object = map['object']; | |
1191 } | 1186 } |
1192 | 1187 |
1193 class WeakPersistentHandle implements M.WeakPersistentHandle { | 1188 class WeakPersistentHandle implements M.WeakPersistentHandle { |
1194 final int externalSize; | 1189 final int externalSize; |
1195 final String peer; | 1190 final String peer; |
1196 final String callbackSymbolName; | 1191 final String callbackSymbolName; |
1197 final String callbackAddress; | 1192 final String callbackAddress; |
1198 final HeapObject object; | 1193 final HeapObject object; |
1199 | 1194 |
1200 WeakPersistentHandle(ServiceMap map) | 1195 WeakPersistentHandle(ServiceMap map) |
1201 : externalSize = int.parse(map['externalSize']), | 1196 : externalSize = int.parse(map['externalSize']), |
1202 peer = map['peer'], | 1197 peer = map['peer'], |
1203 callbackSymbolName = map['callbackSymbolName'], | 1198 callbackSymbolName = map['callbackSymbolName'], |
1204 callbackAddress = map['callbackAddress'], | 1199 callbackAddress = map['callbackAddress'], |
1205 object = map['object']; | 1200 object = map['object']; |
1206 } | 1201 } |
1207 | 1202 |
1208 class HeapSpace implements M.HeapSpace { | 1203 class HeapSpace implements M.HeapSpace { |
1209 int used = 0; | 1204 int used = 0; |
1210 int capacity = 0; | 1205 int capacity = 0; |
1211 int external = 0; | 1206 int external = 0; |
1212 int collections = 0; | 1207 int collections = 0; |
1213 double totalCollectionTimeInSeconds = 0.0; | 1208 double totalCollectionTimeInSeconds = 0.0; |
1214 double averageCollectionPeriodInMillis = 0.0; | 1209 double averageCollectionPeriodInMillis = 0.0; |
1215 | 1210 |
1216 Duration get avgCollectionTime { | 1211 Duration get avgCollectionTime { |
1217 final mcs = totalCollectionTimeInSeconds * Duration.MICROSECONDS_PER_SECOND | 1212 final mcs = totalCollectionTimeInSeconds * |
1218 / math.max(collections, 1); | 1213 Duration.MICROSECONDS_PER_SECOND / |
| 1214 math.max(collections, 1); |
1219 return new Duration(microseconds: mcs.ceil()); | 1215 return new Duration(microseconds: mcs.ceil()); |
1220 } | 1216 } |
1221 | 1217 |
1222 Duration get totalCollectionTime { | 1218 Duration get totalCollectionTime { |
1223 final mcs = totalCollectionTimeInSeconds * Duration.MICROSECONDS_PER_SECOND; | 1219 final mcs = totalCollectionTimeInSeconds * Duration.MICROSECONDS_PER_SECOND; |
1224 return new Duration(microseconds: mcs.ceil()); | 1220 return new Duration(microseconds: mcs.ceil()); |
1225 } | 1221 } |
1226 | 1222 |
1227 Duration get avgCollectionPeriod { | 1223 Duration get avgCollectionPeriod { |
1228 final mcs = averageCollectionPeriodInMillis | 1224 final mcs = |
1229 * Duration.MICROSECONDS_PER_MILLISECOND; | 1225 averageCollectionPeriodInMillis * Duration.MICROSECONDS_PER_MILLISECOND; |
1230 return new Duration(microseconds: mcs.ceil()); | 1226 return new Duration(microseconds: mcs.ceil()); |
1231 } | 1227 } |
1232 | 1228 |
1233 void update(Map heapMap) { | 1229 void update(Map heapMap) { |
1234 used = heapMap['used']; | 1230 used = heapMap['used']; |
1235 capacity = heapMap['capacity']; | 1231 capacity = heapMap['capacity']; |
1236 external = heapMap['external']; | 1232 external = heapMap['external']; |
1237 collections = heapMap['collections']; | 1233 collections = heapMap['collections']; |
1238 totalCollectionTimeInSeconds = heapMap['time']; | 1234 totalCollectionTimeInSeconds = heapMap['time']; |
1239 averageCollectionPeriodInMillis = heapMap['avgCollectionPeriodMillis']; | 1235 averageCollectionPeriodInMillis = heapMap['avgCollectionPeriodMillis']; |
(...skipping 20 matching lines...) Expand all Loading... |
1260 if (startTime == null) { | 1256 if (startTime == null) { |
1261 return null; | 1257 return null; |
1262 } | 1258 } |
1263 return (new DateTime.now().difference(startTime)); | 1259 return (new DateTime.now().difference(startTime)); |
1264 } | 1260 } |
1265 | 1261 |
1266 Map counters = {}; | 1262 Map counters = {}; |
1267 | 1263 |
1268 void _updateRunState() { | 1264 void _updateRunState() { |
1269 topFrame = M.topFrame(pauseEvent); | 1265 topFrame = M.topFrame(pauseEvent); |
1270 paused = (pauseEvent != null && | 1266 paused = (pauseEvent != null && !(pauseEvent is M.ResumeEvent)); |
1271 !(pauseEvent is M.ResumeEvent)); | |
1272 running = (!paused && topFrame != null); | 1267 running = (!paused && topFrame != null); |
1273 idle = (!paused && topFrame == null); | 1268 idle = (!paused && topFrame == null); |
1274 } | 1269 } |
1275 | 1270 |
1276 M.DebugEvent pauseEvent = null; | 1271 M.DebugEvent pauseEvent = null; |
1277 bool paused = false; | 1272 bool paused = false; |
1278 bool running = false; | 1273 bool running = false; |
1279 bool idle = false; | 1274 bool idle = false; |
1280 bool loading = true; | 1275 bool loading = true; |
1281 bool runnable = false; | 1276 bool runnable = false; |
1282 bool ioEnabled = false; | 1277 bool ioEnabled = false; |
1283 bool reloading = false; | 1278 bool reloading = false; |
1284 M.IsolateStatus get status { | 1279 M.IsolateStatus get status { |
1285 if (paused) { | 1280 if (paused) { |
1286 return M.IsolateStatus.paused; | 1281 return M.IsolateStatus.paused; |
1287 } | 1282 } |
1288 if (running) { | 1283 if (running) { |
1289 return M.IsolateStatus.running; | 1284 return M.IsolateStatus.running; |
1290 } | 1285 } |
1291 if (idle) { | 1286 if (idle) { |
1292 return M.IsolateStatus.idle; | 1287 return M.IsolateStatus.idle; |
1293 } | 1288 } |
1294 return M.IsolateStatus.loading; | 1289 return M.IsolateStatus.loading; |
1295 } | 1290 } |
1296 | 1291 |
1297 final List<String> extensionRPCs = new List<String>(); | 1292 final List<String> extensionRPCs = new List<String>(); |
1298 | 1293 |
1299 Map<String,ServiceObject> _cache = new Map<String,ServiceObject>(); | 1294 Map<String, ServiceObject> _cache = new Map<String, ServiceObject>(); |
1300 final TagProfile tagProfile = new TagProfile(20); | 1295 final TagProfile tagProfile = new TagProfile(20); |
1301 | 1296 |
1302 Isolate._empty(ServiceObjectOwner owner) : super._empty(owner) { | 1297 Isolate._empty(ServiceObjectOwner owner) : super._empty(owner) { |
1303 assert(owner is VM); | 1298 assert(owner is VM); |
1304 } | 1299 } |
1305 | 1300 |
1306 void resetCachedProfileData() { | 1301 void resetCachedProfileData() { |
1307 _cache.values.forEach((value) { | 1302 _cache.values.forEach((value) { |
1308 if (value is Code) { | 1303 if (value is Code) { |
1309 Code code = value; | 1304 Code code = value; |
1310 code.profile = null; | 1305 code.profile = null; |
1311 } else if (value is ServiceFunction) { | 1306 } else if (value is ServiceFunction) { |
1312 ServiceFunction function = value; | 1307 ServiceFunction function = value; |
1313 function.profile = null; | 1308 function.profile = null; |
1314 } | 1309 } |
1315 }); | 1310 }); |
1316 } | 1311 } |
1317 | 1312 |
1318 static const kCallSitesReport = '_CallSites'; | 1313 static const kCallSitesReport = '_CallSites'; |
1319 static const kPossibleBreakpointsReport = 'PossibleBreakpoints'; | 1314 static const kPossibleBreakpointsReport = 'PossibleBreakpoints'; |
1320 static const kProfileReport = '_Profile'; | 1315 static const kProfileReport = '_Profile'; |
1321 | 1316 |
1322 Future<ServiceMap> getSourceReport(List<String> report_kinds, | 1317 Future<ServiceMap> getSourceReport(List<String> report_kinds, |
1323 [Script script, | 1318 [Script script, int startPos, int endPos]) { |
1324 int startPos, | 1319 var params = {'reports': report_kinds}; |
1325 int endPos]) { | |
1326 var params = { 'reports' : report_kinds }; | |
1327 if (script != null) { | 1320 if (script != null) { |
1328 params['scriptId'] = script.id; | 1321 params['scriptId'] = script.id; |
1329 } | 1322 } |
1330 if (startPos != null) { | 1323 if (startPos != null) { |
1331 params['tokenPos'] = startPos; | 1324 params['tokenPos'] = startPos; |
1332 } | 1325 } |
1333 if (endPos != null) { | 1326 if (endPos != null) { |
1334 params['endTokenPos'] = endPos; | 1327 params['endTokenPos'] = endPos; |
1335 } | 1328 } |
1336 return invokeRpc('getSourceReport', params); | 1329 return invokeRpc('getSourceReport', params); |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1444 return vm.invokeRpcNoUpgrade(method, params); | 1437 return vm.invokeRpcNoUpgrade(method, params); |
1445 } | 1438 } |
1446 | 1439 |
1447 Future<ServiceObject> invokeRpc(String method, Map params) { | 1440 Future<ServiceObject> invokeRpc(String method, Map params) { |
1448 return invokeRpcNoUpgrade(method, params).then((Map response) { | 1441 return invokeRpcNoUpgrade(method, params).then((Map response) { |
1449 return getFromMap(response); | 1442 return getFromMap(response); |
1450 }); | 1443 }); |
1451 } | 1444 } |
1452 | 1445 |
1453 Future<ServiceObject> getObject(String objectId, | 1446 Future<ServiceObject> getObject(String objectId, |
1454 {bool reload: true, | 1447 {bool reload: true, int count: kDefaultFieldLimit}) { |
1455 int count: kDefaultFieldLimit}) { | |
1456 assert(objectId != null && objectId != ''); | 1448 assert(objectId != null && objectId != ''); |
1457 var obj = _cache[objectId]; | 1449 var obj = _cache[objectId]; |
1458 if (obj != null) { | 1450 if (obj != null) { |
1459 if (reload) { | 1451 if (reload) { |
1460 return obj.reload(count: count); | 1452 return obj.reload(count: count); |
1461 } | 1453 } |
1462 // Returned cached object. | 1454 // Returned cached object. |
1463 return new Future.value(obj); | 1455 return new Future.value(obj); |
1464 } | 1456 } |
1465 Map params = { | 1457 Map params = { |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1513 _snapshotFetch.add([chunkIndex, chunkCount]); | 1505 _snapshotFetch.add([chunkIndex, chunkCount]); |
1514 | 1506 |
1515 for (var i = 0; i < chunkCount; i++) { | 1507 for (var i = 0; i < chunkCount; i++) { |
1516 if (_chunksInProgress[i] == null) return; | 1508 if (_chunksInProgress[i] == null) return; |
1517 } | 1509 } |
1518 | 1510 |
1519 var loadedChunks = _chunksInProgress; | 1511 var loadedChunks = _chunksInProgress; |
1520 _chunksInProgress = null; | 1512 _chunksInProgress = null; |
1521 | 1513 |
1522 if (_snapshotFetch != null) { | 1514 if (_snapshotFetch != null) { |
1523 _snapshotFetch.add( | 1515 _snapshotFetch.add(new RawHeapSnapshot(loadedChunks, event.nodeCount)); |
1524 new RawHeapSnapshot(loadedChunks, event.nodeCount)); | |
1525 _snapshotFetch.close(); | 1516 _snapshotFetch.close(); |
1526 } | 1517 } |
1527 } | 1518 } |
1528 | 1519 |
1529 Stream fetchHeapSnapshot(collectGarbage) { | 1520 Stream fetchHeapSnapshot(collectGarbage) { |
1530 if (_snapshotFetch == null || _snapshotFetch.isClosed) { | 1521 if (_snapshotFetch == null || _snapshotFetch.isClosed) { |
1531 _snapshotFetch = new StreamController.broadcast(); | 1522 _snapshotFetch = new StreamController.broadcast(); |
1532 // isolate.vm.streamListen('_Graph'); | 1523 // isolate.vm.streamListen('_Graph'); |
1533 isolate.invokeRpcNoUpgrade('_requestHeapSnapshot', | 1524 isolate.invokeRpcNoUpgrade( |
1534 {'collectGarbage': collectGarbage}); | 1525 '_requestHeapSnapshot', {'collectGarbage': collectGarbage}); |
1535 } | 1526 } |
1536 return _snapshotFetch.stream; | 1527 return _snapshotFetch.stream; |
1537 } | 1528 } |
1538 | 1529 |
1539 void updateHeapsFromMap(Map map) { | 1530 void updateHeapsFromMap(Map map) { |
1540 newSpace.update(map['new']); | 1531 newSpace.update(map['new']); |
1541 oldSpace.update(map['old']); | 1532 oldSpace.update(map['old']); |
1542 } | 1533 } |
1543 | 1534 |
1544 void _update(Map map, bool mapIsRef) { | 1535 void _update(Map map, bool mapIsRef) { |
1545 name = map['name']; | 1536 name = map['name']; |
1546 vmName = map.containsKey('_vmName') ? map['_vmName'] : name; | 1537 vmName = map.containsKey('_vmName') ? map['_vmName'] : name; |
1547 number = int.parse(map['number'], onError:(_) => null); | 1538 number = int.parse(map['number'], onError: (_) => null); |
1548 if (mapIsRef) { | 1539 if (mapIsRef) { |
1549 return; | 1540 return; |
1550 } | 1541 } |
1551 _loaded = true; | 1542 _loaded = true; |
1552 loading = false; | 1543 loading = false; |
1553 runnable = map['runnable'] == true; | 1544 runnable = map['runnable'] == true; |
1554 _upgradeCollection(map, isolate); | 1545 _upgradeCollection(map, isolate); |
1555 originNumber = int.parse(map['_originNumber'], onError:(_) => null); | 1546 originNumber = int.parse(map['_originNumber'], onError: (_) => null); |
1556 rootLibrary = map['rootLib']; | 1547 rootLibrary = map['rootLib']; |
1557 if (map['entry'] != null) { | 1548 if (map['entry'] != null) { |
1558 entry = map['entry']; | 1549 entry = map['entry']; |
1559 } | 1550 } |
1560 var savedStartTime = startTime; | 1551 var savedStartTime = startTime; |
1561 int startTimeInMillis = map['startTime']; | 1552 int startTimeInMillis = map['startTime']; |
1562 startTime = new DateTime.fromMillisecondsSinceEpoch(startTimeInMillis); | 1553 startTime = new DateTime.fromMillisecondsSinceEpoch(startTimeInMillis); |
1563 var countersMap = map['_tagCounters']; | 1554 var countersMap = map['_tagCounters']; |
1564 if (countersMap != null) { | 1555 if (countersMap != null) { |
1565 var names = countersMap['names']; | 1556 var names = countersMap['names']; |
(...skipping 20 matching lines...) Expand all Loading... |
1586 updateHeapsFromMap(map['_heaps']); | 1577 updateHeapsFromMap(map['_heaps']); |
1587 _updateBreakpoints(map['breakpoints']); | 1578 _updateBreakpoints(map['breakpoints']); |
1588 if (map['_debuggerSettings'] != null) { | 1579 if (map['_debuggerSettings'] != null) { |
1589 exceptionsPauseInfo = map['_debuggerSettings']['_exceptions']; | 1580 exceptionsPauseInfo = map['_debuggerSettings']['_exceptions']; |
1590 } else { | 1581 } else { |
1591 exceptionsPauseInfo = "none"; | 1582 exceptionsPauseInfo = "none"; |
1592 } | 1583 } |
1593 | 1584 |
1594 var newPauseEvent = map['pauseEvent']; | 1585 var newPauseEvent = map['pauseEvent']; |
1595 assert((pauseEvent == null) || | 1586 assert((pauseEvent == null) || |
1596 (newPauseEvent == null) || | 1587 (newPauseEvent == null) || |
1597 !newPauseEvent.timestamp.isBefore(pauseEvent.timestamp)); | 1588 !newPauseEvent.timestamp.isBefore(pauseEvent.timestamp)); |
1598 pauseEvent = createEventFromServiceEvent(newPauseEvent); | 1589 pauseEvent = createEventFromServiceEvent(newPauseEvent); |
1599 _updateRunState(); | 1590 _updateRunState(); |
1600 error = map['error']; | 1591 error = map['error']; |
1601 | 1592 |
1602 libraries.clear(); | 1593 libraries.clear(); |
1603 libraries.addAll(map['libraries']); | 1594 libraries.addAll(map['libraries']); |
1604 libraries.sort(ServiceObject.LexicalSortName); | 1595 libraries.sort(ServiceObject.LexicalSortName); |
1605 if (savedStartTime == null) { | 1596 if (savedStartTime == null) { |
1606 vm._buildIsolateList(); | 1597 vm._buildIsolateList(); |
1607 } | 1598 } |
1608 | 1599 |
1609 extensionRPCs.clear(); | 1600 extensionRPCs.clear(); |
1610 if (map['extensionRPCs'] != null) { | 1601 if (map['extensionRPCs'] != null) { |
1611 extensionRPCs.addAll(map['extensionRPCs']); | 1602 extensionRPCs.addAll(map['extensionRPCs']); |
1612 } | 1603 } |
1613 } | 1604 } |
1614 | 1605 |
1615 Future<TagProfile> updateTagProfile() { | 1606 Future<TagProfile> updateTagProfile() { |
1616 return isolate.invokeRpcNoUpgrade('_getTagProfile', {}).then( | 1607 return isolate.invokeRpcNoUpgrade('_getTagProfile', {}).then((Map map) { |
1617 (Map map) { | 1608 var seconds = new DateTime.now().millisecondsSinceEpoch / 1000.0; |
1618 var seconds = new DateTime.now().millisecondsSinceEpoch / 1000.0; | 1609 tagProfile._processTagProfile(seconds, map); |
1619 tagProfile._processTagProfile(seconds, map); | 1610 return tagProfile; |
1620 return tagProfile; | 1611 }); |
1621 }); | |
1622 } | 1612 } |
1623 | 1613 |
1624 Map<int, Breakpoint> breakpoints = <int, Breakpoint>{}; | 1614 Map<int, Breakpoint> breakpoints = <int, Breakpoint>{}; |
1625 String exceptionsPauseInfo; | 1615 String exceptionsPauseInfo; |
1626 | 1616 |
1627 void _updateBreakpoints(List newBpts) { | 1617 void _updateBreakpoints(List newBpts) { |
1628 // Build a set of new breakpoints. | 1618 // Build a set of new breakpoints. |
1629 var newBptSet = new Set(); | 1619 var newBptSet = new Set(); |
1630 newBpts.forEach((bpt) => newBptSet.add(bpt.number)); | 1620 newBpts.forEach((bpt) => newBptSet.add(bpt.number)); |
1631 | 1621 |
(...skipping 13 matching lines...) Expand all Loading... |
1645 void _addBreakpoint(Breakpoint bpt) { | 1635 void _addBreakpoint(Breakpoint bpt) { |
1646 breakpoints[bpt.number] = bpt; | 1636 breakpoints[bpt.number] = bpt; |
1647 } | 1637 } |
1648 | 1638 |
1649 void _removeBreakpoint(Breakpoint bpt) { | 1639 void _removeBreakpoint(Breakpoint bpt) { |
1650 breakpoints.remove(bpt.number); | 1640 breakpoints.remove(bpt.number); |
1651 bpt.remove(); | 1641 bpt.remove(); |
1652 } | 1642 } |
1653 | 1643 |
1654 void _onEvent(ServiceEvent event) { | 1644 void _onEvent(ServiceEvent event) { |
1655 switch(event.kind) { | 1645 switch (event.kind) { |
1656 case ServiceEvent.kIsolateStart: | 1646 case ServiceEvent.kIsolateStart: |
1657 case ServiceEvent.kIsolateRunnable: | 1647 case ServiceEvent.kIsolateRunnable: |
1658 case ServiceEvent.kIsolateExit: | 1648 case ServiceEvent.kIsolateExit: |
1659 case ServiceEvent.kInspect: | 1649 case ServiceEvent.kInspect: |
1660 // Handled elsewhere. | 1650 // Handled elsewhere. |
1661 break; | 1651 break; |
1662 case ServiceEvent.kIsolateReload: | 1652 case ServiceEvent.kIsolateReload: |
1663 _handleIsolateReloadEvent(event); | 1653 _handleIsolateReloadEvent(event); |
1664 break; | 1654 break; |
1665 case ServiceEvent.kBreakpointAdded: | 1655 case ServiceEvent.kBreakpointAdded: |
(...skipping 11 matching lines...) Expand all Loading... |
1677 break; | 1667 break; |
1678 | 1668 |
1679 case ServiceEvent.kPauseStart: | 1669 case ServiceEvent.kPauseStart: |
1680 case ServiceEvent.kPauseExit: | 1670 case ServiceEvent.kPauseExit: |
1681 case ServiceEvent.kPauseBreakpoint: | 1671 case ServiceEvent.kPauseBreakpoint: |
1682 case ServiceEvent.kPauseInterrupted: | 1672 case ServiceEvent.kPauseInterrupted: |
1683 case ServiceEvent.kPauseException: | 1673 case ServiceEvent.kPauseException: |
1684 case ServiceEvent.kNone: | 1674 case ServiceEvent.kNone: |
1685 case ServiceEvent.kResume: | 1675 case ServiceEvent.kResume: |
1686 assert((pauseEvent == null) || | 1676 assert((pauseEvent == null) || |
1687 !event.timestamp.isBefore(pauseEvent.timestamp)); | 1677 !event.timestamp.isBefore(pauseEvent.timestamp)); |
1688 pauseEvent = createEventFromServiceEvent(event); | 1678 pauseEvent = createEventFromServiceEvent(event); |
1689 _updateRunState(); | 1679 _updateRunState(); |
1690 break; | 1680 break; |
1691 | 1681 |
1692 case ServiceEvent.kGraph: | 1682 case ServiceEvent.kGraph: |
1693 _loadHeapSnapshot(event); | 1683 _loadHeapSnapshot(event); |
1694 break; | 1684 break; |
1695 | 1685 |
1696 case ServiceEvent.kGC: | 1686 case ServiceEvent.kGC: |
1697 // Ignore GC events for now. | 1687 // Ignore GC events for now. |
(...skipping 10 matching lines...) Expand all Loading... |
1708 Map params = { | 1698 Map params = { |
1709 'scriptId': script.id, | 1699 'scriptId': script.id, |
1710 'line': line, | 1700 'line': line, |
1711 }; | 1701 }; |
1712 if (col != null) { | 1702 if (col != null) { |
1713 params['column'] = col; | 1703 params['column'] = col; |
1714 } | 1704 } |
1715 return invokeRpc('addBreakpoint', params); | 1705 return invokeRpc('addBreakpoint', params); |
1716 } | 1706 } |
1717 | 1707 |
1718 Future<ServiceObject> addBreakpointByScriptUri( | 1708 Future<ServiceObject> addBreakpointByScriptUri(String uri, int line, |
1719 String uri, int line, [int col]) { | 1709 [int col]) { |
1720 Map params = { | 1710 Map params = { |
1721 'scriptUri': uri, | 1711 'scriptUri': uri, |
1722 'line': line.toString(), | 1712 'line': line.toString(), |
1723 }; | 1713 }; |
1724 if (col != null) { | 1714 if (col != null) { |
1725 params['column'] = col.toString(); | 1715 params['column'] = col.toString(); |
1726 } | 1716 } |
1727 return invokeRpc('addBreakpointWithScriptUri', params); | 1717 return invokeRpc('addBreakpointWithScriptUri', params); |
1728 } | 1718 } |
1729 | 1719 |
1730 Future<ServiceObject> addBreakpointAtEntry(ServiceFunction function) { | 1720 Future<ServiceObject> addBreakpointAtEntry(ServiceFunction function) { |
1731 return invokeRpc('addBreakpointAtEntry', | 1721 return invokeRpc('addBreakpointAtEntry', {'functionId': function.id}); |
1732 { 'functionId': function.id }); | |
1733 } | 1722 } |
1734 | 1723 |
1735 Future<ServiceObject> addBreakOnActivation(Instance closure) { | 1724 Future<ServiceObject> addBreakOnActivation(Instance closure) { |
1736 return invokeRpc('_addBreakpointAtActivation', | 1725 return invokeRpc('_addBreakpointAtActivation', {'objectId': closure.id}); |
1737 { 'objectId': closure.id }); | |
1738 } | 1726 } |
1739 | 1727 |
1740 Future removeBreakpoint(Breakpoint bpt) { | 1728 Future removeBreakpoint(Breakpoint bpt) { |
1741 return invokeRpc('removeBreakpoint', | 1729 return invokeRpc('removeBreakpoint', {'breakpointId': bpt.id}); |
1742 { 'breakpointId': bpt.id }); | |
1743 } | 1730 } |
1744 | 1731 |
1745 Future pause() { | 1732 Future pause() { |
1746 return invokeRpc('pause', {}); | 1733 return invokeRpc('pause', {}); |
1747 } | 1734 } |
1748 | 1735 |
1749 Future resume() { | 1736 Future resume() { |
1750 return invokeRpc('resume', {}); | 1737 return invokeRpc('resume', {}); |
1751 } | 1738 } |
1752 | 1739 |
(...skipping 26 matching lines...) Expand all Loading... |
1779 } | 1766 } |
1780 | 1767 |
1781 Future<ObjectStore> getObjectStore() { | 1768 Future<ObjectStore> getObjectStore() { |
1782 return invokeRpcNoUpgrade('_getObjectStore', {}).then((map) { | 1769 return invokeRpcNoUpgrade('_getObjectStore', {}).then((map) { |
1783 ObjectStore objectStore = new ObjectStore._empty(this); | 1770 ObjectStore objectStore = new ObjectStore._empty(this); |
1784 objectStore._update(map, false); | 1771 objectStore._update(map, false); |
1785 return objectStore; | 1772 return objectStore; |
1786 }); | 1773 }); |
1787 } | 1774 } |
1788 | 1775 |
1789 Future<ServiceObject> eval(ServiceObject target, | 1776 Future<ServiceObject> eval(ServiceObject target, String expression) { |
1790 String expression) { | |
1791 Map params = { | 1777 Map params = { |
1792 'targetId': target.id, | 1778 'targetId': target.id, |
1793 'expression': expression, | 1779 'expression': expression, |
1794 }; | 1780 }; |
1795 return invokeRpc('evaluate', params); | 1781 return invokeRpc('evaluate', params); |
1796 } | 1782 } |
1797 | 1783 |
1798 Future<ServiceObject> evalFrame(int frameIndex, | 1784 Future<ServiceObject> evalFrame(int frameIndex, String expression) { |
1799 String expression) { | |
1800 Map params = { | 1785 Map params = { |
1801 'frameIndex': frameIndex, | 1786 'frameIndex': frameIndex, |
1802 'expression': expression, | 1787 'expression': expression, |
1803 }; | 1788 }; |
1804 return invokeRpc('evaluateInFrame', params); | 1789 return invokeRpc('evaluateInFrame', params); |
1805 } | 1790 } |
1806 | 1791 |
1807 Future<ServiceObject> getReachableSize(ServiceObject target) { | 1792 Future<ServiceObject> getReachableSize(ServiceObject target) { |
1808 Map params = { | 1793 Map params = { |
1809 'targetId': target.id, | 1794 'targetId': target.id, |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1842 } | 1827 } |
1843 | 1828 |
1844 Future<ServiceObject> getInstances(Class cls, var limit) { | 1829 Future<ServiceObject> getInstances(Class cls, var limit) { |
1845 Map params = { | 1830 Map params = { |
1846 'classId': cls.id, | 1831 'classId': cls.id, |
1847 'limit': limit.toString(), | 1832 'limit': limit.toString(), |
1848 }; | 1833 }; |
1849 return invokeRpc('_getInstances', params); | 1834 return invokeRpc('_getInstances', params); |
1850 } | 1835 } |
1851 | 1836 |
1852 Future<ServiceObject> getObjectByAddress(String address, [bool ref=true]) { | 1837 Future<ServiceObject> getObjectByAddress(String address, [bool ref = true]) { |
1853 Map params = { | 1838 Map params = { |
1854 'address': address, | 1839 'address': address, |
1855 'ref': ref, | 1840 'ref': ref, |
1856 }; | 1841 }; |
1857 return invokeRpc('_getObjectByAddress', params); | 1842 return invokeRpc('_getObjectByAddress', params); |
1858 } | 1843 } |
1859 | 1844 |
1860 final Map<String, ServiceMetric> dartMetrics = <String, ServiceMetric>{}; | 1845 final Map<String, ServiceMetric> dartMetrics = <String, ServiceMetric>{}; |
1861 | 1846 |
1862 final Map<String, ServiceMetric> nativeMetrics = <String, ServiceMetric>{}; | 1847 final Map<String, ServiceMetric> nativeMetrics = <String, ServiceMetric>{}; |
1863 | 1848 |
1864 Future<Map<String, ServiceMetric>> _refreshMetrics( | 1849 Future<Map<String, ServiceMetric>> _refreshMetrics( |
1865 String metricType, | 1850 String metricType, Map<String, ServiceMetric> metricsMap) { |
1866 Map<String, ServiceMetric> metricsMap) { | 1851 return invokeRpc('_getIsolateMetricList', {'type': metricType}) |
1867 return invokeRpc('_getIsolateMetricList', | 1852 .then((result) { |
1868 { 'type': metricType }).then((result) { | |
1869 // Clear metrics map. | 1853 // Clear metrics map. |
1870 metricsMap.clear(); | 1854 metricsMap.clear(); |
1871 // Repopulate metrics map. | 1855 // Repopulate metrics map. |
1872 var metrics = result['metrics']; | 1856 var metrics = result['metrics']; |
1873 for (var metric in metrics) { | 1857 for (var metric in metrics) { |
1874 metricsMap[metric.id] = metric; | 1858 metricsMap[metric.id] = metric; |
1875 } | 1859 } |
1876 return metricsMap; | 1860 return metricsMap; |
1877 }); | 1861 }); |
1878 } | 1862 } |
1879 | 1863 |
1880 Future<Map<String, ServiceMetric>> refreshDartMetrics() { | 1864 Future<Map<String, ServiceMetric>> refreshDartMetrics() { |
1881 return _refreshMetrics('Dart', dartMetrics); | 1865 return _refreshMetrics('Dart', dartMetrics); |
1882 } | 1866 } |
1883 | 1867 |
1884 Future<Map<String, ServiceMetric>> refreshNativeMetrics() { | 1868 Future<Map<String, ServiceMetric>> refreshNativeMetrics() { |
1885 return _refreshMetrics('Native', nativeMetrics); | 1869 return _refreshMetrics('Native', nativeMetrics); |
1886 } | 1870 } |
1887 | 1871 |
1888 Future refreshMetrics() { | 1872 Future refreshMetrics() { |
1889 return Future.wait([refreshDartMetrics(), refreshNativeMetrics()]); | 1873 return Future.wait([refreshDartMetrics(), refreshNativeMetrics()]); |
1890 } | 1874 } |
1891 | 1875 |
1892 String toString() => "Isolate($name)"; | 1876 String toString() => "Isolate($name)"; |
1893 } | 1877 } |
1894 | 1878 |
1895 | |
1896 class NamedField implements M.NamedField { | 1879 class NamedField implements M.NamedField { |
1897 final String name; | 1880 final String name; |
1898 final M.ObjectRef value; | 1881 final M.ObjectRef value; |
1899 NamedField(this.name, this.value); | 1882 NamedField(this.name, this.value); |
1900 } | 1883 } |
1901 | 1884 |
1902 | |
1903 class ObjectStore extends ServiceObject implements M.ObjectStore { | 1885 class ObjectStore extends ServiceObject implements M.ObjectStore { |
1904 List<NamedField> fields = new List<NamedField>(); | 1886 List<NamedField> fields = new List<NamedField>(); |
1905 | 1887 |
1906 ObjectStore._empty(ServiceObjectOwner owner) : super._empty(owner); | 1888 ObjectStore._empty(ServiceObjectOwner owner) : super._empty(owner); |
1907 | 1889 |
1908 void _update(Map map, bool mapIsRef) { | 1890 void _update(Map map, bool mapIsRef) { |
1909 // Extract full properties. | 1891 // Extract full properties. |
1910 _upgradeCollection(map, isolate); | 1892 _upgradeCollection(map, isolate); |
1911 | 1893 |
1912 if (mapIsRef) { | 1894 if (mapIsRef) { |
1913 return; | 1895 return; |
1914 } | 1896 } |
1915 | 1897 |
1916 fields.clear(); | 1898 fields.clear(); |
1917 map['fields'].forEach((key, value) { | 1899 map['fields'].forEach((key, value) { |
1918 fields.add(new NamedField(key, value)); | 1900 fields.add(new NamedField(key, value)); |
1919 }); | 1901 }); |
1920 _loaded = true; | 1902 _loaded = true; |
1921 } | 1903 } |
1922 } | 1904 } |
1923 | 1905 |
1924 | |
1925 /// A [ServiceObject] which implements [Map]. | 1906 /// A [ServiceObject] which implements [Map]. |
1926 class ServiceMap extends ServiceObject implements Map, M.UnknownObjectRef { | 1907 class ServiceMap extends ServiceObject implements Map, M.UnknownObjectRef { |
1927 final Map _map = {}; | 1908 final Map _map = {}; |
1928 static String objectIdRingPrefix = 'objects/'; | 1909 static String objectIdRingPrefix = 'objects/'; |
1929 | 1910 |
1930 bool get immutable => false; | 1911 bool get immutable => false; |
1931 | 1912 |
1932 ServiceMap._empty(ServiceObjectOwner owner) : super._empty(owner); | 1913 ServiceMap._empty(ServiceObjectOwner owner) : super._empty(owner); |
1933 | 1914 |
1934 void _update(Map map, bool mapIsRef) { | 1915 void _update(Map map, bool mapIsRef) { |
1935 _loaded = !mapIsRef; | 1916 _loaded = !mapIsRef; |
1936 | 1917 |
(...skipping 26 matching lines...) Expand all Loading... |
1963 bool get isEmpty => _map.isEmpty; | 1944 bool get isEmpty => _map.isEmpty; |
1964 bool get isNotEmpty => _map.isNotEmpty; | 1945 bool get isNotEmpty => _map.isNotEmpty; |
1965 Iterable get keys => _map.keys; | 1946 Iterable get keys => _map.keys; |
1966 Iterable get values => _map.values; | 1947 Iterable get values => _map.values; |
1967 int get length => _map.length; | 1948 int get length => _map.length; |
1968 | 1949 |
1969 String toString() => "ServiceMap($_map)"; | 1950 String toString() => "ServiceMap($_map)"; |
1970 } | 1951 } |
1971 | 1952 |
1972 M.ErrorKind stringToErrorKind(String value) { | 1953 M.ErrorKind stringToErrorKind(String value) { |
1973 switch(value) { | 1954 switch (value) { |
1974 case 'UnhandledException': return M.ErrorKind.unhandledException; | 1955 case 'UnhandledException': |
1975 case 'LanguageError': return M.ErrorKind.unhandledException; | 1956 return M.ErrorKind.unhandledException; |
1976 case 'InternalError': return M.ErrorKind.internalError; | 1957 case 'LanguageError': |
1977 case 'TerminationError': return M.ErrorKind.terminationError; | 1958 return M.ErrorKind.unhandledException; |
| 1959 case 'InternalError': |
| 1960 return M.ErrorKind.internalError; |
| 1961 case 'TerminationError': |
| 1962 return M.ErrorKind.terminationError; |
1978 } | 1963 } |
1979 Logger.root.severe('Unrecognized error kind: $value'); | 1964 Logger.root.severe('Unrecognized error kind: $value'); |
1980 throw new FallThroughError(); | 1965 throw new FallThroughError(); |
1981 } | 1966 } |
1982 | 1967 |
1983 /// A [DartError] is peered to a Dart Error object. | 1968 /// A [DartError] is peered to a Dart Error object. |
1984 class DartError extends ServiceObject implements M.Error { | 1969 class DartError extends ServiceObject implements M.Error { |
1985 DartError._empty(ServiceObject owner) : super._empty(owner); | 1970 DartError._empty(ServiceObject owner) : super._empty(owner); |
1986 | 1971 |
1987 M.ErrorKind kind; | 1972 M.ErrorKind kind; |
(...skipping 20 matching lines...) Expand all Loading... |
2008 if (level.value == value) { | 1993 if (level.value == value) { |
2009 return level; | 1994 return level; |
2010 } | 1995 } |
2011 } | 1996 } |
2012 return new Level('$value', value); | 1997 return new Level('$value', value); |
2013 } | 1998 } |
2014 | 1999 |
2015 /// A [ServiceEvent] is an asynchronous event notification from the vm. | 2000 /// A [ServiceEvent] is an asynchronous event notification from the vm. |
2016 class ServiceEvent extends ServiceObject { | 2001 class ServiceEvent extends ServiceObject { |
2017 /// The possible 'kind' values. | 2002 /// The possible 'kind' values. |
2018 static const kVMUpdate = 'VMUpdate'; | 2003 static const kVMUpdate = 'VMUpdate'; |
2019 static const kIsolateStart = 'IsolateStart'; | 2004 static const kIsolateStart = 'IsolateStart'; |
2020 static const kIsolateRunnable = 'IsolateRunnable'; | 2005 static const kIsolateRunnable = 'IsolateRunnable'; |
2021 static const kIsolateExit = 'IsolateExit'; | 2006 static const kIsolateExit = 'IsolateExit'; |
2022 static const kIsolateUpdate = 'IsolateUpdate'; | 2007 static const kIsolateUpdate = 'IsolateUpdate'; |
2023 static const kIsolateReload = 'IsolateReload'; | 2008 static const kIsolateReload = 'IsolateReload'; |
2024 static const kIsolateSpawn = 'IsolateSpawn'; | 2009 static const kIsolateSpawn = 'IsolateSpawn'; |
2025 static const kServiceExtensionAdded = 'ServiceExtensionAdded'; | 2010 static const kServiceExtensionAdded = 'ServiceExtensionAdded'; |
2026 static const kPauseStart = 'PauseStart'; | 2011 static const kPauseStart = 'PauseStart'; |
2027 static const kPauseExit = 'PauseExit'; | 2012 static const kPauseExit = 'PauseExit'; |
2028 static const kPauseBreakpoint = 'PauseBreakpoint'; | 2013 static const kPauseBreakpoint = 'PauseBreakpoint'; |
2029 static const kPauseInterrupted = 'PauseInterrupted'; | 2014 static const kPauseInterrupted = 'PauseInterrupted'; |
2030 static const kPauseException = 'PauseException'; | 2015 static const kPauseException = 'PauseException'; |
2031 static const kNone = 'None'; | 2016 static const kNone = 'None'; |
2032 static const kResume = 'Resume'; | 2017 static const kResume = 'Resume'; |
2033 static const kBreakpointAdded = 'BreakpointAdded'; | 2018 static const kBreakpointAdded = 'BreakpointAdded'; |
2034 static const kBreakpointResolved = 'BreakpointResolved'; | 2019 static const kBreakpointResolved = 'BreakpointResolved'; |
2035 static const kBreakpointRemoved = 'BreakpointRemoved'; | 2020 static const kBreakpointRemoved = 'BreakpointRemoved'; |
2036 static const kGraph = '_Graph'; | 2021 static const kGraph = '_Graph'; |
2037 static const kGC = 'GC'; | 2022 static const kGC = 'GC'; |
2038 static const kInspect = 'Inspect'; | 2023 static const kInspect = 'Inspect'; |
2039 static const kDebuggerSettingsUpdate = '_DebuggerSettingsUpdate'; | 2024 static const kDebuggerSettingsUpdate = '_DebuggerSettingsUpdate'; |
2040 static const kConnectionClosed = 'ConnectionClosed'; | 2025 static const kConnectionClosed = 'ConnectionClosed'; |
2041 static const kLogging = '_Logging'; | 2026 static const kLogging = '_Logging'; |
2042 static const kExtension = 'Extension'; | 2027 static const kExtension = 'Extension'; |
2043 | 2028 |
2044 ServiceEvent._empty(ServiceObjectOwner owner) : super._empty(owner); | 2029 ServiceEvent._empty(ServiceObjectOwner owner) : super._empty(owner); |
2045 | 2030 |
2046 ServiceEvent.connectionClosed(this.reason) : super._empty(null) { | 2031 ServiceEvent.connectionClosed(this.reason) : super._empty(null) { |
2047 kind = kConnectionClosed; | 2032 kind = kConnectionClosed; |
2048 } | 2033 } |
2049 | 2034 |
2050 String kind; | 2035 String kind; |
2051 DateTime timestamp; | 2036 DateTime timestamp; |
2052 List<M.Breakpoint> pauseBreakpoints; | 2037 List<M.Breakpoint> pauseBreakpoints; |
(...skipping 14 matching lines...) Expand all Loading... |
2067 String extensionKind; | 2052 String extensionKind; |
2068 Map extensionData; | 2053 Map extensionData; |
2069 List timelineEvents; | 2054 List timelineEvents; |
2070 String spawnToken; | 2055 String spawnToken; |
2071 String spawnError; | 2056 String spawnError; |
2072 | 2057 |
2073 int chunkIndex, chunkCount, nodeCount; | 2058 int chunkIndex, chunkCount, nodeCount; |
2074 | 2059 |
2075 bool get isPauseEvent { | 2060 bool get isPauseEvent { |
2076 return (kind == kPauseStart || | 2061 return (kind == kPauseStart || |
2077 kind == kPauseExit || | 2062 kind == kPauseExit || |
2078 kind == kPauseBreakpoint || | 2063 kind == kPauseBreakpoint || |
2079 kind == kPauseInterrupted || | 2064 kind == kPauseInterrupted || |
2080 kind == kPauseException || | 2065 kind == kPauseException || |
2081 kind == kNone); | 2066 kind == kNone); |
2082 } | 2067 } |
2083 | 2068 |
2084 void _update(Map map, bool mapIsRef) { | 2069 void _update(Map map, bool mapIsRef) { |
2085 _loaded = true; | 2070 _loaded = true; |
2086 _upgradeCollection(map, owner); | 2071 _upgradeCollection(map, owner); |
2087 | 2072 |
2088 assert(map['isolate'] == null || owner == map['isolate']); | 2073 assert(map['isolate'] == null || owner == map['isolate']); |
2089 timestamp = | 2074 timestamp = new DateTime.fromMillisecondsSinceEpoch(map['timestamp']); |
2090 new DateTime.fromMillisecondsSinceEpoch(map['timestamp']); | |
2091 kind = map['kind']; | 2075 kind = map['kind']; |
2092 name = 'ServiceEvent $kind'; | 2076 name = 'ServiceEvent $kind'; |
2093 vmName = name; | 2077 vmName = name; |
2094 if (map['breakpoint'] != null) { | 2078 if (map['breakpoint'] != null) { |
2095 breakpoint = map['breakpoint']; | 2079 breakpoint = map['breakpoint']; |
2096 } | 2080 } |
2097 if (map['pauseBreakpoints'] != null) { | 2081 if (map['pauseBreakpoints'] != null) { |
2098 pauseBreakpoints = map['pauseBreakpoints']; | 2082 pauseBreakpoints = map['pauseBreakpoints']; |
2099 if (pauseBreakpoints.length > 0) { | 2083 if (pauseBreakpoints.length > 0) { |
2100 breakpoint = pauseBreakpoints[0]; | 2084 breakpoint = pauseBreakpoints[0]; |
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2240 return 'Synthetic Async Continuation Breakpoint ${number}'; | 2224 return 'Synthetic Async Continuation Breakpoint ${number}'; |
2241 } else { | 2225 } else { |
2242 return 'Breakpoint ${number} at ${location}'; | 2226 return 'Breakpoint ${number} at ${location}'; |
2243 } | 2227 } |
2244 } else { | 2228 } else { |
2245 return 'Uninitialized breakpoint'; | 2229 return 'Uninitialized breakpoint'; |
2246 } | 2230 } |
2247 } | 2231 } |
2248 } | 2232 } |
2249 | 2233 |
2250 | |
2251 class LibraryDependency implements M.LibraryDependency { | 2234 class LibraryDependency implements M.LibraryDependency { |
2252 final bool isImport; | 2235 final bool isImport; |
2253 final bool isDeferred; | 2236 final bool isDeferred; |
2254 final String prefix; | 2237 final String prefix; |
2255 final Library target; | 2238 final Library target; |
2256 | 2239 |
2257 bool get isExport => !isImport; | 2240 bool get isExport => !isImport; |
2258 | 2241 |
2259 LibraryDependency._(this.isImport, this.isDeferred, this.prefix, this.target); | 2242 LibraryDependency._(this.isImport, this.isDeferred, this.prefix, this.target); |
2260 | 2243 |
2261 static _fromMap(map) => new LibraryDependency._(map["isImport"], | 2244 static _fromMap(map) => new LibraryDependency._( |
2262 map["isDeferred"], | 2245 map["isImport"], map["isDeferred"], map["prefix"], map["target"]); |
2263 map["prefix"], | |
2264 map["target"]); | |
2265 } | 2246 } |
2266 | 2247 |
2267 | |
2268 class Library extends HeapObject implements M.Library { | 2248 class Library extends HeapObject implements M.Library { |
2269 String uri; | 2249 String uri; |
2270 final dependencies = <LibraryDependency>[]; | 2250 final dependencies = <LibraryDependency>[]; |
2271 final scripts = <Script>[]; | 2251 final scripts = <Script>[]; |
2272 final classes = <Class>[]; | 2252 final classes = <Class>[]; |
2273 final variables = <Field>[]; | 2253 final variables = <Field>[]; |
2274 final functions = <ServiceFunction>[]; | 2254 final functions = <ServiceFunction>[]; |
2275 | 2255 |
2276 bool get immutable => false; | 2256 bool get immutable => false; |
2277 | 2257 |
2278 bool isDart(String libraryName) { | 2258 bool isDart(String libraryName) { |
2279 return uri == 'dart:$libraryName'; | 2259 return uri == 'dart:$libraryName'; |
2280 } | 2260 } |
2281 | 2261 |
2282 Library._empty(ServiceObjectOwner owner) : super._empty(owner); | 2262 Library._empty(ServiceObjectOwner owner) : super._empty(owner); |
2283 | 2263 |
2284 void _update(Map map, bool mapIsRef) { | 2264 void _update(Map map, bool mapIsRef) { |
2285 _upgradeCollection(map, isolate); | 2265 _upgradeCollection(map, isolate); |
2286 super._update(map, mapIsRef); | 2266 super._update(map, mapIsRef); |
2287 | 2267 |
2288 uri = map['uri']; | 2268 uri = map['uri']; |
2289 var shortUri = uri; | 2269 var shortUri = uri; |
2290 if (uri.startsWith('file://') || | 2270 if (uri.startsWith('file://') || uri.startsWith('http://')) { |
2291 uri.startsWith('http://')) { | |
2292 shortUri = uri.substring(uri.lastIndexOf('/') + 1); | 2271 shortUri = uri.substring(uri.lastIndexOf('/') + 1); |
2293 } | 2272 } |
2294 name = map['name']; | 2273 name = map['name']; |
2295 if (name.isEmpty) { | 2274 if (name.isEmpty) { |
2296 // When there is no name for a library, use the shortUri. | 2275 // When there is no name for a library, use the shortUri. |
2297 name = shortUri; | 2276 name = shortUri; |
2298 } | 2277 } |
2299 vmName = (map.containsKey('_vmName') ? map['_vmName'] : name); | 2278 vmName = (map.containsKey('_vmName') ? map['_vmName'] : name); |
2300 if (mapIsRef) { | 2279 if (mapIsRef) { |
2301 return; | 2280 return; |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2403 | 2382 |
2404 Class._empty(ServiceObjectOwner owner) : super._empty(owner); | 2383 Class._empty(ServiceObjectOwner owner) : super._empty(owner); |
2405 | 2384 |
2406 void _update(Map map, bool mapIsRef) { | 2385 void _update(Map map, bool mapIsRef) { |
2407 _upgradeCollection(map, isolate); | 2386 _upgradeCollection(map, isolate); |
2408 super._update(map, mapIsRef); | 2387 super._update(map, mapIsRef); |
2409 | 2388 |
2410 name = map['name']; | 2389 name = map['name']; |
2411 vmName = (map.containsKey('_vmName') ? map['_vmName'] : name); | 2390 vmName = (map.containsKey('_vmName') ? map['_vmName'] : name); |
2412 if (vmName == '::') { | 2391 if (vmName == '::') { |
2413 name = 'top-level-class'; // Better than '' | 2392 name = 'top-level-class'; // Better than '' |
2414 } | 2393 } |
2415 var idPrefix = "classes/"; | 2394 var idPrefix = "classes/"; |
2416 assert(id.startsWith(idPrefix)); | 2395 assert(id.startsWith(idPrefix)); |
2417 vmCid = int.parse(id.substring(idPrefix.length)); | 2396 vmCid = int.parse(id.substring(idPrefix.length)); |
2418 | 2397 |
2419 if (mapIsRef) { | 2398 if (mapIsRef) { |
2420 return; | 2399 return; |
2421 } | 2400 } |
2422 | 2401 |
2423 // We are fully loaded. | 2402 // We are fully loaded. |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2485 subclasses.add(subclass); | 2464 subclasses.add(subclass); |
2486 subclasses.sort(ServiceObject.LexicalSortName); | 2465 subclasses.sort(ServiceObject.LexicalSortName); |
2487 } | 2466 } |
2488 | 2467 |
2489 Future<ServiceObject> evaluate(String expression) { | 2468 Future<ServiceObject> evaluate(String expression) { |
2490 return isolate.eval(this, expression); | 2469 return isolate.eval(this, expression); |
2491 } | 2470 } |
2492 | 2471 |
2493 Future<ServiceObject> setTraceAllocations(bool enable) { | 2472 Future<ServiceObject> setTraceAllocations(bool enable) { |
2494 return isolate.invokeRpc('_setTraceClassAllocation', { | 2473 return isolate.invokeRpc('_setTraceClassAllocation', { |
2495 'enable': enable, | 2474 'enable': enable, |
2496 'classId': id, | 2475 'classId': id, |
2497 }); | 2476 }); |
2498 } | 2477 } |
2499 | 2478 |
2500 Future<ServiceObject> getAllocationSamples([String tags = 'None']) { | 2479 Future<ServiceObject> getAllocationSamples([String tags = 'None']) { |
2501 var params = { 'tags': tags, | 2480 var params = {'tags': tags, 'classId': id}; |
2502 'classId': id }; | |
2503 return isolate.invokeRpc('_getAllocationSamples', params); | 2481 return isolate.invokeRpc('_getAllocationSamples', params); |
2504 } | 2482 } |
2505 | 2483 |
2506 String toString() => 'Class($vmName)'; | 2484 String toString() => 'Class($vmName)'; |
2507 } | 2485 } |
2508 | 2486 |
2509 M.InstanceKind stringToInstanceKind(String s) { | 2487 M.InstanceKind stringToInstanceKind(String s) { |
2510 switch (s) { | 2488 switch (s) { |
2511 case 'PlainInstance': | 2489 case 'PlainInstance': |
2512 return M.InstanceKind.plainInstance; | 2490 return M.InstanceKind.plainInstance; |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2589 | 2567 |
2590 factory Guarded(ServiceObject obj) { | 2568 factory Guarded(ServiceObject obj) { |
2591 if (obj is Sentinel) { | 2569 if (obj is Sentinel) { |
2592 return new Guarded.fromSentinel(obj); | 2570 return new Guarded.fromSentinel(obj); |
2593 } else if (obj is T) { | 2571 } else if (obj is T) { |
2594 return new Guarded.fromValue(obj); | 2572 return new Guarded.fromValue(obj); |
2595 } | 2573 } |
2596 throw new Exception('${obj.type} is neither Sentinel or $T'); | 2574 throw new Exception('${obj.type} is neither Sentinel or $T'); |
2597 } | 2575 } |
2598 | 2576 |
2599 Guarded.fromSentinel(this.asSentinel) | 2577 Guarded.fromSentinel(this.asSentinel) : asValue = null; |
2600 : asValue = null; | 2578 Guarded.fromValue(this.asValue) : asSentinel = null; |
2601 Guarded.fromValue(this.asValue) | |
2602 : asSentinel = null; | |
2603 } | 2579 } |
2604 | 2580 |
2605 class BoundField implements M.BoundField { | 2581 class BoundField implements M.BoundField { |
2606 final Field decl; | 2582 final Field decl; |
2607 final Guarded<Instance> value; | 2583 final Guarded<Instance> value; |
2608 BoundField(this.decl, value) | 2584 BoundField(this.decl, value) : value = new Guarded(value); |
2609 : value = new Guarded(value); | |
2610 } | 2585 } |
2611 | 2586 |
2612 class NativeField implements M.NativeField { | 2587 class NativeField implements M.NativeField { |
2613 final int value; | 2588 final int value; |
2614 NativeField(this.value); | 2589 NativeField(this.value); |
2615 } | 2590 } |
2616 | 2591 |
2617 class MapAssociation implements M.MapAssociation { | 2592 class MapAssociation implements M.MapAssociation { |
2618 final Guarded<Instance> key; | 2593 final Guarded<Instance> key; |
2619 final Guarded<Instance> value; | 2594 final Guarded<Instance> value; |
2620 MapAssociation(key, value) | 2595 MapAssociation(key, value) |
2621 : key = new Guarded(key), | 2596 : key = new Guarded(key), |
2622 value = new Guarded(value); | 2597 value = new Guarded(value); |
2623 } | 2598 } |
2624 | 2599 |
2625 class Instance extends HeapObject implements M.Instance { | 2600 class Instance extends HeapObject implements M.Instance { |
2626 M.InstanceKind kind; | 2601 M.InstanceKind kind; |
2627 String valueAsString; // If primitive. | 2602 String valueAsString; // If primitive. |
2628 bool valueAsStringIsTruncated; | 2603 bool valueAsStringIsTruncated; |
2629 ServiceFunction closureFunction; // If a closure. | 2604 ServiceFunction closureFunction; // If a closure. |
2630 Context closureContext; // If a closure. | 2605 Context closureContext; // If a closure. |
2631 int length; // If a List, Map or TypedData. | 2606 int length; // If a List, Map or TypedData. |
2632 int count; | 2607 int count; |
2633 int offset; | 2608 int offset; |
2634 Instance pattern; // If a RegExp. | 2609 Instance pattern; // If a RegExp. |
2635 | 2610 |
2636 String name; | 2611 String name; |
2637 Class typeClass; | 2612 Class typeClass; |
2638 Class parameterizedClass; | 2613 Class parameterizedClass; |
2639 TypeArguments typeArguments; | 2614 TypeArguments typeArguments; |
2640 int parameterIndex; | 2615 int parameterIndex; |
2641 Instance targetType; | 2616 Instance targetType; |
2642 Instance bound; | 2617 Instance bound; |
2643 | 2618 |
2644 Iterable<BoundField> fields; | 2619 Iterable<BoundField> fields; |
2645 var nativeFields; | 2620 var nativeFields; |
2646 Iterable<Guarded<HeapObject>> elements; // If a List. | 2621 Iterable<Guarded<HeapObject>> elements; // If a List. |
2647 Iterable<MapAssociation> associations; // If a Map. | 2622 Iterable<MapAssociation> associations; // If a Map. |
2648 Iterable<dynamic> typedElements; // If a TypedData. | 2623 Iterable<dynamic> typedElements; // If a TypedData. |
2649 HeapObject referent; // If a MirrorReference. | 2624 HeapObject referent; // If a MirrorReference. |
2650 Instance key; // If a WeakProperty. | 2625 Instance key; // If a WeakProperty. |
2651 Instance value; // If a WeakProperty. | 2626 Instance value; // If a WeakProperty. |
2652 Breakpoint activationBreakpoint; // If a Closure. | 2627 Breakpoint activationBreakpoint; // If a Closure. |
2653 ServiceFunction oneByteFunction; // If a RegExp. | 2628 ServiceFunction oneByteFunction; // If a RegExp. |
2654 ServiceFunction twoByteFunction; // If a RegExp. | 2629 ServiceFunction twoByteFunction; // If a RegExp. |
2655 ServiceFunction externalOneByteFunction; // If a RegExp. | 2630 ServiceFunction externalOneByteFunction; // If a RegExp. |
2656 ServiceFunction externalTwoByteFunction; // If a RegExp. | 2631 ServiceFunction externalTwoByteFunction; // If a RegExp. |
2657 Instance oneByteBytecode; // If a RegExp. | 2632 Instance oneByteBytecode; // If a RegExp. |
2658 Instance twoByteBytecode; // If a RegExp. | 2633 Instance twoByteBytecode; // If a RegExp. |
2659 bool isCaseSensitive; // If a RegExp. | 2634 bool isCaseSensitive; // If a RegExp. |
2660 bool isMultiLine; // If a RegExp. | 2635 bool isMultiLine; // If a RegExp. |
2661 | 2636 |
2662 bool get isAbstractType => M.isAbstractType(kind); | 2637 bool get isAbstractType => M.isAbstractType(kind); |
2663 bool get isNull => kind == M.InstanceKind.vNull; | 2638 bool get isNull => kind == M.InstanceKind.vNull; |
2664 bool get isBool => kind == M.InstanceKind.bool; | 2639 bool get isBool => kind == M.InstanceKind.bool; |
2665 bool get isDouble => kind == M.InstanceKind.double; | 2640 bool get isDouble => kind == M.InstanceKind.double; |
2666 bool get isString => kind == M.InstanceKind.string; | 2641 bool get isString => kind == M.InstanceKind.string; |
2667 bool get isInt => kind == M.InstanceKind.int; | 2642 bool get isInt => kind == M.InstanceKind.int; |
2668 bool get isList => kind == M.InstanceKind.list; | 2643 bool get isList => kind == M.InstanceKind.list; |
2669 bool get isMap => kind == M.InstanceKind.map; | 2644 bool get isMap => kind == M.InstanceKind.map; |
2670 bool get isTypedData { | 2645 bool get isTypedData { |
2671 return M.isTypedData(kind); | 2646 return M.isTypedData(kind); |
2672 } | 2647 } |
| 2648 |
2673 bool get isSimdValue { | 2649 bool get isSimdValue { |
2674 return M.isSimdValue(kind); | 2650 return M.isSimdValue(kind); |
2675 } | 2651 } |
| 2652 |
2676 bool get isRegExp => kind == M.InstanceKind.regExp; | 2653 bool get isRegExp => kind == M.InstanceKind.regExp; |
2677 bool get isMirrorReference => kind == M.InstanceKind.mirrorReference; | 2654 bool get isMirrorReference => kind == M.InstanceKind.mirrorReference; |
2678 bool get isWeakProperty => kind == M.InstanceKind.weakProperty; | 2655 bool get isWeakProperty => kind == M.InstanceKind.weakProperty; |
2679 bool get isClosure => kind == M.InstanceKind.closure; | 2656 bool get isClosure => kind == M.InstanceKind.closure; |
2680 bool get isStackTrace => kind == M.InstanceKind.stackTrace; | 2657 bool get isStackTrace => kind == M.InstanceKind.stackTrace; |
2681 bool get isStackOverflowError { | 2658 bool get isStackOverflowError { |
2682 if (clazz == null) { | 2659 if (clazz == null) { |
2683 return false; | 2660 return false; |
2684 } | 2661 } |
2685 if (clazz.library == null) { | 2662 if (clazz.library == null) { |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2724 return; | 2701 return; |
2725 } | 2702 } |
2726 | 2703 |
2727 count = map['count']; | 2704 count = map['count']; |
2728 offset = map['offset']; | 2705 offset = map['offset']; |
2729 isCaseSensitive = map['isCaseSensitive']; | 2706 isCaseSensitive = map['isCaseSensitive']; |
2730 isMultiLine = map['isMultiLine']; | 2707 isMultiLine = map['isMultiLine']; |
2731 bool isCompiled = map['_oneByteFunction'] is ServiceFunction; | 2708 bool isCompiled = map['_oneByteFunction'] is ServiceFunction; |
2732 oneByteFunction = isCompiled ? map['_oneByteFunction'] : null; | 2709 oneByteFunction = isCompiled ? map['_oneByteFunction'] : null; |
2733 twoByteFunction = isCompiled ? map['_twoByteFunction'] : null; | 2710 twoByteFunction = isCompiled ? map['_twoByteFunction'] : null; |
2734 externalOneByteFunction = isCompiled ? map['_externalOneByteFunction'] : nul
l; | 2711 externalOneByteFunction = |
2735 externalTwoByteFunction = isCompiled ? map['_externalTwoByteFunction'] : nul
l; | 2712 isCompiled ? map['_externalOneByteFunction'] : null; |
| 2713 externalTwoByteFunction = |
| 2714 isCompiled ? map['_externalTwoByteFunction'] : null; |
2736 oneByteBytecode = map['_oneByteBytecode']; | 2715 oneByteBytecode = map['_oneByteBytecode']; |
2737 twoByteBytecode = map['_twoByteBytecode']; | 2716 twoByteBytecode = map['_twoByteBytecode']; |
2738 | 2717 |
2739 if (map['fields'] != null) { | 2718 if (map['fields'] != null) { |
2740 fields = map['fields'] | 2719 fields = map['fields'] |
2741 .map((f) => new BoundField(f['decl'], f['value'])).toList(); | 2720 .map((f) => new BoundField(f['decl'], f['value'])) |
| 2721 .toList(); |
2742 } else { | 2722 } else { |
2743 fields = null; | 2723 fields = null; |
2744 } | 2724 } |
2745 if (map['_nativeFields'] != null) { | 2725 if (map['_nativeFields'] != null) { |
2746 nativeFields = map['_nativeFields'] | 2726 nativeFields = |
2747 .map((f) => new NativeField(f['value'])).toList(); | 2727 map['_nativeFields'].map((f) => new NativeField(f['value'])).toList(); |
2748 } else { | 2728 } else { |
2749 nativeFields = null; | 2729 nativeFields = null; |
2750 } | 2730 } |
2751 if (map['elements'] != null) { | 2731 if (map['elements'] != null) { |
2752 // Should be: | 2732 // Should be: |
2753 // elements = map['elements'].map((e) => new Guarded<Instance>(e)).toList(); | 2733 // elements = map['elements'].map((e) => new Guarded<Instance>(e)).toList(
); |
2754 // some times we obtain object that are not InstanceRef | 2734 // some times we obtain object that are not InstanceRef |
2755 elements = map['elements'].map((e) => new Guarded<ServiceObject>(e)) | 2735 elements = |
2756 .toList(); | 2736 map['elements'].map((e) => new Guarded<ServiceObject>(e)).toList(); |
2757 } else { | 2737 } else { |
2758 elements = null; | 2738 elements = null; |
2759 } | 2739 } |
2760 if (map['associations'] != null) { | 2740 if (map['associations'] != null) { |
2761 associations = map['associations'].map((a) => | 2741 associations = map['associations'] |
2762 new MapAssociation(a['key'], a['value'])).toList(); | 2742 .map((a) => new MapAssociation(a['key'], a['value'])) |
| 2743 .toList(); |
2763 } else { | 2744 } else { |
2764 associations = null; | 2745 associations = null; |
2765 }; | 2746 } |
| 2747 ; |
2766 if (map['bytes'] != null) { | 2748 if (map['bytes'] != null) { |
2767 Uint8List bytes = BASE64.decode(map['bytes']); | 2749 Uint8List bytes = BASE64.decode(map['bytes']); |
2768 switch (map['kind']) { | 2750 switch (map['kind']) { |
2769 case "Uint8ClampedList": | 2751 case "Uint8ClampedList": |
2770 typedElements = bytes.buffer.asUint8ClampedList(); break; | 2752 typedElements = bytes.buffer.asUint8ClampedList(); |
| 2753 break; |
2771 case "Uint8List": | 2754 case "Uint8List": |
2772 typedElements = bytes.buffer.asUint8List(); break; | 2755 typedElements = bytes.buffer.asUint8List(); |
| 2756 break; |
2773 case "Uint16List": | 2757 case "Uint16List": |
2774 typedElements = bytes.buffer.asUint16List(); break; | 2758 typedElements = bytes.buffer.asUint16List(); |
| 2759 break; |
2775 case "Uint32List": | 2760 case "Uint32List": |
2776 typedElements = bytes.buffer.asUint32List(); break; | 2761 typedElements = bytes.buffer.asUint32List(); |
| 2762 break; |
2777 case "Uint64List": | 2763 case "Uint64List": |
2778 typedElements = bytes.buffer.asUint64List(); break; | 2764 typedElements = bytes.buffer.asUint64List(); |
| 2765 break; |
2779 case "Int8List": | 2766 case "Int8List": |
2780 typedElements = bytes.buffer.asInt8List(); break; | 2767 typedElements = bytes.buffer.asInt8List(); |
| 2768 break; |
2781 case "Int16List": | 2769 case "Int16List": |
2782 typedElements = bytes.buffer.asInt16List(); break; | 2770 typedElements = bytes.buffer.asInt16List(); |
| 2771 break; |
2783 case "Int32List": | 2772 case "Int32List": |
2784 typedElements = bytes.buffer.asInt32List(); break; | 2773 typedElements = bytes.buffer.asInt32List(); |
| 2774 break; |
2785 case "Int64List": | 2775 case "Int64List": |
2786 typedElements = bytes.buffer.asInt64List(); break; | 2776 typedElements = bytes.buffer.asInt64List(); |
| 2777 break; |
2787 case "Float32List": | 2778 case "Float32List": |
2788 typedElements = bytes.buffer.asFloat32List(); break; | 2779 typedElements = bytes.buffer.asFloat32List(); |
| 2780 break; |
2789 case "Float64List": | 2781 case "Float64List": |
2790 typedElements = bytes.buffer.asFloat64List(); break; | 2782 typedElements = bytes.buffer.asFloat64List(); |
| 2783 break; |
2791 case "Int32x4List": | 2784 case "Int32x4List": |
2792 typedElements = bytes.buffer.asInt32x4List(); break; | 2785 typedElements = bytes.buffer.asInt32x4List(); |
| 2786 break; |
2793 case "Float32x4List": | 2787 case "Float32x4List": |
2794 typedElements = bytes.buffer.asFloat32x4List(); break; | 2788 typedElements = bytes.buffer.asFloat32x4List(); |
| 2789 break; |
2795 case "Float64x2List": | 2790 case "Float64x2List": |
2796 typedElements = bytes.buffer.asFloat64x2List(); break; | 2791 typedElements = bytes.buffer.asFloat64x2List(); |
| 2792 break; |
2797 } | 2793 } |
2798 } else { | 2794 } else { |
2799 typedElements = null; | 2795 typedElements = null; |
2800 } | 2796 } |
2801 parameterizedClass = map['parameterizedClass']; | 2797 parameterizedClass = map['parameterizedClass']; |
2802 typeArguments = map['typeArguments']; | 2798 typeArguments = map['typeArguments']; |
2803 parameterIndex = map['parameterIndex']; | 2799 parameterIndex = map['parameterIndex']; |
2804 targetType = map['targetType']; | 2800 targetType = map['targetType']; |
2805 bound = map['bound']; | 2801 bound = map['bound']; |
2806 | 2802 |
(...skipping 16 matching lines...) Expand all Loading... |
2823 return 'a ${clazz.name}'; | 2819 return 'a ${clazz.name}'; |
2824 } | 2820 } |
2825 | 2821 |
2826 Future<ServiceObject> evaluate(String expression) { | 2822 Future<ServiceObject> evaluate(String expression) { |
2827 return isolate.eval(this, expression); | 2823 return isolate.eval(this, expression); |
2828 } | 2824 } |
2829 | 2825 |
2830 String toString() => 'Instance($shortName)'; | 2826 String toString() => 'Instance($shortName)'; |
2831 } | 2827 } |
2832 | 2828 |
2833 | |
2834 class Context extends HeapObject implements M.Context { | 2829 class Context extends HeapObject implements M.Context { |
2835 Context parentContext; | 2830 Context parentContext; |
2836 int length; | 2831 int length; |
2837 Iterable<ContextElement> variables; | 2832 Iterable<ContextElement> variables; |
2838 | 2833 |
2839 Context._empty(ServiceObjectOwner owner) : super._empty(owner); | 2834 Context._empty(ServiceObjectOwner owner) : super._empty(owner); |
2840 | 2835 |
2841 void _update(Map map, bool mapIsRef) { | 2836 void _update(Map map, bool mapIsRef) { |
2842 // Extract full properties. | 2837 // Extract full properties. |
2843 _upgradeCollection(map, isolate); | 2838 _upgradeCollection(map, isolate); |
2844 super._update(map, mapIsRef); | 2839 super._update(map, mapIsRef); |
2845 | 2840 |
2846 length = map['length']; | 2841 length = map['length']; |
2847 parentContext = map['parent']; | 2842 parentContext = map['parent']; |
2848 | 2843 |
2849 if (mapIsRef) { | 2844 if (mapIsRef) { |
2850 return; | 2845 return; |
2851 } | 2846 } |
2852 | 2847 |
2853 variables = (map['variables'] ?? const []).map((element) => | 2848 variables = (map['variables'] ?? const []) |
2854 new ContextElement(element)); | 2849 .map((element) => new ContextElement(element)); |
2855 | 2850 |
2856 // We are fully loaded. | 2851 // We are fully loaded. |
2857 _loaded = true; | 2852 _loaded = true; |
2858 } | 2853 } |
2859 | 2854 |
2860 String toString() => 'Context($length)'; | 2855 String toString() => 'Context($length)'; |
2861 } | 2856 } |
2862 | 2857 |
2863 class ContextElement extends M.ContextElement { | 2858 class ContextElement extends M.ContextElement { |
2864 final Guarded<Instance> value; | 2859 final Guarded<Instance> value; |
2865 | 2860 |
2866 ContextElement(Map map) | 2861 ContextElement(Map map) : value = new Guarded<Instance>(map['value']); |
2867 : value = new Guarded<Instance>(map['value']); | |
2868 } | 2862 } |
2869 | 2863 |
2870 M.FunctionKind stringToFunctionKind(String value) { | 2864 M.FunctionKind stringToFunctionKind(String value) { |
2871 switch(value) { | 2865 switch (value) { |
2872 case 'RegularFunction': return M.FunctionKind.regular; | 2866 case 'RegularFunction': |
2873 case 'ClosureFunction': return M.FunctionKind.closure; | 2867 return M.FunctionKind.regular; |
2874 case 'GetterFunction': return M.FunctionKind.getter; | 2868 case 'ClosureFunction': |
2875 case 'SetterFunction': return M.FunctionKind.setter; | 2869 return M.FunctionKind.closure; |
2876 case 'Constructor': return M.FunctionKind.constructor; | 2870 case 'GetterFunction': |
2877 case 'ImplicitGetter': return M.FunctionKind.implicitGetter; | 2871 return M.FunctionKind.getter; |
2878 case 'ImplicitSetter': return M.FunctionKind.implicitSetter; | 2872 case 'SetterFunction': |
| 2873 return M.FunctionKind.setter; |
| 2874 case 'Constructor': |
| 2875 return M.FunctionKind.constructor; |
| 2876 case 'ImplicitGetter': |
| 2877 return M.FunctionKind.implicitGetter; |
| 2878 case 'ImplicitSetter': |
| 2879 return M.FunctionKind.implicitSetter; |
2879 case 'ImplicitStaticFinalGetter': | 2880 case 'ImplicitStaticFinalGetter': |
2880 return M.FunctionKind.implicitStaticFinalGetter; | 2881 return M.FunctionKind.implicitStaticFinalGetter; |
2881 case 'IrregexpFunction': return M.FunctionKind.irregexpFunction; | 2882 case 'IrregexpFunction': |
2882 case 'StaticInitializer': return M.FunctionKind.staticInitializer; | 2883 return M.FunctionKind.irregexpFunction; |
2883 case 'MethodExtractor': return M.FunctionKind.methodExtractor; | 2884 case 'StaticInitializer': |
2884 case 'NoSuchMethodDispatcher': return M.FunctionKind.noSuchMethodDispatcher; | 2885 return M.FunctionKind.staticInitializer; |
2885 case 'InvokeFieldDispatcher': return M.FunctionKind.invokeFieldDispatcher; | 2886 case 'MethodExtractor': |
2886 case 'Collected': return M.FunctionKind.collected; | 2887 return M.FunctionKind.methodExtractor; |
2887 case 'Native': return M.FunctionKind.native; | 2888 case 'NoSuchMethodDispatcher': |
2888 case 'Stub': return M.FunctionKind.stub; | 2889 return M.FunctionKind.noSuchMethodDispatcher; |
2889 case 'Tag': return M.FunctionKind.tag; | 2890 case 'InvokeFieldDispatcher': |
2890 case 'SignatureFunction': return M.FunctionKind.signatureFunction; | 2891 return M.FunctionKind.invokeFieldDispatcher; |
| 2892 case 'Collected': |
| 2893 return M.FunctionKind.collected; |
| 2894 case 'Native': |
| 2895 return M.FunctionKind.native; |
| 2896 case 'Stub': |
| 2897 return M.FunctionKind.stub; |
| 2898 case 'Tag': |
| 2899 return M.FunctionKind.tag; |
| 2900 case 'SignatureFunction': |
| 2901 return M.FunctionKind.signatureFunction; |
2891 } | 2902 } |
2892 Logger.root.severe('Unrecognized function kind: $value'); | 2903 Logger.root.severe('Unrecognized function kind: $value'); |
2893 throw new FallThroughError(); | 2904 throw new FallThroughError(); |
2894 } | 2905 } |
2895 | 2906 |
2896 class ServiceFunction extends HeapObject implements M.Function { | 2907 class ServiceFunction extends HeapObject implements M.Function { |
2897 // owner is a Library, Class, or ServiceFunction. | 2908 // owner is a Library, Class, or ServiceFunction. |
2898 M.ObjectRef dartOwner; | 2909 M.ObjectRef dartOwner; |
2899 Library library; | 2910 Library library; |
2900 bool isStatic; | 2911 bool isStatic; |
(...skipping 27 matching lines...) Expand all Loading... |
2928 vmName = (map.containsKey('_vmName') ? map['_vmName'] : name); | 2939 vmName = (map.containsKey('_vmName') ? map['_vmName'] : name); |
2929 | 2940 |
2930 dartOwner = map['owner']; | 2941 dartOwner = map['owner']; |
2931 kind = stringToFunctionKind(map['_kind']); | 2942 kind = stringToFunctionKind(map['_kind']); |
2932 isDart = M.isDartFunction(kind); | 2943 isDart = M.isDartFunction(kind); |
2933 | 2944 |
2934 if (dartOwner is ServiceFunction) { | 2945 if (dartOwner is ServiceFunction) { |
2935 ServiceFunction ownerFunction = dartOwner; | 2946 ServiceFunction ownerFunction = dartOwner; |
2936 library = ownerFunction.library; | 2947 library = ownerFunction.library; |
2937 qualifiedName = "${ownerFunction.qualifiedName}.${name}"; | 2948 qualifiedName = "${ownerFunction.qualifiedName}.${name}"; |
2938 | |
2939 } else if (dartOwner is Class) { | 2949 } else if (dartOwner is Class) { |
2940 Class ownerClass = dartOwner; | 2950 Class ownerClass = dartOwner; |
2941 library = ownerClass.library; | 2951 library = ownerClass.library; |
2942 qualifiedName = "${ownerClass.name}.${name}"; | 2952 qualifiedName = "${ownerClass.name}.${name}"; |
2943 | |
2944 } else { | 2953 } else { |
2945 library = dartOwner; | 2954 library = dartOwner; |
2946 qualifiedName = name; | 2955 qualifiedName = name; |
2947 } | 2956 } |
2948 | 2957 |
2949 hasIntrinsic = map['_intrinsic']; | 2958 hasIntrinsic = map['_intrinsic']; |
2950 isNative = map['_native']; | 2959 isNative = map['_native']; |
2951 | 2960 |
2952 if (mapIsRef) { | 2961 if (mapIsRef) { |
2953 return; | 2962 return; |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2990 case 'OptimizedOut': | 2999 case 'OptimizedOut': |
2991 return M.SentinelKind.optimizedOut; | 3000 return M.SentinelKind.optimizedOut; |
2992 case 'Free': | 3001 case 'Free': |
2993 return M.SentinelKind.free; | 3002 return M.SentinelKind.free; |
2994 } | 3003 } |
2995 Logger.root.severe("Unrecognized SentinelKind: '$s'"); | 3004 Logger.root.severe("Unrecognized SentinelKind: '$s'"); |
2996 throw new FallThroughError(); | 3005 throw new FallThroughError(); |
2997 } | 3006 } |
2998 | 3007 |
2999 class Sentinel extends ServiceObject implements M.Sentinel { | 3008 class Sentinel extends ServiceObject implements M.Sentinel { |
3000 | |
3001 M.SentinelKind kind; | 3009 M.SentinelKind kind; |
3002 String valueAsString; | 3010 String valueAsString; |
3003 | 3011 |
3004 Sentinel._empty(ServiceObjectOwner owner) : super._empty(owner); | 3012 Sentinel._empty(ServiceObjectOwner owner) : super._empty(owner); |
3005 | 3013 |
3006 void _update(Map map, bool mapIsRef) { | 3014 void _update(Map map, bool mapIsRef) { |
3007 // Extract full properties. | 3015 // Extract full properties. |
3008 _upgradeCollection(map, isolate); | 3016 _upgradeCollection(map, isolate); |
3009 | 3017 |
3010 kind = stringToSentinelKind(map['kind']); | 3018 kind = stringToSentinelKind(map['kind']); |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3045 vmName = (map.containsKey('_vmName') ? map['_vmName'] : name); | 3053 vmName = (map.containsKey('_vmName') ? map['_vmName'] : name); |
3046 dartOwner = map['owner']; | 3054 dartOwner = map['owner']; |
3047 declaredType = map['declaredType']; | 3055 declaredType = map['declaredType']; |
3048 isStatic = map['static']; | 3056 isStatic = map['static']; |
3049 isFinal = map['final']; | 3057 isFinal = map['final']; |
3050 isConst = map['const']; | 3058 isConst = map['const']; |
3051 | 3059 |
3052 if (dartOwner is Class) { | 3060 if (dartOwner is Class) { |
3053 Class ownerClass = dartOwner; | 3061 Class ownerClass = dartOwner; |
3054 library = ownerClass.library; | 3062 library = ownerClass.library; |
3055 | |
3056 } else { | 3063 } else { |
3057 library = dartOwner; | 3064 library = dartOwner; |
3058 } | 3065 } |
3059 | 3066 |
3060 if (mapIsRef) { | 3067 if (mapIsRef) { |
3061 return; | 3068 return; |
3062 } | 3069 } |
3063 staticValue = map['staticValue']; | 3070 staticValue = map['staticValue']; |
3064 | 3071 |
3065 guardNullable = map['_guardNullable']; | 3072 guardNullable = map['_guardNullable']; |
3066 if (map['_guardClass'] is Class) { | 3073 if (map['_guardClass'] is Class) { |
3067 guardClass = map['_guardClass']; | 3074 guardClass = map['_guardClass']; |
3068 guardClassKind = M.GuardClassKind.single; | 3075 guardClassKind = M.GuardClassKind.single; |
3069 } else { | 3076 } else { |
3070 switch (map['_guardClass']) { | 3077 switch (map['_guardClass']) { |
3071 case 'various': | 3078 case 'various': |
3072 guardClassKind = M.GuardClassKind.dynamic; | 3079 guardClassKind = M.GuardClassKind.dynamic; |
3073 break; | 3080 break; |
3074 case 'unknown': | 3081 case 'unknown': |
3075 default: | 3082 default: |
3076 guardClassKind = M.GuardClassKind.unknown; | 3083 guardClassKind = M.GuardClassKind.unknown; |
3077 break; | 3084 break; |
3078 } | 3085 } |
3079 } | 3086 } |
3080 | 3087 |
3081 guardLength = map['_guardLength']; | 3088 guardLength = map['_guardLength']; |
3082 location = map['location']; | 3089 location = map['location']; |
3083 _loaded = true; | 3090 _loaded = true; |
3084 } | 3091 } |
3085 | 3092 |
3086 String toString() => 'Field(${dartOwner.name}.$name)'; | 3093 String toString() => 'Field(${dartOwner.name}.$name)'; |
3087 } | 3094 } |
3088 | 3095 |
3089 | |
3090 class ScriptLine { | 3096 class ScriptLine { |
3091 final Script script; | 3097 final Script script; |
3092 final int line; | 3098 final int line; |
3093 final String text; | 3099 final String text; |
3094 Set<Breakpoint> breakpoints; | 3100 Set<Breakpoint> breakpoints; |
3095 | 3101 |
3096 ScriptLine(this.script, this.line, this.text); | 3102 ScriptLine(this.script, this.line, this.text); |
3097 | 3103 |
3098 bool get isBlank { | 3104 bool get isBlank { |
3099 return text.isEmpty || text.trim().isEmpty; | 3105 return text.isEmpty || text.trim().isEmpty; |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3184 var entries = new List<CallSiteEntry>(); | 3190 var entries = new List<CallSiteEntry>(); |
3185 for (var entryMap in siteMap['cacheEntries']) { | 3191 for (var entryMap in siteMap['cacheEntries']) { |
3186 entries.add(new CallSiteEntry.fromMap(entryMap)); | 3192 entries.add(new CallSiteEntry.fromMap(entryMap)); |
3187 } | 3193 } |
3188 return new CallSite(name, script, tokenPos, entries); | 3194 return new CallSite(name, script, tokenPos, entries); |
3189 } | 3195 } |
3190 | 3196 |
3191 operator ==(other) { | 3197 operator ==(other) { |
3192 return (script == other.script) && (tokenPos == other.tokenPos); | 3198 return (script == other.script) && (tokenPos == other.tokenPos); |
3193 } | 3199 } |
| 3200 |
3194 int get hashCode => (script.hashCode << 8) | tokenPos; | 3201 int get hashCode => (script.hashCode << 8) | tokenPos; |
3195 | 3202 |
3196 String toString() => "CallSite($name, $tokenPos)"; | 3203 String toString() => "CallSite($name, $tokenPos)"; |
3197 } | 3204 } |
3198 | 3205 |
3199 class CallSiteEntry { | 3206 class CallSiteEntry { |
3200 final /* Class | Library */ receiver; | 3207 final /* Class | Library */ receiver; |
3201 final int count; | 3208 final int count; |
3202 final ServiceFunction target; | 3209 final ServiceFunction target; |
3203 | 3210 |
3204 CallSiteEntry(this.receiver, this.count, this.target); | 3211 CallSiteEntry(this.receiver, this.count, this.target); |
3205 | 3212 |
3206 factory CallSiteEntry.fromMap(Map entryMap) { | 3213 factory CallSiteEntry.fromMap(Map entryMap) { |
3207 return new CallSiteEntry(entryMap['receiver'], | 3214 return new CallSiteEntry( |
3208 entryMap['count'], | 3215 entryMap['receiver'], entryMap['count'], entryMap['target']); |
3209 entryMap['target']); | |
3210 } | 3216 } |
3211 | 3217 |
3212 String toString() => "CallSiteEntry(${receiver.name}, $count)"; | 3218 String toString() => "CallSiteEntry(${receiver.name}, $count)"; |
3213 } | 3219 } |
3214 | 3220 |
3215 /// The location of a local variable reference in a script. | 3221 /// The location of a local variable reference in a script. |
3216 class LocalVarLocation { | 3222 class LocalVarLocation { |
3217 final int line; | 3223 final int line; |
3218 final int column; | 3224 final int column; |
3219 final int endColumn; | 3225 final int endColumn; |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3257 String source = getLine(line).text; | 3263 String source = getLine(line).text; |
3258 | 3264 |
3259 var pos = column; | 3265 var pos = column; |
3260 if (pos >= source.length) { | 3266 if (pos >= source.length) { |
3261 return null; | 3267 return null; |
3262 } | 3268 } |
3263 | 3269 |
3264 var c = source.codeUnitAt(pos); | 3270 var c = source.codeUnitAt(pos); |
3265 if (c == 123) return 1; // { - Map literal | 3271 if (c == 123) return 1; // { - Map literal |
3266 | 3272 |
3267 if (c == 91) return 1; // [ - List literal, index, index assignment | 3273 if (c == 91) return 1; // [ - List literal, index, index assignment |
3268 | 3274 |
3269 if (c == 40) return 1; // ( - Closure call | 3275 if (c == 40) return 1; // ( - Closure call |
3270 | 3276 |
3271 if (_isOperatorChar(c)) { | 3277 if (_isOperatorChar(c)) { |
3272 while (++pos < source.length && | 3278 while (++pos < source.length && _isOperatorChar(source.codeUnitAt(pos))); |
3273 _isOperatorChar(source.codeUnitAt(pos))); | |
3274 return pos - column; | 3279 return pos - column; |
3275 } | 3280 } |
3276 | 3281 |
3277 if (_isInitialIdentifierChar(c)) { | 3282 if (_isInitialIdentifierChar(c)) { |
3278 while (++pos < source.length && | 3283 while ( |
3279 _isIdentifierChar(source.codeUnitAt(pos))); | 3284 ++pos < source.length && _isIdentifierChar(source.codeUnitAt(pos))); |
3280 return pos - column; | 3285 return pos - column; |
3281 } | 3286 } |
3282 | 3287 |
3283 return null; | 3288 return null; |
3284 } | 3289 } |
3285 | 3290 |
3286 static bool _isOperatorChar(int c) { | 3291 static bool _isOperatorChar(int c) { |
3287 switch (c) { | 3292 switch (c) { |
3288 case 25: // % | 3293 case 25: // % |
3289 case 26: // & | 3294 case 26: // & |
3290 case 42: // * | 3295 case 42: // * |
3291 case 43: // + | 3296 case 43: // + |
3292 case 45: // -: | 3297 case 45: // -: |
3293 case 47: // / | 3298 case 47: // / |
3294 case 60: // < | 3299 case 60: // < |
3295 case 61: // = | 3300 case 61: // = |
3296 case 62: // > | 3301 case 62: // > |
3297 case 94: // ^ | 3302 case 94: // ^ |
3298 case 124: // | | 3303 case 124: // | |
3299 case 126: // ~ | 3304 case 126: // ~ |
3300 return true; | 3305 return true; |
3301 default: | 3306 default: |
3302 return false; | 3307 return false; |
3303 } | 3308 } |
3304 } | 3309 } |
3305 | 3310 |
3306 static bool _isInitialIdentifierChar(int c) { | 3311 static bool _isInitialIdentifierChar(int c) { |
3307 if (c >= 65 && c <= 90) return true; // Upper | 3312 if (c >= 65 && c <= 90) return true; // Upper |
3308 if (c >= 97 && c <= 122) return true; // Lower | 3313 if (c >= 97 && c <= 122) return true; // Lower |
3309 if (c == 95) return true; // Underscore | 3314 if (c == 95) return true; // Underscore |
3310 if (c == 36) return true; // Dollar | 3315 if (c == 36) return true; // Dollar |
3311 return false; | 3316 return false; |
3312 } | 3317 } |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3349 lastTokenPos = null; | 3354 lastTokenPos = null; |
3350 var lineSet = new Set(); | 3355 var lineSet = new Set(); |
3351 | 3356 |
3352 for (var line in table) { | 3357 for (var line in table) { |
3353 // Each entry begins with a line number... | 3358 // Each entry begins with a line number... |
3354 var lineNumber = line[0]; | 3359 var lineNumber = line[0]; |
3355 lineSet.add(lineNumber); | 3360 lineSet.add(lineNumber); |
3356 for (var pos = 1; pos < line.length; pos += 2) { | 3361 for (var pos = 1; pos < line.length; pos += 2) { |
3357 // ...and is followed by (token offset, col number) pairs. | 3362 // ...and is followed by (token offset, col number) pairs. |
3358 var tokenOffset = line[pos]; | 3363 var tokenOffset = line[pos]; |
3359 var colNumber = line[pos+1]; | 3364 var colNumber = line[pos + 1]; |
3360 if (firstTokenPos == null) { | 3365 if (firstTokenPos == null) { |
3361 // Mark first token position. | 3366 // Mark first token position. |
3362 firstTokenPos = tokenOffset; | 3367 firstTokenPos = tokenOffset; |
3363 lastTokenPos = tokenOffset; | 3368 lastTokenPos = tokenOffset; |
3364 } else { | 3369 } else { |
3365 // Keep track of max and min token positions. | 3370 // Keep track of max and min token positions. |
3366 firstTokenPos = (firstTokenPos <= tokenOffset) ? | 3371 firstTokenPos = |
3367 firstTokenPos : tokenOffset; | 3372 (firstTokenPos <= tokenOffset) ? firstTokenPos : tokenOffset; |
3368 lastTokenPos = (lastTokenPos >= tokenOffset) ? | 3373 lastTokenPos = |
3369 lastTokenPos : tokenOffset; | 3374 (lastTokenPos >= tokenOffset) ? lastTokenPos : tokenOffset; |
3370 } | 3375 } |
3371 _tokenToLine[tokenOffset] = lineNumber; | 3376 _tokenToLine[tokenOffset] = lineNumber; |
3372 _tokenToCol[tokenOffset] = colNumber; | 3377 _tokenToCol[tokenOffset] = colNumber; |
3373 } | 3378 } |
3374 } | 3379 } |
3375 } | 3380 } |
3376 | 3381 |
3377 void _processSource(String source) { | 3382 void _processSource(String source) { |
3378 if (source == null) { | 3383 if (source == null) { |
3379 return; | 3384 return; |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3412 } else { | 3417 } else { |
3413 UnresolvedSourceLocation loc = bpt.location; | 3418 UnresolvedSourceLocation loc = bpt.location; |
3414 line = loc.line; | 3419 line = loc.line; |
3415 } | 3420 } |
3416 if (line != null) { | 3421 if (line != null) { |
3417 getLine(line).removeBreakpoint(bpt); | 3422 getLine(line).removeBreakpoint(bpt); |
3418 } | 3423 } |
3419 } | 3424 } |
3420 | 3425 |
3421 List<LocalVarLocation> scanLineForLocalVariableLocations(Pattern pattern, | 3426 List<LocalVarLocation> scanLineForLocalVariableLocations(Pattern pattern, |
3422 String name, | 3427 String name, String lineContents, int lineNumber, int columnOffset) { |
3423 String lineContents, | |
3424 int lineNumber, | |
3425 int columnOffset) { | |
3426 var r = <LocalVarLocation>[]; | 3428 var r = <LocalVarLocation>[]; |
3427 | 3429 |
3428 pattern.allMatches(lineContents).forEach((Match match) { | 3430 pattern.allMatches(lineContents).forEach((Match match) { |
3429 // We have a match but our regular expression may have matched extra | 3431 // We have a match but our regular expression may have matched extra |
3430 // characters on either side of the name. Tighten the location. | 3432 // characters on either side of the name. Tighten the location. |
3431 var nameStart = match.input.indexOf(name, match.start); | 3433 var nameStart = match.input.indexOf(name, match.start); |
3432 var column = nameStart + columnOffset; | 3434 var column = nameStart + columnOffset; |
3433 var endColumn = column + name.length; | 3435 var endColumn = column + name.length; |
3434 var localVarLocation = new LocalVarLocation(lineNumber, | 3436 var localVarLocation = |
3435 column, | 3437 new LocalVarLocation(lineNumber, column, endColumn); |
3436 endColumn); | |
3437 r.add(localVarLocation); | 3438 r.add(localVarLocation); |
3438 }); | 3439 }); |
3439 | 3440 |
3440 return r; | 3441 return r; |
3441 } | 3442 } |
3442 | 3443 |
3443 List<LocalVarLocation> scanForLocalVariableLocations(String name, | 3444 List<LocalVarLocation> scanForLocalVariableLocations( |
3444 int tokenPos, | 3445 String name, int tokenPos, int endTokenPos) { |
3445 int endTokenPos) { | |
3446 // A pattern that matches: | 3446 // A pattern that matches: |
3447 // start of line OR non-(alpha numeric OR period) character followed by | 3447 // start of line OR non-(alpha numeric OR period) character followed by |
3448 // name followed by | 3448 // name followed by |
3449 // a non-alpha numerc character. | 3449 // a non-alpha numerc character. |
3450 // | 3450 // |
3451 // NOTE: This pattern can over match on both ends. This is corrected for | 3451 // NOTE: This pattern can over match on both ends. This is corrected for |
3452 // [scanLineForLocalVariableLocationse]. | 3452 // [scanLineForLocalVariableLocationse]. |
3453 var pattern = new RegExp("(^|[^A-Za-z0-9\.])$name[^A-Za-z0-9]"); | 3453 var pattern = new RegExp("(^|[^A-Za-z0-9\.])$name[^A-Za-z0-9]"); |
3454 | 3454 |
3455 // Result. | 3455 // Result. |
(...skipping 28 matching lines...) Expand all Loading... |
3484 | 3484 |
3485 if (line == lastLine) { | 3485 if (line == lastLine) { |
3486 // Only one line. | 3486 // Only one line. |
3487 if (!getLine(line).isTrivial) { | 3487 if (!getLine(line).isTrivial) { |
3488 // TODO(johnmccutchan): end token pos -> column can lie for snapshotted | 3488 // TODO(johnmccutchan): end token pos -> column can lie for snapshotted |
3489 // code. e.g.: | 3489 // code. e.g.: |
3490 // io_sink.dart source line 23 ends at column 39 | 3490 // io_sink.dart source line 23 ends at column 39 |
3491 // io_sink.dart snapshotted source line 23 ends at column 35. | 3491 // io_sink.dart snapshotted source line 23 ends at column 35. |
3492 lastColumn = math.min(getLine(line).text.length, lastColumn); | 3492 lastColumn = math.min(getLine(line).text.length, lastColumn); |
3493 lineContents = getLine(line).text.substring(column, lastColumn - 1); | 3493 lineContents = getLine(line).text.substring(column, lastColumn - 1); |
3494 return scanLineForLocalVariableLocations(pattern, | 3494 return scanLineForLocalVariableLocations( |
3495 name, | 3495 pattern, name, lineContents, line, column); |
3496 lineContents, | |
3497 line, | |
3498 column); | |
3499 } | 3496 } |
3500 } | 3497 } |
3501 | 3498 |
3502 // Scan first line. | 3499 // Scan first line. |
3503 if (!getLine(line).isTrivial) { | 3500 if (!getLine(line).isTrivial) { |
3504 lineContents = getLine(line).text.substring(column); | 3501 lineContents = getLine(line).text.substring(column); |
3505 r.addAll(scanLineForLocalVariableLocations(pattern, | 3502 r.addAll(scanLineForLocalVariableLocations( |
3506 name, | 3503 pattern, name, lineContents, line++, column)); |
3507 lineContents, | |
3508 line++, | |
3509 column)); | |
3510 } | 3504 } |
3511 | 3505 |
3512 // Scan middle lines. | 3506 // Scan middle lines. |
3513 while (line < (lastLine - 1)) { | 3507 while (line < (lastLine - 1)) { |
3514 if (getLine(line).isTrivial) { | 3508 if (getLine(line).isTrivial) { |
3515 line++; | 3509 line++; |
3516 continue; | 3510 continue; |
3517 } | 3511 } |
3518 lineContents = getLine(line).text; | 3512 lineContents = getLine(line).text; |
3519 r.addAll( | 3513 r.addAll(scanLineForLocalVariableLocations( |
3520 scanLineForLocalVariableLocations(pattern, | 3514 pattern, name, lineContents, line++, 0)); |
3521 name, | |
3522 lineContents, | |
3523 line++, | |
3524 0)); | |
3525 } | 3515 } |
3526 | 3516 |
3527 // Scan last line. | 3517 // Scan last line. |
3528 if (!getLine(line).isTrivial) { | 3518 if (!getLine(line).isTrivial) { |
3529 // TODO(johnmccutchan): end token pos -> column can lie for snapshotted | 3519 // TODO(johnmccutchan): end token pos -> column can lie for snapshotted |
3530 // code. e.g.: | 3520 // code. e.g.: |
3531 // io_sink.dart source line 23 ends at column 39 | 3521 // io_sink.dart source line 23 ends at column 39 |
3532 // io_sink.dart snapshotted source line 23 ends at column 35. | 3522 // io_sink.dart snapshotted source line 23 ends at column 35. |
3533 lastColumn = math.min(getLine(line).text.length, lastColumn); | 3523 lastColumn = math.min(getLine(line).text.length, lastColumn); |
3534 lineContents = getLine(line).text.substring(0, lastColumn - 1); | 3524 lineContents = getLine(line).text.substring(0, lastColumn - 1); |
3535 r.addAll( | 3525 r.addAll(scanLineForLocalVariableLocations( |
3536 scanLineForLocalVariableLocations(pattern, | 3526 pattern, name, lineContents, line, 0)); |
3537 name, | |
3538 lineContents, | |
3539 line, | |
3540 0)); | |
3541 } | 3527 } |
3542 return r; | 3528 return r; |
3543 } | 3529 } |
3544 } | 3530 } |
3545 | 3531 |
3546 class PcDescriptor { | 3532 class PcDescriptor { |
3547 final int pcOffset; | 3533 final int pcOffset; |
3548 final int deoptId; | 3534 final int deoptId; |
3549 final int tokenPos; | 3535 final int tokenPos; |
3550 final int tryIndex; | 3536 final int tryIndex; |
3551 final String kind; | 3537 final String kind; |
3552 Script script; | 3538 Script script; |
3553 String formattedLine; | 3539 String formattedLine; |
3554 PcDescriptor(this.pcOffset, this.deoptId, this.tokenPos, this.tryIndex, | 3540 PcDescriptor( |
3555 this.kind); | 3541 this.pcOffset, this.deoptId, this.tokenPos, this.tryIndex, this.kind); |
3556 | 3542 |
3557 String formattedDeoptId() { | 3543 String formattedDeoptId() { |
3558 if (deoptId == -1) { | 3544 if (deoptId == -1) { |
3559 return 'N/A'; | 3545 return 'N/A'; |
3560 } | 3546 } |
3561 return deoptId.toString(); | 3547 return deoptId.toString(); |
3562 } | 3548 } |
3563 | 3549 |
3564 String formattedTokenPos() { | 3550 String formattedTokenPos() { |
3565 if (tokenPos == -1) { | 3551 if (tokenPos == -1) { |
(...skipping 16 matching lines...) Expand all Loading... |
3582 formattedLine = scriptLine.text; | 3568 formattedLine = scriptLine.text; |
3583 } | 3569 } |
3584 } | 3570 } |
3585 | 3571 |
3586 class PcDescriptors extends ServiceObject implements M.PcDescriptorsRef { | 3572 class PcDescriptors extends ServiceObject implements M.PcDescriptorsRef { |
3587 Class clazz; | 3573 Class clazz; |
3588 int size; | 3574 int size; |
3589 bool get immutable => true; | 3575 bool get immutable => true; |
3590 final List<PcDescriptor> descriptors = <PcDescriptor>[]; | 3576 final List<PcDescriptor> descriptors = <PcDescriptor>[]; |
3591 | 3577 |
3592 PcDescriptors._empty(ServiceObjectOwner owner) : super._empty(owner) { | 3578 PcDescriptors._empty(ServiceObjectOwner owner) : super._empty(owner) {} |
3593 } | |
3594 | 3579 |
3595 void _update(Map m, bool mapIsRef) { | 3580 void _update(Map m, bool mapIsRef) { |
3596 if (mapIsRef) { | 3581 if (mapIsRef) { |
3597 return; | 3582 return; |
3598 } | 3583 } |
3599 _upgradeCollection(m, isolate); | 3584 _upgradeCollection(m, isolate); |
3600 clazz = m['class']; | 3585 clazz = m['class']; |
3601 size = m['size']; | 3586 size = m['size']; |
3602 descriptors.clear(); | 3587 descriptors.clear(); |
3603 for (var descriptor in m['members']) { | 3588 for (var descriptor in m['members']) { |
3604 var pcOffset = int.parse(descriptor['pcOffset'], radix:16); | 3589 var pcOffset = int.parse(descriptor['pcOffset'], radix: 16); |
3605 var deoptId = descriptor['deoptId']; | 3590 var deoptId = descriptor['deoptId']; |
3606 var tokenPos = descriptor['tokenPos']; | 3591 var tokenPos = descriptor['tokenPos']; |
3607 var tryIndex = descriptor['tryIndex']; | 3592 var tryIndex = descriptor['tryIndex']; |
3608 var kind = descriptor['kind'].trim(); | 3593 var kind = descriptor['kind'].trim(); |
3609 descriptors.add( | 3594 descriptors |
3610 new PcDescriptor(pcOffset, deoptId, tokenPos, tryIndex, kind)); | 3595 .add(new PcDescriptor(pcOffset, deoptId, tokenPos, tryIndex, kind)); |
3611 } | 3596 } |
3612 } | 3597 } |
3613 } | 3598 } |
3614 | 3599 |
3615 class LocalVarDescriptor implements M.LocalVarDescriptorsRef { | 3600 class LocalVarDescriptor implements M.LocalVarDescriptorsRef { |
3616 final String id; | 3601 final String id; |
3617 final String name; | 3602 final String name; |
3618 final int index; | 3603 final int index; |
3619 final int beginPos; | 3604 final int beginPos; |
3620 final int endPos; | 3605 final int endPos; |
3621 final int scopeId; | 3606 final int scopeId; |
3622 final String kind; | 3607 final String kind; |
3623 | 3608 |
3624 LocalVarDescriptor(this.id, this.name, this.index, this.beginPos, this.endPos, | 3609 LocalVarDescriptor(this.id, this.name, this.index, this.beginPos, this.endPos, |
3625 this.scopeId, this.kind); | 3610 this.scopeId, this.kind); |
3626 } | 3611 } |
3627 | 3612 |
3628 class LocalVarDescriptors extends ServiceObject { | 3613 class LocalVarDescriptors extends ServiceObject { |
3629 Class clazz; | 3614 Class clazz; |
3630 int size; | 3615 int size; |
3631 bool get immutable => true; | 3616 bool get immutable => true; |
3632 final List<LocalVarDescriptor> descriptors = <LocalVarDescriptor>[]; | 3617 final List<LocalVarDescriptor> descriptors = <LocalVarDescriptor>[]; |
3633 LocalVarDescriptors._empty(ServiceObjectOwner owner) : super._empty(owner); | 3618 LocalVarDescriptors._empty(ServiceObjectOwner owner) : super._empty(owner); |
3634 | 3619 |
3635 void _update(Map m, bool mapIsRef) { | 3620 void _update(Map m, bool mapIsRef) { |
3636 if (mapIsRef) { | 3621 if (mapIsRef) { |
3637 return; | 3622 return; |
3638 } | 3623 } |
3639 _upgradeCollection(m, isolate); | 3624 _upgradeCollection(m, isolate); |
3640 clazz = m['class']; | 3625 clazz = m['class']; |
3641 size = m['size']; | 3626 size = m['size']; |
3642 descriptors.clear(); | 3627 descriptors.clear(); |
3643 for (var descriptor in m['members']) { | 3628 for (var descriptor in m['members']) { |
3644 var id = descriptor['name']; | 3629 var id = descriptor['name']; |
3645 var name = descriptor['name']; | 3630 var name = descriptor['name']; |
3646 var index = descriptor['index']; | 3631 var index = descriptor['index']; |
3647 var beginPos = descriptor['beginPos']; | 3632 var beginPos = descriptor['beginPos']; |
3648 var endPos = descriptor['endPos']; | 3633 var endPos = descriptor['endPos']; |
3649 var scopeId = descriptor['scopeId']; | 3634 var scopeId = descriptor['scopeId']; |
3650 var kind = descriptor['kind'].trim(); | 3635 var kind = descriptor['kind'].trim(); |
3651 descriptors.add( | 3636 descriptors.add(new LocalVarDescriptor( |
3652 new LocalVarDescriptor(id, name, index, beginPos, endPos, scopeId, | 3637 id, name, index, beginPos, endPos, scopeId, kind)); |
3653 kind)); | |
3654 } | 3638 } |
3655 } | 3639 } |
3656 } | 3640 } |
3657 | 3641 |
3658 class ObjectPool extends HeapObject implements M.ObjectPool { | 3642 class ObjectPool extends HeapObject implements M.ObjectPool { |
3659 bool get immutable => false; | 3643 bool get immutable => false; |
3660 | 3644 |
3661 int length; | 3645 int length; |
3662 List<ObjectPoolEntry> entries; | 3646 List<ObjectPoolEntry> entries; |
3663 | 3647 |
(...skipping 22 matching lines...) Expand all Loading... |
3686 int offset = map['offset']; | 3670 int offset = map['offset']; |
3687 switch (kind) { | 3671 switch (kind) { |
3688 case M.ObjectPoolEntryKind.object: | 3672 case M.ObjectPoolEntryKind.object: |
3689 return new ObjectPoolEntry._fromObject(map['value'], offset); | 3673 return new ObjectPoolEntry._fromObject(map['value'], offset); |
3690 default: | 3674 default: |
3691 return new ObjectPoolEntry._fromInteger(kind, map['value'], offset); | 3675 return new ObjectPoolEntry._fromInteger(kind, map['value'], offset); |
3692 } | 3676 } |
3693 } | 3677 } |
3694 | 3678 |
3695 ObjectPoolEntry._fromObject(this.asObject, this.offset) | 3679 ObjectPoolEntry._fromObject(this.asObject, this.offset) |
3696 : kind = M.ObjectPoolEntryKind.object, | 3680 : kind = M.ObjectPoolEntryKind.object, |
3697 asInteger = null; | 3681 asInteger = null; |
3698 | 3682 |
3699 ObjectPoolEntry._fromInteger(this.kind, this.asInteger, this.offset) | 3683 ObjectPoolEntry._fromInteger(this.kind, this.asInteger, this.offset) |
3700 : asObject = null; | 3684 : asObject = null; |
3701 } | 3685 } |
3702 | 3686 |
3703 M.ObjectPoolEntryKind stringToObjectPoolEntryKind(String kind) { | 3687 M.ObjectPoolEntryKind stringToObjectPoolEntryKind(String kind) { |
3704 switch (kind) { | 3688 switch (kind) { |
3705 case 'Object': | 3689 case 'Object': |
3706 return M.ObjectPoolEntryKind.object; | 3690 return M.ObjectPoolEntryKind.object; |
3707 case 'Immediate': | 3691 case 'Immediate': |
3708 return M.ObjectPoolEntryKind.immediate; | 3692 return M.ObjectPoolEntryKind.immediate; |
3709 case 'NativeEntry': | 3693 case 'NativeEntry': |
3710 return M.ObjectPoolEntryKind.nativeEntry; | 3694 return M.ObjectPoolEntryKind.nativeEntry; |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3820 | 3804 |
3821 class CodeInstruction { | 3805 class CodeInstruction { |
3822 final int address; | 3806 final int address; |
3823 final int pcOffset; | 3807 final int pcOffset; |
3824 final String machine; | 3808 final String machine; |
3825 final String human; | 3809 final String human; |
3826 final ServiceObject object; | 3810 final ServiceObject object; |
3827 CodeInstruction jumpTarget; | 3811 CodeInstruction jumpTarget; |
3828 List<PcDescriptor> descriptors = <PcDescriptor>[]; | 3812 List<PcDescriptor> descriptors = <PcDescriptor>[]; |
3829 | 3813 |
3830 CodeInstruction(this.address, | 3814 CodeInstruction( |
3831 this.pcOffset, | 3815 this.address, this.pcOffset, this.machine, this.human, this.object); |
3832 this.machine, | |
3833 this.human, | |
3834 this.object); | |
3835 | 3816 |
3836 bool get isComment => address == 0; | 3817 bool get isComment => address == 0; |
3837 bool get hasDescriptors => descriptors.length > 0; | 3818 bool get hasDescriptors => descriptors.length > 0; |
3838 | 3819 |
3839 bool _isJumpInstruction() { | 3820 bool _isJumpInstruction() { |
3840 return human.startsWith('j'); | 3821 return human.startsWith('j'); |
3841 } | 3822 } |
3842 | 3823 |
3843 int _getJumpAddress() { | 3824 int _getJumpAddress() { |
3844 assert(_isJumpInstruction()); | 3825 assert(_isJumpInstruction()); |
3845 var chunks = human.split(' '); | 3826 var chunks = human.split(' '); |
3846 if (chunks.length != 2) { | 3827 if (chunks.length != 2) { |
3847 // We expect jump instructions to be of the form 'j.. address'. | 3828 // We expect jump instructions to be of the form 'j.. address'. |
3848 return 0; | 3829 return 0; |
3849 } | 3830 } |
3850 var address = chunks[1]; | 3831 var address = chunks[1]; |
3851 if (address.startsWith('0x')) { | 3832 if (address.startsWith('0x')) { |
3852 // Chop off the 0x. | 3833 // Chop off the 0x. |
3853 address = address.substring(2); | 3834 address = address.substring(2); |
3854 } | 3835 } |
3855 try { | 3836 try { |
3856 return int.parse(address, radix:16); | 3837 return int.parse(address, radix: 16); |
3857 } catch (_) { | 3838 } catch (_) { |
3858 return 0; | 3839 return 0; |
3859 } | 3840 } |
3860 } | 3841 } |
3861 | 3842 |
3862 void _resolveJumpTarget(List<CodeInstruction> instructionsByAddressOffset, | 3843 void _resolveJumpTarget( |
3863 int startAddress) { | 3844 List<CodeInstruction> instructionsByAddressOffset, int startAddress) { |
3864 if (!_isJumpInstruction()) { | 3845 if (!_isJumpInstruction()) { |
3865 return; | 3846 return; |
3866 } | 3847 } |
3867 int address = _getJumpAddress(); | 3848 int address = _getJumpAddress(); |
3868 if (address == 0) { | 3849 if (address == 0) { |
3869 return; | 3850 return; |
3870 } | 3851 } |
3871 var relativeAddress = address - startAddress; | 3852 var relativeAddress = address - startAddress; |
3872 if (relativeAddress < 0) { | 3853 if (relativeAddress < 0) { |
3873 Logger.root.warning('Bad address resolving jump target $relativeAddress'); | 3854 Logger.root.warning('Bad address resolving jump target $relativeAddress'); |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3934 descriptor.processScript(script); | 3915 descriptor.processScript(script); |
3935 } | 3916 } |
3936 } | 3917 } |
3937 } | 3918 } |
3938 | 3919 |
3939 void loadScript() { | 3920 void loadScript() { |
3940 if (script != null) { | 3921 if (script != null) { |
3941 // Already done. | 3922 // Already done. |
3942 return; | 3923 return; |
3943 } | 3924 } |
3944 if (kind != M.CodeKind.dart){ | 3925 if (kind != M.CodeKind.dart) { |
3945 return; | 3926 return; |
3946 } | 3927 } |
3947 if (function == null) { | 3928 if (function == null) { |
3948 return; | 3929 return; |
3949 } | 3930 } |
3950 if ((function.location == null) || | 3931 if ((function.location == null) || (function.location.script == null)) { |
3951 (function.location.script == null)) { | |
3952 // Attempt to load the function. | 3932 // Attempt to load the function. |
3953 function.load().then((func) { | 3933 function.load().then((func) { |
3954 var script = function.location.script; | 3934 var script = function.location.script; |
3955 if (script == null) { | 3935 if (script == null) { |
3956 // Function doesn't have an associated script. | 3936 // Function doesn't have an associated script. |
3957 return; | 3937 return; |
3958 } | 3938 } |
3959 // Load the script and then update descriptors. | 3939 // Load the script and then update descriptors. |
3960 script.load().then(_updateDescriptors); | 3940 script.load().then(_updateDescriptors); |
3961 }); | 3941 }); |
(...skipping 18 matching lines...) Expand all Loading... |
3980 name = m['name']; | 3960 name = m['name']; |
3981 vmName = (m.containsKey('_vmName') ? m['_vmName'] : name); | 3961 vmName = (m.containsKey('_vmName') ? m['_vmName'] : name); |
3982 isOptimized = m['_optimized']; | 3962 isOptimized = m['_optimized']; |
3983 kind = stringToCodeKind(m['kind']); | 3963 kind = stringToCodeKind(m['kind']); |
3984 hasIntrinsic = m['_intrinsic']; | 3964 hasIntrinsic = m['_intrinsic']; |
3985 isNative = m['_native']; | 3965 isNative = m['_native']; |
3986 if (mapIsRef) { | 3966 if (mapIsRef) { |
3987 return; | 3967 return; |
3988 } | 3968 } |
3989 _loaded = true; | 3969 _loaded = true; |
3990 startAddress = int.parse(m['_startAddress'], radix:16); | 3970 startAddress = int.parse(m['_startAddress'], radix: 16); |
3991 endAddress = int.parse(m['_endAddress'], radix:16); | 3971 endAddress = int.parse(m['_endAddress'], radix: 16); |
3992 function = isolate.getFromMap(m['function']); | 3972 function = isolate.getFromMap(m['function']); |
3993 objectPool = isolate.getFromMap(m['_objectPool']); | 3973 objectPool = isolate.getFromMap(m['_objectPool']); |
3994 var disassembly = m['_disassembly']; | 3974 var disassembly = m['_disassembly']; |
3995 if (disassembly != null) { | 3975 if (disassembly != null) { |
3996 _processDisassembly(disassembly); | 3976 _processDisassembly(disassembly); |
3997 } | 3977 } |
3998 var descriptors = m['_descriptors']; | 3978 var descriptors = m['_descriptors']; |
3999 if (descriptors != null) { | 3979 if (descriptors != null) { |
4000 descriptors = descriptors['members']; | 3980 descriptors = descriptors['members']; |
4001 _processDescriptors(descriptors); | 3981 _processDescriptors(descriptors); |
(...skipping 28 matching lines...) Expand all Loading... |
4030 for (var i = 0; i < inlineIntervals.length; i++) { | 4010 for (var i = 0; i < inlineIntervals.length; i++) { |
4031 var interval = inlineIntervals[i]; | 4011 var interval = inlineIntervals[i]; |
4032 if (interval.contains(pc)) { | 4012 if (interval.contains(pc)) { |
4033 return interval; | 4013 return interval; |
4034 } | 4014 } |
4035 } | 4015 } |
4036 return null; | 4016 return null; |
4037 } | 4017 } |
4038 | 4018 |
4039 void _processInline(List<ServiceFunction> inlinedFunctionsTable, | 4019 void _processInline(List<ServiceFunction> inlinedFunctionsTable, |
4040 List<List<int>> inlinedIntervals) { | 4020 List<List<int>> inlinedIntervals) { |
4041 for (var i = 0; i < inlinedIntervals.length; i++) { | 4021 for (var i = 0; i < inlinedIntervals.length; i++) { |
4042 var inlinedInterval = inlinedIntervals[i]; | 4022 var inlinedInterval = inlinedIntervals[i]; |
4043 var start = inlinedInterval[0] + startAddress; | 4023 var start = inlinedInterval[0] + startAddress; |
4044 var end = inlinedInterval[1] + startAddress; | 4024 var end = inlinedInterval[1] + startAddress; |
4045 var codeInlineInterval = new CodeInlineInterval(start, end); | 4025 var codeInlineInterval = new CodeInlineInterval(start, end); |
4046 for (var i = 2; i < inlinedInterval.length - 1; i++) { | 4026 for (var i = 2; i < inlinedInterval.length - 1; i++) { |
4047 var inline_id = inlinedInterval[i]; | 4027 var inline_id = inlinedInterval[i]; |
4048 if (inline_id < 0) { | 4028 if (inline_id < 0) { |
4049 continue; | 4029 continue; |
4050 } | 4030 } |
4051 var function = inlinedFunctionsTable[inline_id]; | 4031 var function = inlinedFunctionsTable[inline_id]; |
4052 codeInlineInterval.functions.add(function); | 4032 codeInlineInterval.functions.add(function); |
4053 } | 4033 } |
4054 inlineIntervals.add(codeInlineInterval); | 4034 inlineIntervals.add(codeInlineInterval); |
4055 } | 4035 } |
4056 } | 4036 } |
4057 | 4037 |
4058 bool hasDisassembly = false; | 4038 bool hasDisassembly = false; |
4059 | 4039 |
4060 void _processDisassembly(List disassembly) { | 4040 void _processDisassembly(List disassembly) { |
4061 assert(disassembly != null); | 4041 assert(disassembly != null); |
4062 instructions.clear(); | 4042 instructions.clear(); |
4063 instructionsByAddressOffset = new List(endAddress - startAddress); | 4043 instructionsByAddressOffset = new List(endAddress - startAddress); |
4064 | 4044 |
4065 assert((disassembly.length % 4) == 0); | 4045 assert((disassembly.length % 4) == 0); |
4066 for (var i = 0; i < disassembly.length; i += 4) { | 4046 for (var i = 0; i < disassembly.length; i += 4) { |
4067 var address = 0; // Assume code comment. | 4047 var address = 0; // Assume code comment. |
4068 var machine = disassembly[i + 1]; | 4048 var machine = disassembly[i + 1]; |
4069 var human = disassembly[i + 2]; | 4049 var human = disassembly[i + 2]; |
4070 var object = disassembly[i + 3]; | 4050 var object = disassembly[i + 3]; |
4071 if (object != null) { | 4051 if (object != null) { |
4072 object = new ServiceObject._fromMap(owner, object); | 4052 object = new ServiceObject._fromMap(owner, object); |
4073 } | 4053 } |
4074 var pcOffset = 0; | 4054 var pcOffset = 0; |
4075 if (disassembly[i] != null) { | 4055 if (disassembly[i] != null) { |
4076 // Not a code comment, extract address. | 4056 // Not a code comment, extract address. |
4077 address = int.parse(disassembly[i], radix:16); | 4057 address = int.parse(disassembly[i], radix: 16); |
4078 pcOffset = address - startAddress; | 4058 pcOffset = address - startAddress; |
4079 } | 4059 } |
4080 var instruction = | 4060 var instruction = |
4081 new CodeInstruction(address, pcOffset, machine, human, object); | 4061 new CodeInstruction(address, pcOffset, machine, human, object); |
4082 instructions.add(instruction); | 4062 instructions.add(instruction); |
4083 if (disassembly[i] != null) { | 4063 if (disassembly[i] != null) { |
4084 // Not a code comment. | 4064 // Not a code comment. |
4085 instructionsByAddressOffset[pcOffset] = instruction; | 4065 instructionsByAddressOffset[pcOffset] = instruction; |
4086 } | 4066 } |
4087 } | 4067 } |
4088 for (var instruction in instructions) { | 4068 for (var instruction in instructions) { |
4089 instruction._resolveJumpTarget(instructionsByAddressOffset, startAddress); | 4069 instruction._resolveJumpTarget(instructionsByAddressOffset, startAddress); |
4090 } | 4070 } |
4091 } | 4071 } |
4092 | 4072 |
4093 void _processDescriptors(List<Map> descriptors) { | 4073 void _processDescriptors(List<Map> descriptors) { |
4094 for (Map descriptor in descriptors) { | 4074 for (Map descriptor in descriptors) { |
4095 var pcOffset = int.parse(descriptor['pcOffset'], radix:16); | 4075 var pcOffset = int.parse(descriptor['pcOffset'], radix: 16); |
4096 var address = startAddress + pcOffset; | 4076 var address = startAddress + pcOffset; |
4097 var deoptId = descriptor['deoptId']; | 4077 var deoptId = descriptor['deoptId']; |
4098 var tokenPos = descriptor['tokenPos']; | 4078 var tokenPos = descriptor['tokenPos']; |
4099 var tryIndex = descriptor['tryIndex']; | 4079 var tryIndex = descriptor['tryIndex']; |
4100 var kind = descriptor['kind'].trim(); | 4080 var kind = descriptor['kind'].trim(); |
4101 | 4081 |
4102 var instruction = instructionsByAddressOffset[address - startAddress]; | 4082 var instruction = instructionsByAddressOffset[address - startAddress]; |
4103 if (instruction != null) { | 4083 if (instruction != null) { |
4104 instruction.descriptors.add(new PcDescriptor(pcOffset, | 4084 instruction.descriptors |
4105 deoptId, | 4085 .add(new PcDescriptor(pcOffset, deoptId, tokenPos, tryIndex, kind)); |
4106 tokenPos, | |
4107 tryIndex, | |
4108 kind)); | |
4109 } else { | 4086 } else { |
4110 Logger.root.warning( | 4087 Logger.root.warning( |
4111 'Could not find instruction with pc descriptor address: $address'); | 4088 'Could not find instruction with pc descriptor address: $address'); |
4112 } | 4089 } |
4113 } | 4090 } |
4114 } | 4091 } |
4115 | 4092 |
4116 /// Returns true if [address] is contained inside [this]. | 4093 /// Returns true if [address] is contained inside [this]. |
4117 bool contains(int address) { | 4094 bool contains(int address) { |
4118 return (address >= startAddress) && (address < endAddress); | 4095 return (address >= startAddress) && (address < endAddress); |
4119 } | 4096 } |
4120 | 4097 |
4121 bool get isDartCode => (kind == M.CodeKind.dart) || | 4098 bool get isDartCode => (kind == M.CodeKind.dart) || (kind == M.CodeKind.stub); |
4122 (kind == M.CodeKind.stub); | |
4123 | 4099 |
4124 String toString() => 'Code($kind, $name)'; | 4100 String toString() => 'Code($kind, $name)'; |
4125 } | 4101 } |
4126 | 4102 |
4127 | |
4128 class SocketKind { | 4103 class SocketKind { |
4129 final _value; | 4104 final _value; |
4130 const SocketKind._internal(this._value); | 4105 const SocketKind._internal(this._value); |
4131 String toString() => '$_value'; | 4106 String toString() => '$_value'; |
4132 | 4107 |
4133 static SocketKind fromString(String s) { | 4108 static SocketKind fromString(String s) { |
4134 if (s == 'Listening') { | 4109 if (s == 'Listening') { |
4135 return Listening; | 4110 return Listening; |
4136 } else if (s == 'Normal') { | 4111 } else if (s == 'Normal') { |
4137 return Normal; | 4112 return Normal; |
4138 } else if (s == 'Pipe') { | 4113 } else if (s == 'Pipe') { |
4139 return Pipe; | 4114 return Pipe; |
4140 } else if (s == 'Internal') { | 4115 } else if (s == 'Internal') { |
4141 return Internal; | 4116 return Internal; |
4142 } | 4117 } |
4143 Logger.root.warning('Unknown socket kind $s'); | 4118 Logger.root.warning('Unknown socket kind $s'); |
4144 throw new FallThroughError(); | 4119 throw new FallThroughError(); |
4145 } | 4120 } |
| 4121 |
4146 static const Listening = const SocketKind._internal('Listening'); | 4122 static const Listening = const SocketKind._internal('Listening'); |
4147 static const Normal = const SocketKind._internal('Normal'); | 4123 static const Normal = const SocketKind._internal('Normal'); |
4148 static const Pipe = const SocketKind._internal('Pipe'); | 4124 static const Pipe = const SocketKind._internal('Pipe'); |
4149 static const Internal = const SocketKind._internal('Internal'); | 4125 static const Internal = const SocketKind._internal('Internal'); |
4150 } | 4126 } |
4151 | 4127 |
4152 /// A snapshot of statistics associated with a [Socket]. | 4128 /// A snapshot of statistics associated with a [Socket]. |
4153 class SocketStats { | 4129 class SocketStats { |
4154 final int bytesRead; | 4130 final int bytesRead; |
4155 final int bytesWritten; | 4131 final int bytesWritten; |
4156 final int readCalls; | 4132 final int readCalls; |
4157 final int writeCalls; | 4133 final int writeCalls; |
4158 final int available; | 4134 final int available; |
4159 | 4135 |
4160 SocketStats(this.bytesRead, this.bytesWritten, | 4136 SocketStats(this.bytesRead, this.bytesWritten, this.readCalls, |
4161 this.readCalls, this.writeCalls, | 4137 this.writeCalls, this.available); |
4162 this.available); | |
4163 } | 4138 } |
4164 | 4139 |
4165 /// A peer to a Socket in dart:io. Sockets can represent network sockets or | 4140 /// A peer to a Socket in dart:io. Sockets can represent network sockets or |
4166 /// OS pipes. Each socket is owned by another ServceObject, for example, | 4141 /// OS pipes. Each socket is owned by another ServceObject, for example, |
4167 /// a process or an HTTP server. | 4142 /// a process or an HTTP server. |
4168 class Socket extends ServiceObject { | 4143 class Socket extends ServiceObject { |
4169 Socket._empty(ServiceObjectOwner owner) : super._empty(owner); | 4144 Socket._empty(ServiceObjectOwner owner) : super._empty(owner); |
4170 | 4145 |
4171 ServiceObject socketOwner; | 4146 ServiceObject socketOwner; |
4172 | 4147 |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4219 localPort = map['localPort']; | 4194 localPort = map['localPort']; |
4220 remoteAddress = map['remoteAddress']; | 4195 remoteAddress = map['remoteAddress']; |
4221 remotePort = map['remotePort']; | 4196 remotePort = map['remotePort']; |
4222 | 4197 |
4223 fd = map['fd']; | 4198 fd = map['fd']; |
4224 socketOwner = map['owner']; | 4199 socketOwner = map['owner']; |
4225 } | 4200 } |
4226 } | 4201 } |
4227 | 4202 |
4228 class ServiceMetric extends ServiceObject implements M.Metric { | 4203 class ServiceMetric extends ServiceObject implements M.Metric { |
4229 ServiceMetric._empty(ServiceObjectOwner owner) : super._empty(owner) { | 4204 ServiceMetric._empty(ServiceObjectOwner owner) : super._empty(owner) {} |
4230 } | |
4231 | 4205 |
4232 bool get immutable => false; | 4206 bool get immutable => false; |
4233 | 4207 |
4234 Future<Map> _fetchDirect({int count: kDefaultFieldLimit}) { | 4208 Future<Map> _fetchDirect({int count: kDefaultFieldLimit}) { |
4235 assert(owner is Isolate); | 4209 assert(owner is Isolate); |
4236 return isolate.invokeRpcNoUpgrade('_getIsolateMetric', { 'metricId': id }); | 4210 return isolate.invokeRpcNoUpgrade('_getIsolateMetric', {'metricId': id}); |
4237 } | 4211 } |
4238 | 4212 |
4239 String description; | 4213 String description; |
4240 double value = 0.0; | 4214 double value = 0.0; |
4241 // Only a guage has a non-null min and max. | 4215 // Only a guage has a non-null min and max. |
4242 double min; | 4216 double min; |
4243 double max; | 4217 double max; |
4244 | 4218 |
4245 bool get isGauge => (min != null) && (max != null); | 4219 bool get isGauge => (min != null) && (max != null); |
4246 | 4220 |
(...skipping 25 matching lines...) Expand all Loading... |
4272 this.index = map['index']; | 4246 this.index = map['index']; |
4273 this.function = map['function']; | 4247 this.function = map['function']; |
4274 this.location = map['location']; | 4248 this.location = map['location']; |
4275 this.code = map['code']; | 4249 this.code = map['code']; |
4276 this.variables = map['vars']; | 4250 this.variables = map['vars']; |
4277 } | 4251 } |
4278 | 4252 |
4279 String toString() => "Frame(${function.qualifiedName} $location)"; | 4253 String toString() => "Frame(${function.qualifiedName} $location)"; |
4280 } | 4254 } |
4281 | 4255 |
4282 | |
4283 class ServiceMessage extends ServiceObject { | 4256 class ServiceMessage extends ServiceObject { |
4284 int index; | 4257 int index; |
4285 String messageObjectId; | 4258 String messageObjectId; |
4286 int size; | 4259 int size; |
4287 ServiceFunction handler; | 4260 ServiceFunction handler; |
4288 SourceLocation location; | 4261 SourceLocation location; |
4289 | 4262 |
4290 ServiceMessage._empty(ServiceObject owner) : super._empty(owner); | 4263 ServiceMessage._empty(ServiceObject owner) : super._empty(owner); |
4291 | 4264 |
4292 void _update(Map map, bool mapIsRef) { | 4265 void _update(Map map, bool mapIsRef) { |
4293 assert(!mapIsRef); | 4266 assert(!mapIsRef); |
4294 _loaded = true; | 4267 _loaded = true; |
4295 _upgradeCollection(map, owner); | 4268 _upgradeCollection(map, owner); |
4296 this.messageObjectId = map['messageObjectId']; | 4269 this.messageObjectId = map['messageObjectId']; |
4297 this.index = map['index']; | 4270 this.index = map['index']; |
4298 this.size = map['size']; | 4271 this.size = map['size']; |
4299 this.handler = map['handler']; | 4272 this.handler = map['handler']; |
4300 this.location = map['location']; | 4273 this.location = map['location']; |
4301 } | 4274 } |
4302 } | 4275 } |
4303 | 4276 |
4304 | |
4305 // Helper function to extract possible breakpoint locations from a | 4277 // Helper function to extract possible breakpoint locations from a |
4306 // SourceReport for some script. | 4278 // SourceReport for some script. |
4307 Set<int> getPossibleBreakpointLines(ServiceMap report, Script script) { | 4279 Set<int> getPossibleBreakpointLines(ServiceMap report, Script script) { |
4308 var result = new Set<int>(); | 4280 var result = new Set<int>(); |
4309 int scriptIndex; | 4281 int scriptIndex; |
4310 int numScripts = report['scripts'].length; | 4282 int numScripts = report['scripts'].length; |
4311 for (scriptIndex = 0; scriptIndex < numScripts; scriptIndex++) { | 4283 for (scriptIndex = 0; scriptIndex < numScripts; scriptIndex++) { |
4312 if (report['scripts'][scriptIndex].id == script.id) { | 4284 if (report['scripts'][scriptIndex].id == script.id) { |
4313 break; | 4285 break; |
4314 } | 4286 } |
(...skipping 21 matching lines...) Expand all Loading... |
4336 if (!script.getLine(line).isTrivial) { | 4308 if (!script.getLine(line).isTrivial) { |
4337 result.add(line); | 4309 result.add(line); |
4338 } | 4310 } |
4339 } | 4311 } |
4340 } | 4312 } |
4341 } | 4313 } |
4342 } | 4314 } |
4343 return result; | 4315 return result; |
4344 } | 4316 } |
4345 | 4317 |
4346 | |
4347 // Returns true if [map] is a service map. i.e. it has the following keys: | 4318 // Returns true if [map] is a service map. i.e. it has the following keys: |
4348 // 'id' and a 'type'. | 4319 // 'id' and a 'type'. |
4349 bool _isServiceMap(Map m) { | 4320 bool _isServiceMap(Map m) { |
4350 return (m != null) && (m['type'] != null); | 4321 return (m != null) && (m['type'] != null); |
4351 } | 4322 } |
4352 | 4323 |
4353 bool _hasRef(String type) => type.startsWith('@'); | 4324 bool _hasRef(String type) => type.startsWith('@'); |
4354 String _stripRef(String type) => (_hasRef(type) ? type.substring(1) : type); | 4325 String _stripRef(String type) => (_hasRef(type) ? type.substring(1) : type); |
4355 | 4326 |
4356 /// Recursively upgrades all [ServiceObject]s inside [collection] which must | 4327 /// Recursively upgrades all [ServiceObject]s inside [collection] which must |
(...skipping 27 matching lines...) Expand all Loading... |
4384 var v = list[i]; | 4355 var v = list[i]; |
4385 if ((v is Map) && _isServiceMap(v)) { | 4356 if ((v is Map) && _isServiceMap(v)) { |
4386 list[i] = owner.getFromMap(v); | 4357 list[i] = owner.getFromMap(v); |
4387 } else if (v is List) { | 4358 } else if (v is List) { |
4388 _upgradeList(v, owner); | 4359 _upgradeList(v, owner); |
4389 } else if (v is Map) { | 4360 } else if (v is Map) { |
4390 _upgradeMap(v, owner); | 4361 _upgradeMap(v, owner); |
4391 } | 4362 } |
4392 } | 4363 } |
4393 } | 4364 } |
OLD | NEW |