Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 part of service; | 5 part of service; |
| 6 | 6 |
| 7 /// A [ServiceObject] represents a persistent object within the vm. | 7 /// A [ServiceObject] represents a persistent object within the vm. |
| 8 abstract class ServiceObject extends Observable { | 8 abstract class ServiceObject extends Observable { |
| 9 static int LexicalSortName(ServiceObject o1, ServiceObject o2) { | 9 static int LexicalSortName(ServiceObject o1, ServiceObject o2) { |
| 10 return o1.name.compareTo(o2.name); | 10 return o1.name.compareTo(o2.name); |
| (...skipping 325 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 336 // TODO(johnmccutchan): Ensure that isolates do not end up in _cache. | 336 // TODO(johnmccutchan): Ensure that isolates do not end up in _cache. |
| 337 Map<String,ServiceObject> _cache = new Map<String,ServiceObject>(); | 337 Map<String,ServiceObject> _cache = new Map<String,ServiceObject>(); |
| 338 final ObservableMap<String,Isolate> _isolateCache = | 338 final ObservableMap<String,Isolate> _isolateCache = |
| 339 new ObservableMap<String,Isolate>(); | 339 new ObservableMap<String,Isolate>(); |
| 340 | 340 |
| 341 @reflectable Iterable<Isolate> get isolates => _isolateCache.values; | 341 @reflectable Iterable<Isolate> get isolates => _isolateCache.values; |
| 342 | 342 |
| 343 @observable String version = 'unknown'; | 343 @observable String version = 'unknown'; |
| 344 @observable String targetCPU; | 344 @observable String targetCPU; |
| 345 @observable int architectureBits; | 345 @observable int architectureBits; |
| 346 @observable double uptime = 0.0; | |
| 347 @observable bool assertsEnabled = false; | 346 @observable bool assertsEnabled = false; |
| 348 @observable bool typeChecksEnabled = false; | 347 @observable bool typeChecksEnabled = false; |
| 349 @observable String pid = ''; | 348 @observable String pid = ''; |
| 350 @observable DateTime lastUpdate; | 349 @observable DateTime startTime; |
| 350 @observable DateTime refreshTime; | |
| 351 @observable Duration get upTime => | |
| 352 (new DateTime.now().difference(startTime)); | |
| 351 | 353 |
| 352 VM() : super._empty(null) { | 354 VM() : super._empty(null) { |
| 353 name = 'vm'; | 355 name = 'vm'; |
| 354 vmName = 'vm'; | 356 vmName = 'vm'; |
| 355 _cache['vm'] = this; | 357 _cache['vm'] = this; |
| 356 update(toObservable({'id':'vm', 'type':'@VM'})); | 358 update(toObservable({'id':'vm', 'type':'@VM'})); |
| 357 } | 359 } |
| 358 | 360 |
| 359 final StreamController<ServiceException> exceptions = | 361 final StreamController<ServiceException> exceptions = |
| 360 new StreamController.broadcast(); | 362 new StreamController.broadcast(); |
| 361 final StreamController<ServiceError> errors = | 363 final StreamController<ServiceError> errors = |
| 362 new StreamController.broadcast(); | 364 new StreamController.broadcast(); |
| 363 final StreamController<ServiceEvent> events = | 365 final StreamController<ServiceEvent> events = |
| 364 new StreamController.broadcast(); | 366 new StreamController.broadcast(); |
| 365 | 367 |
| 366 bool _isIsolateLifecycleEvent(String eventType) { | |
| 367 return _isIsolateExitEvent(eventType) || | |
| 368 _isIsolateStartEvent(eventType); | |
| 369 } | |
| 370 | |
| 371 bool _isIsolateExitEvent(String eventType) { | |
| 372 return (eventType == ServiceEvent.kIsolateExit); | |
| 373 } | |
| 374 | |
| 375 bool _isIsolateStartEvent(String eventType) { | |
| 376 return (eventType == ServiceEvent.kIsolateStart); | |
| 377 } | |
| 378 | |
| 379 void postServiceEvent(String response, ByteData data) { | 368 void postServiceEvent(String response, ByteData data) { |
| 380 var map; | 369 var map; |
| 381 try { | 370 try { |
| 382 map = _parseJSON(response); | 371 map = _parseJSON(response); |
| 383 assert(!map.containsKey('_data')); | 372 assert(!map.containsKey('_data')); |
| 384 if (data != null) { | 373 if (data != null) { |
| 385 map['_data'] = data; | 374 map['_data'] = data; |
| 386 } | 375 } |
| 387 } catch (e, st) { | 376 } catch (e, st) { |
| 388 Logger.root.severe('Ignoring malformed event response: ${response}'); | 377 Logger.root.severe('Ignoring malformed event response: ${response}'); |
| 389 return; | 378 return; |
| 390 } | 379 } |
| 391 if (map['type'] != 'ServiceEvent') { | 380 if (map['type'] != 'ServiceEvent') { |
| 392 Logger.root.severe( | 381 Logger.root.severe( |
| 393 "Expected 'ServiceEvent' but found '${map['type']}'"); | 382 "Expected 'ServiceEvent' but found '${map['type']}'"); |
| 394 return; | 383 return; |
| 395 } | 384 } |
| 396 | 385 |
| 397 var eventType = map['eventType']; | 386 var eventIsolate = map['isolate']; |
| 398 | 387 if (eventIsolate == null) { |
| 399 if (_isIsolateLifecycleEvent(eventType)) { | 388 var event = new ServiceObject._fromMap(vm, map); |
| 400 String isolateId = map['isolate']['id']; | 389 events.add(event); |
| 401 var event; | 390 } else { |
| 402 if (_isIsolateStartEvent(eventType)) { | 391 // getFromMap creates the Isolate if it hasn't been seen already. |
| 403 _onIsolateStart(map['isolate']); | 392 var isolate = getFromMap(map['isolate']); |
| 404 // By constructing the event *after* adding the isolate to the | 393 var event = new ServiceObject._fromMap(isolate, map); |
| 405 // isolate cache, the call to getFromMap will use the cached Isolate. | 394 if (event.eventType == ServiceEvent.kIsolateExit) { |
| 406 event = new ServiceObject._fromMap(this, map); | 395 _removeIsolate(isolate.id); |
| 407 } else { | |
| 408 assert(_isIsolateExitEvent(eventType)); | |
| 409 // By constructing the event *before* removing the isolate from the | |
| 410 // isolate cache, the call to getFromMap will use the cached Isolate. | |
| 411 event = new ServiceObject._fromMap(this, map); | |
| 412 _onIsolateExit(isolateId); | |
| 413 } | 396 } |
| 414 assert(event != null); | 397 isolate._onEvent(event); |
| 415 events.add(event); | 398 events.add(event); |
| 416 return; | |
| 417 } | 399 } |
| 418 | |
| 419 // Extract the owning isolate from the event itself. | |
| 420 String owningIsolateId = map['isolate']['id']; | |
| 421 getIsolate(owningIsolateId).then((owningIsolate) { | |
| 422 if (owningIsolate == null) { | |
| 423 // TODO(koda): Do we care about GC events in VM isolate? | |
| 424 Logger.root.severe('Ignoring event with unknown isolate id: ' | |
| 425 '$owningIsolateId'); | |
| 426 return; | |
| 427 } | |
| 428 var event = new ServiceObject._fromMap(owningIsolate, map); | |
| 429 owningIsolate._onEvent(event); | |
| 430 events.add(event); | |
| 431 }); | |
| 432 } | 400 } |
| 433 | 401 |
| 434 Isolate _onIsolateStart(Map isolateMap) { | 402 void _removeIsolate(String isolateId) { |
| 435 var isolateId = isolateMap['id']; | |
| 436 assert(!_isolateCache.containsKey(isolateId)); | |
| 437 Isolate isolate = new ServiceObject._fromMap(this, isolateMap); | |
| 438 _isolateCache[isolateId] = isolate; | |
| 439 notifyPropertyChange(#isolates, true, false); | |
| 440 // Eagerly load the isolate. | |
| 441 isolate.load().catchError((e) { | |
| 442 Logger.root.info('Eagerly loading an isolate failed: $e'); | |
| 443 }); | |
| 444 return isolate; | |
| 445 } | |
| 446 | |
| 447 void _onIsolateExit(String isolateId) { | |
| 448 assert(_isolateCache.containsKey(isolateId)); | 403 assert(_isolateCache.containsKey(isolateId)); |
| 449 _isolateCache.remove(isolateId); | 404 _isolateCache.remove(isolateId); |
| 450 notifyPropertyChange(#isolates, true, false); | 405 notifyPropertyChange(#isolates, true, false); |
| 451 } | 406 } |
| 452 | 407 |
| 453 void _updateIsolatesFromList(List isolateList) { | 408 void _updateIsolates(List newIsolates) { |
| 454 var shutdownIsolates = <String>[]; | 409 // Build a set of new isolates. |
| 455 var createdIsolates = <Map>[]; | 410 var newIsolateSet = new Set(); |
| 456 var isolateStillExists = <String, bool>{}; | 411 newIsolates.forEach((iso) => newIsolateSet.add(iso.id)); |
| 457 | 412 |
| 458 // Start with the assumption that all isolates are gone. | 413 // Remove any old isolates which no longer exist. |
| 459 for (var isolateId in _isolateCache.keys) { | 414 List toRemove = []; |
| 460 isolateStillExists[isolateId] = false; | 415 _isolateCache.forEach((id, _) { |
| 461 } | 416 if (!newIsolateSet.contains(id)) { |
| 462 | 417 toRemove.add(id); |
| 463 // Find created isolates and mark existing isolates as living. | |
| 464 for (var isolateMap in isolateList) { | |
| 465 var isolateId = isolateMap['id']; | |
| 466 if (!_isolateCache.containsKey(isolateId)) { | |
| 467 createdIsolates.add(isolateMap); | |
| 468 } else { | |
| 469 isolateStillExists[isolateId] = true; | |
| 470 } | |
| 471 } | |
| 472 | |
| 473 // Find shutdown isolates. | |
| 474 isolateStillExists.forEach((isolateId, exists) { | |
| 475 if (!exists) { | |
| 476 shutdownIsolates.add(isolateId); | |
| 477 } | 418 } |
| 478 }); | 419 }); |
| 479 | 420 toRemove.forEach((id) => _removeIsolate(id)); |
| 480 // Process shutdown. | 421 notifyPropertyChange(#isolates, true, false); |
| 481 for (var isolateId in shutdownIsolates) { | |
| 482 _onIsolateExit(isolateId); | |
| 483 } | |
| 484 | |
| 485 // Process creation. | |
| 486 for (var isolateMap in createdIsolates) { | |
| 487 _onIsolateStart(isolateMap); | |
| 488 } | |
| 489 } | 422 } |
| 490 | 423 |
| 491 static final String _isolateIdPrefix = 'isolates/'; | 424 static final String _isolateIdPrefix = 'isolates/'; |
| 492 | 425 |
| 493 ServiceObject getFromMap(ObservableMap map) { | 426 ServiceObject getFromMap(ObservableMap map) { |
| 494 if (map == null) { | 427 if (map == null) { |
| 495 return null; | 428 return null; |
| 496 } | 429 } |
| 497 String id = map['id']; | 430 String id = map['id']; |
| 498 if (!id.startsWith(_isolateIdPrefix)) { | 431 if (!id.startsWith(_isolateIdPrefix)) { |
| 499 // Currently the VM only supports upgrading Isolate ServiceObjects. | 432 // Currently the VM only supports upgrading Isolate ServiceObjects. |
| 500 throw new UnimplementedError(); | 433 throw new UnimplementedError(); |
| 501 } | 434 } |
| 502 | 435 |
| 503 // Check cache. | 436 // Check cache. |
| 504 var isolate = _isolateCache[id]; | 437 var isolate = _isolateCache[id]; |
| 505 if (isolate == null) { | 438 if (isolate == null) { |
| 506 // We should never see an unknown isolate here. | 439 // Add new isolate to the cache. |
| 507 throw new UnimplementedError(); | 440 isolate = new ServiceObject._fromMap(this, map); |
| 508 } | 441 _isolateCache[id] = isolate; |
| 509 var mapIsRef = _hasRef(map['type']); | 442 notifyPropertyChange(#isolates, true, false); |
| 510 if (!mapIsRef) { | 443 |
| 444 // Eagerly load the isolate. | |
| 445 isolate.load().catchError((e, stack) { | |
| 446 Logger.root.info('Eagerly loading an isolate failed: $e\n$stack'); | |
| 447 }); | |
| 448 } else { | |
| 511 isolate.update(map); | 449 isolate.update(map); |
| 512 } | 450 } |
| 513 return isolate; | 451 return isolate; |
| 514 } | 452 } |
| 515 | 453 |
| 516 // Note that this function does not reload the isolate if it found | 454 // Note that this function does not reload the isolate if it found |
| 517 // in the cache. | 455 // in the cache. |
| 518 Future<ServiceObject> getIsolate(String isolateId) { | 456 Future<ServiceObject> getIsolate(String isolateId) { |
| 519 if (!loaded) { | 457 if (!loaded) { |
| 520 // Trigger a VM load, then get the isolate. | 458 // Trigger a VM load, then get the isolate. |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 613 void disconnect(); | 551 void disconnect(); |
| 614 /// Completes when the VM first connects. | 552 /// Completes when the VM first connects. |
| 615 Future get onConnect; | 553 Future get onConnect; |
| 616 /// Completes when the VM disconnects or there was an error connecting. | 554 /// Completes when the VM disconnects or there was an error connecting. |
| 617 Future get onDisconnect; | 555 Future get onDisconnect; |
| 618 | 556 |
| 619 void _update(ObservableMap map, bool mapIsRef) { | 557 void _update(ObservableMap map, bool mapIsRef) { |
| 620 if (mapIsRef) { | 558 if (mapIsRef) { |
| 621 return; | 559 return; |
| 622 } | 560 } |
| 561 // Note that upgrading the collection creates any isolates in the | |
| 562 // isolate list which are new. | |
| 563 _upgradeCollection(map, vm); | |
| 564 | |
| 623 _loaded = true; | 565 _loaded = true; |
| 624 version = map['version']; | 566 version = map['version']; |
| 625 targetCPU = map['targetCPU']; | 567 targetCPU = map['targetCPU']; |
| 626 architectureBits = map['architectureBits']; | 568 architectureBits = map['architectureBits']; |
| 627 uptime = map['uptime']; | 569 var startTimeMillis = map['startTime']; |
| 628 var dateInMillis = int.parse(map['date']); | 570 startTime = new DateTime.fromMillisecondsSinceEpoch(startTimeMillis); |
| 629 lastUpdate = new DateTime.fromMillisecondsSinceEpoch(dateInMillis); | 571 var refreshTimeMillis = map['refreshTime']; |
| 572 refreshTime = new DateTime.fromMillisecondsSinceEpoch(refreshTimeMillis); | |
| 573 notifyPropertyChange(#upTime, 0, 1); | |
| 630 assertsEnabled = map['assertsEnabled']; | 574 assertsEnabled = map['assertsEnabled']; |
| 631 pid = map['pid']; | 575 pid = map['pid']; |
| 632 typeChecksEnabled = map['typeChecksEnabled']; | 576 typeChecksEnabled = map['typeChecksEnabled']; |
| 633 _updateIsolatesFromList(map['isolates']); | 577 _updateIsolates(map['isolates']); |
|
Cutch
2015/03/18 20:05:48
s/_updateIsolates/_removeDeadIsolates
turnidge
2015/03/26 17:46:58
Done.
| |
| 634 } | 578 } |
| 635 | 579 |
| 636 // Reload all isolates. | 580 // Reload all isolates. |
| 637 Future reloadIsolates() { | 581 Future reloadIsolates() { |
| 638 var reloads = []; | 582 var reloads = []; |
| 639 for (var isolate in isolates) { | 583 for (var isolate in isolates) { |
| 640 var reload = isolate.reload().catchError((e) { | 584 var reload = isolate.reload().catchError((e) { |
| 641 Logger.root.info('Bulk reloading of isolates failed: $e'); | 585 Logger.root.info('Bulk reloading of isolates failed: $e'); |
| 642 }); | 586 }); |
| 643 reloads.add(reload); | 587 reloads.add(reload); |
| (...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 769 return result; | 713 return result; |
| 770 } | 714 } |
| 771 | 715 |
| 772 | 716 |
| 773 } | 717 } |
| 774 | 718 |
| 775 /// State for a running isolate. | 719 /// State for a running isolate. |
| 776 class Isolate extends ServiceObjectOwner with Coverage { | 720 class Isolate extends ServiceObjectOwner with Coverage { |
| 777 @reflectable VM get vm => owner; | 721 @reflectable VM get vm => owner; |
| 778 @reflectable Isolate get isolate => this; | 722 @reflectable Isolate get isolate => this; |
| 723 @observable int number; | |
| 724 @observable DateTime startTime; | |
| 725 @observable Duration get upTime => | |
| 726 (new DateTime.now().difference(startTime)); | |
| 727 | |
| 779 @observable ObservableMap counters = new ObservableMap(); | 728 @observable ObservableMap counters = new ObservableMap(); |
| 780 | 729 |
| 781 @observable ServiceEvent pauseEvent = null; | |
| 782 | |
| 783 void _updateRunState() { | 730 void _updateRunState() { |
| 784 topFrame = (pauseEvent != null ? pauseEvent.topFrame : null); | 731 topFrame = (pauseEvent != null ? pauseEvent.topFrame : null); |
| 785 paused = (pauseEvent != null && | 732 paused = (pauseEvent != null && |
| 786 pauseEvent.eventType != ServiceEvent.kResume); | 733 pauseEvent.eventType != ServiceEvent.kResume); |
| 787 running = (!paused && topFrame != null); | 734 running = (!paused && topFrame != null); |
| 788 idle = (!paused && topFrame == null); | 735 idle = (!paused && topFrame == null); |
| 789 notifyPropertyChange(#topFrame, 0, 1); | 736 notifyPropertyChange(#topFrame, 0, 1); |
| 790 notifyPropertyChange(#paused, 0, 1); | 737 notifyPropertyChange(#paused, 0, 1); |
| 791 notifyPropertyChange(#running, 0, 1); | 738 notifyPropertyChange(#running, 0, 1); |
| 792 notifyPropertyChange(#idle, 0, 1); | 739 notifyPropertyChange(#idle, 0, 1); |
| 793 } | 740 } |
| 794 | 741 |
| 742 @observable ServiceEvent pauseEvent = null; | |
| 795 @observable bool paused = false; | 743 @observable bool paused = false; |
| 796 @observable bool running = false; | 744 @observable bool running = false; |
| 797 @observable bool idle = false; | 745 @observable bool idle = false; |
| 798 @observable bool loading = true; | 746 @observable bool loading = true; |
| 799 | 747 |
| 800 @observable bool ioEnabled = false; | 748 @observable bool ioEnabled = false; |
| 801 | 749 |
| 802 Map<String,ServiceObject> _cache = new Map<String,ServiceObject>(); | 750 Map<String,ServiceObject> _cache = new Map<String,ServiceObject>(); |
| 803 final TagProfile tagProfile = new TagProfile(20); | 751 final TagProfile tagProfile = new TagProfile(20); |
| 804 | 752 |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 852 } | 800 } |
| 853 } | 801 } |
| 854 assert(objectClass != null); | 802 assert(objectClass != null); |
| 855 return new Future.value(objectClass); | 803 return new Future.value(objectClass); |
| 856 } | 804 } |
| 857 | 805 |
| 858 ServiceObject getFromMap(ObservableMap map) { | 806 ServiceObject getFromMap(ObservableMap map) { |
| 859 if (map == null) { | 807 if (map == null) { |
| 860 return null; | 808 return null; |
| 861 } | 809 } |
| 810 var mapType = _stripRef(map['type']); | |
| 811 if (mapType == 'Isolate') { | |
| 812 // There are sometimes isolate refs in ServiceEvents. | |
| 813 return vm.getFromMap(map); | |
| 814 } | |
| 862 String mapId = map['id']; | 815 String mapId = map['id']; |
| 863 var obj = (mapId != null) ? _cache[mapId] : null; | 816 var obj = (mapId != null) ? _cache[mapId] : null; |
| 864 if (obj != null) { | 817 if (obj != null) { |
| 865 var mapIsRef = _hasRef(map['type']); | 818 obj.update(map); |
| 866 if (!mapIsRef) { | |
| 867 obj.update(map); | |
| 868 } | |
| 869 return obj; | 819 return obj; |
| 870 } | 820 } |
| 871 // Build the object from the map directly. | 821 // Build the object from the map directly. |
| 872 obj = new ServiceObject._fromMap(this, map); | 822 obj = new ServiceObject._fromMap(this, map); |
| 873 if ((obj != null) && obj.canCache) { | 823 if ((obj != null) && obj.canCache) { |
| 874 _cache[mapId] = obj; | 824 _cache[mapId] = obj; |
| 875 } | 825 } |
| 876 return obj; | 826 return obj; |
| 877 } | 827 } |
| 878 | 828 |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 945 | 895 |
| 946 void updateHeapsFromMap(ObservableMap map) { | 896 void updateHeapsFromMap(ObservableMap map) { |
| 947 newSpace.update(map['new']); | 897 newSpace.update(map['new']); |
| 948 oldSpace.update(map['old']); | 898 oldSpace.update(map['old']); |
| 949 } | 899 } |
| 950 | 900 |
| 951 void _update(ObservableMap map, bool mapIsRef) { | 901 void _update(ObservableMap map, bool mapIsRef) { |
| 952 mainPort = map['mainPort']; | 902 mainPort = map['mainPort']; |
| 953 name = map['name']; | 903 name = map['name']; |
| 954 vmName = map['name']; | 904 vmName = map['name']; |
| 905 number = int.parse(map['number'], onError:(_) => null); | |
| 955 if (mapIsRef) { | 906 if (mapIsRef) { |
| 956 return; | 907 return; |
| 957 } | 908 } |
| 958 _loaded = true; | 909 _loaded = true; |
| 959 loading = false; | 910 loading = false; |
| 960 | 911 |
| 961 _upgradeCollection(map, isolate); | 912 _upgradeCollection(map, isolate); |
| 962 if (map['rootLib'] == null || | 913 if (map['rootLib'] == null || |
| 963 map['timers'] == null || | 914 map['timers'] == null || |
| 964 map['heaps'] == null) { | 915 map['heaps'] == null) { |
| 965 Logger.root.severe("Malformed 'Isolate' response: $map"); | 916 Logger.root.severe("Malformed 'Isolate' response: $map"); |
| 966 return; | 917 return; |
| 967 } | 918 } |
| 968 rootLib = map['rootLib']; | 919 rootLib = map['rootLib']; |
| 969 if (map['entry'] != null) { | 920 if (map['entry'] != null) { |
| 970 entry = map['entry']; | 921 entry = map['entry']; |
| 971 } | 922 } |
| 972 | 923 var startTimeInMillis = map['startTime']; |
| 924 startTime = new DateTime.fromMillisecondsSinceEpoch(startTimeInMillis); | |
| 925 notifyPropertyChange(#upTime, 0, 1); | |
| 973 var countersMap = map['tagCounters']; | 926 var countersMap = map['tagCounters']; |
| 974 if (countersMap != null) { | 927 if (countersMap != null) { |
| 975 var names = countersMap['names']; | 928 var names = countersMap['names']; |
| 976 var counts = countersMap['counters']; | 929 var counts = countersMap['counters']; |
| 977 assert(names.length == counts.length); | 930 assert(names.length == counts.length); |
| 978 var sum = 0; | 931 var sum = 0; |
| 979 for (var i = 0; i < counts.length; i++) { | 932 for (var i = 0; i < counts.length; i++) { |
| 980 sum += counts[i]; | 933 sum += counts[i]; |
| 981 } | 934 } |
| 982 // TODO: Why does this not work without this? | 935 // TODO: Why does this not work without this? |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1030 (ObservableMap map) { | 983 (ObservableMap map) { |
| 1031 var seconds = new DateTime.now().millisecondsSinceEpoch / 1000.0; | 984 var seconds = new DateTime.now().millisecondsSinceEpoch / 1000.0; |
| 1032 tagProfile._processTagProfile(seconds, map); | 985 tagProfile._processTagProfile(seconds, map); |
| 1033 return tagProfile; | 986 return tagProfile; |
| 1034 }); | 987 }); |
| 1035 } | 988 } |
| 1036 | 989 |
| 1037 ObservableMap<int, Breakpoint> breakpoints = new ObservableMap(); | 990 ObservableMap<int, Breakpoint> breakpoints = new ObservableMap(); |
| 1038 | 991 |
| 1039 void _updateBreakpoints(List newBpts) { | 992 void _updateBreakpoints(List newBpts) { |
| 1040 // Build a map of new breakpoints. | 993 // Build a set of new breakpoints. |
| 1041 var newBptMap = {}; | 994 var newBptSet = new Set(); |
| 1042 newBpts.forEach((bpt) => (newBptMap[bpt.number] = bpt)); | 995 newBpts.forEach((bpt) => newBptSet.add(bpt.number)); |
| 1043 | 996 |
| 1044 // Remove any old breakpoints which no longer exist. | 997 // Remove any old breakpoints which no longer exist. |
| 1045 List toRemove = []; | 998 List toRemove = []; |
| 1046 breakpoints.forEach((key, _) { | 999 breakpoints.forEach((key, _) { |
| 1047 if (!newBptMap.containsKey(key)) { | 1000 if (!newBptSet.contains(key)) { |
| 1048 toRemove.add(key); | 1001 toRemove.add(key); |
| 1049 } | 1002 } |
| 1050 }); | 1003 }); |
| 1051 toRemove.forEach((key) => breakpoints.remove(key)); | 1004 toRemove.forEach((key) => breakpoints.remove(key)); |
| 1052 | 1005 |
| 1053 // Add all new breakpoints. | 1006 // Add all new breakpoints. |
| 1054 breakpoints.addAll(newBptMap); | 1007 newBpts.forEach((bpt) => (breakpoints[bpt.number] = bpt)); |
| 1055 } | 1008 } |
| 1056 | 1009 |
| 1057 void _addBreakpoint(Breakpoint bpt) { | 1010 void _addBreakpoint(Breakpoint bpt) { |
| 1058 breakpoints[bpt.number] = bpt; | 1011 breakpoints[bpt.number] = bpt; |
| 1059 } | 1012 } |
| 1060 | 1013 |
| 1061 void _removeBreakpoint(Breakpoint bpt) { | 1014 void _removeBreakpoint(Breakpoint bpt) { |
| 1062 breakpoints.remove(bpt.number); | 1015 breakpoints.remove(bpt.number); |
| 1063 bpt.remove(); | 1016 bpt.remove(); |
| 1064 } | 1017 } |
| 1065 | 1018 |
| 1066 void _onEvent(ServiceEvent event) { | 1019 void _onEvent(ServiceEvent event) { |
| 1067 assert(event.eventType != ServiceEvent.kIsolateStart && | |
| 1068 event.eventType != ServiceEvent.kIsolateExit); | |
| 1069 switch(event.eventType) { | 1020 switch(event.eventType) { |
| 1021 case ServiceEvent.kIsolateStart: | |
| 1022 case ServiceEvent.kIsolateExit: | |
| 1023 // Handled elsewhere. | |
| 1024 break; | |
| 1025 | |
| 1070 case ServiceEvent.kBreakpointAdded: | 1026 case ServiceEvent.kBreakpointAdded: |
| 1071 _addBreakpoint(event.breakpoint); | 1027 _addBreakpoint(event.breakpoint); |
| 1072 break; | 1028 break; |
| 1073 | 1029 |
| 1030 case ServiceEvent.kIsolateUpdate: | |
| 1074 case ServiceEvent.kBreakpointResolved: | 1031 case ServiceEvent.kBreakpointResolved: |
| 1075 // Update occurs as side-effect of caching. | 1032 // Update occurs as side-effect of caching. |
| 1076 break; | 1033 break; |
| 1077 | 1034 |
| 1078 case ServiceEvent.kBreakpointRemoved: | 1035 case ServiceEvent.kBreakpointRemoved: |
| 1079 _removeBreakpoint(event.breakpoint); | 1036 _removeBreakpoint(event.breakpoint); |
| 1080 break; | 1037 break; |
| 1081 | 1038 |
| 1082 case ServiceEvent.kPauseStart: | 1039 case ServiceEvent.kPauseStart: |
| 1083 case ServiceEvent.kPauseExit: | 1040 case ServiceEvent.kPauseExit: |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1134 return invokeRpc('removeBreakpoint', | 1091 return invokeRpc('removeBreakpoint', |
| 1135 { 'breakpointId': bpt.id }); | 1092 { 'breakpointId': bpt.id }); |
| 1136 } | 1093 } |
| 1137 | 1094 |
| 1138 Future pause() { | 1095 Future pause() { |
| 1139 return invokeRpc('pause', {}).then((result) { | 1096 return invokeRpc('pause', {}).then((result) { |
| 1140 if (result is DartError) { | 1097 if (result is DartError) { |
| 1141 // TODO(turnidge): Handle this more gracefully. | 1098 // TODO(turnidge): Handle this more gracefully. |
| 1142 Logger.root.severe(result.message); | 1099 Logger.root.severe(result.message); |
| 1143 } | 1100 } |
| 1101 return result; | |
| 1144 }); | 1102 }); |
| 1145 } | 1103 } |
| 1146 | 1104 |
| 1147 Future resume() { | 1105 Future resume() { |
| 1148 return invokeRpc('resume', {}).then((result) { | 1106 return invokeRpc('resume', {}).then((result) { |
| 1149 if (result is DartError) { | 1107 if (result is DartError) { |
| 1150 // TODO(turnidge): Handle this more gracefully. | 1108 // TODO(turnidge): Handle this more gracefully. |
| 1151 Logger.root.severe(result.message); | 1109 Logger.root.severe(result.message); |
| 1152 } | 1110 } |
| 1111 return result; | |
| 1153 }); | 1112 }); |
| 1154 } | 1113 } |
| 1155 | 1114 |
| 1156 Future stepInto() { | 1115 Future stepInto() { |
| 1157 return invokeRpc('resume', {'step': 'into'}).then((result) { | 1116 return invokeRpc('resume', {'step': 'into'}).then((result) { |
| 1158 if (result is DartError) { | 1117 if (result is DartError) { |
| 1159 // TODO(turnidge): Handle this more gracefully. | 1118 // TODO(turnidge): Handle this more gracefully. |
| 1160 Logger.root.severe(result.message); | 1119 Logger.root.severe(result.message); |
| 1161 } | 1120 } |
| 1121 return result; | |
| 1162 }); | 1122 }); |
| 1163 } | 1123 } |
| 1164 | 1124 |
| 1165 Future stepOver() { | 1125 Future stepOver() { |
| 1166 return invokeRpc('resume', {'step': 'over'}).then((result) { | 1126 return invokeRpc('resume', {'step': 'over'}).then((result) { |
| 1167 if (result is DartError) { | 1127 if (result is DartError) { |
| 1168 // TODO(turnidge): Handle this more gracefully. | 1128 // TODO(turnidge): Handle this more gracefully. |
| 1169 Logger.root.severe(result.message); | 1129 Logger.root.severe(result.message); |
| 1170 } | 1130 } |
| 1131 return result; | |
| 1171 }); | 1132 }); |
| 1172 } | 1133 } |
| 1173 | 1134 |
| 1174 Future stepOut() { | 1135 Future stepOut() { |
| 1175 return invokeRpc('resume', {'step': 'out'}).then((result) { | 1136 return invokeRpc('resume', {'step': 'out'}).then((result) { |
| 1176 if (result is DartError) { | 1137 if (result is DartError) { |
| 1177 // TODO(turnidge): Handle this more gracefully. | 1138 // TODO(turnidge): Handle this more gracefully. |
| 1178 Logger.root.severe(result.message); | 1139 Logger.root.severe(result.message); |
| 1179 } | 1140 } |
| 1141 return result; | |
| 1180 }); | 1142 }); |
| 1181 } | 1143 } |
| 1182 | 1144 |
| 1145 Future setName(String newName) { | |
| 1146 Map params = { | |
| 1147 'name': newName, | |
| 1148 }; | |
| 1149 return invokeRpc('setName', params); | |
| 1150 } | |
| 1151 | |
| 1183 Future<ServiceMap> getStack() { | 1152 Future<ServiceMap> getStack() { |
| 1184 return invokeRpc('getStack', {}).then((result) { | 1153 return invokeRpc('getStack', {}).then((result) { |
| 1185 if (result is DartError) { | 1154 if (result is DartError) { |
| 1186 // TODO(turnidge): Handle this more gracefully. | 1155 // TODO(turnidge): Handle this more gracefully. |
| 1187 Logger.root.severe(result.message); | 1156 Logger.root.severe(result.message); |
| 1188 } | 1157 } |
| 1189 return result; | 1158 return result; |
| 1190 }); | 1159 }); |
| 1191 } | 1160 } |
| 1192 | 1161 |
| (...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1415 } | 1384 } |
| 1416 | 1385 |
| 1417 String toString() => 'ServiceException($message)'; | 1386 String toString() => 'ServiceException($message)'; |
| 1418 } | 1387 } |
| 1419 | 1388 |
| 1420 /// A [ServiceEvent] is an asynchronous event notification from the vm. | 1389 /// A [ServiceEvent] is an asynchronous event notification from the vm. |
| 1421 class ServiceEvent extends ServiceObject { | 1390 class ServiceEvent extends ServiceObject { |
| 1422 /// The possible 'eventType' values. | 1391 /// The possible 'eventType' values. |
| 1423 static const kIsolateStart = 'IsolateStart'; | 1392 static const kIsolateStart = 'IsolateStart'; |
| 1424 static const kIsolateExit = 'IsolateExit'; | 1393 static const kIsolateExit = 'IsolateExit'; |
| 1394 static const kIsolateUpdate = 'IsolateUpdate'; | |
| 1425 static const kPauseStart = 'PauseStart'; | 1395 static const kPauseStart = 'PauseStart'; |
| 1426 static const kPauseExit = 'PauseExit'; | 1396 static const kPauseExit = 'PauseExit'; |
| 1427 static const kPauseBreakpoint = 'PauseBreakpoint'; | 1397 static const kPauseBreakpoint = 'PauseBreakpoint'; |
| 1428 static const kPauseInterrupted = 'PauseInterrupted'; | 1398 static const kPauseInterrupted = 'PauseInterrupted'; |
| 1429 static const kPauseException = 'PauseException'; | 1399 static const kPauseException = 'PauseException'; |
| 1430 static const kResume = 'Resume'; | 1400 static const kResume = 'Resume'; |
| 1431 static const kBreakpointAdded = 'BreakpointAdded'; | 1401 static const kBreakpointAdded = 'BreakpointAdded'; |
| 1432 static const kBreakpointResolved = 'BreakpointResolved'; | 1402 static const kBreakpointResolved = 'BreakpointResolved'; |
| 1433 static const kBreakpointRemoved = 'BreakpointRemoved'; | 1403 static const kBreakpointRemoved = 'BreakpointRemoved'; |
| 1434 static const kGraph = '_Graph'; | 1404 static const kGraph = '_Graph'; |
| 1435 static const kGC = 'GC'; | 1405 static const kGC = 'GC'; |
| 1436 static const kVMDisconnected = 'VMDisconnected'; | 1406 static const kVMDisconnected = 'VMDisconnected'; |
| 1437 | 1407 |
| 1438 ServiceEvent._empty(ServiceObjectOwner owner) : super._empty(owner); | 1408 ServiceEvent._empty(ServiceObjectOwner owner) : super._empty(owner); |
| 1439 | 1409 |
| 1440 ServiceEvent.vmDisconencted() : super._empty(null) { | 1410 ServiceEvent.vmDisconencted() : super._empty(null) { |
| 1441 eventType = kVMDisconnected; | 1411 eventType = kVMDisconnected; |
| 1442 } | 1412 } |
| 1443 | 1413 |
| 1444 @observable String eventType; | 1414 @observable String eventType; |
| 1445 @observable Breakpoint breakpoint; | 1415 @observable Breakpoint breakpoint; |
| 1446 @observable ServiceMap topFrame; | 1416 @observable ServiceMap topFrame; |
| 1447 @observable ServiceMap exception; | 1417 @observable ServiceMap exception; |
| 1448 @observable ByteData data; | 1418 @observable ByteData data; |
| 1449 @observable int count; | 1419 @observable int count; |
| 1450 | 1420 |
| 1451 void _update(ObservableMap map, bool mapIsRef) { | 1421 void _update(ObservableMap map, bool mapIsRef) { |
| 1452 _loaded = true; | 1422 _loaded = true; |
| 1453 _upgradeCollection(map, owner); | 1423 _upgradeCollection(map, owner); |
| 1424 assert(map['isolate'] == null || owner == map['isolate']); | |
| 1454 eventType = map['eventType']; | 1425 eventType = map['eventType']; |
| 1455 name = 'ServiceEvent $eventType'; | 1426 name = 'ServiceEvent $eventType'; |
| 1456 vmName = name; | 1427 vmName = name; |
| 1457 if (map['breakpoint'] != null) { | 1428 if (map['breakpoint'] != null) { |
| 1458 breakpoint = map['breakpoint']; | 1429 breakpoint = map['breakpoint']; |
| 1459 } | 1430 } |
| 1460 if (map['topFrame'] != null) { | 1431 if (map['topFrame'] != null) { |
| 1461 topFrame = map['topFrame']; | 1432 topFrame = map['topFrame']; |
| 1462 } | 1433 } |
| 1463 if (map['exception'] != null) { | 1434 if (map['exception'] != null) { |
| (...skipping 393 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1857 case 'kIrregexpFunction': return kIrregexpFunction; | 1828 case 'kIrregexpFunction': return kIrregexpFunction; |
| 1858 case 'kStaticInitializer': return kStaticInitializer; | 1829 case 'kStaticInitializer': return kStaticInitializer; |
| 1859 case 'kMethodExtractor': return kMethodExtractor; | 1830 case 'kMethodExtractor': return kMethodExtractor; |
| 1860 case 'kNoSuchMethodDispatcher': return kNoSuchMethodDispatcher; | 1831 case 'kNoSuchMethodDispatcher': return kNoSuchMethodDispatcher; |
| 1861 case 'kInvokeFieldDispatcher': return kInvokeFieldDispatcher; | 1832 case 'kInvokeFieldDispatcher': return kInvokeFieldDispatcher; |
| 1862 case 'Collected': return kCollected; | 1833 case 'Collected': return kCollected; |
| 1863 case 'Native': return kNative; | 1834 case 'Native': return kNative; |
| 1864 case 'Stub': return kStub; | 1835 case 'Stub': return kStub; |
| 1865 case 'Tag': return kTag; | 1836 case 'Tag': return kTag; |
| 1866 } | 1837 } |
| 1867 print('did not understand $value'); | 1838 Logger.root.severe('Unrecognized function kind: $value'); |
| 1868 throw new FallThroughError(); | 1839 throw new FallThroughError(); |
| 1869 } | 1840 } |
| 1870 | 1841 |
| 1871 static FunctionKind kRegularFunction = new FunctionKind._internal('function'); | 1842 static FunctionKind kRegularFunction = new FunctionKind._internal('function'); |
| 1872 static FunctionKind kClosureFunction = new FunctionKind._internal('closure fun ction'); | 1843 static FunctionKind kClosureFunction = new FunctionKind._internal('closure fun ction'); |
| 1873 static FunctionKind kGetterFunction = new FunctionKind._internal('getter funct ion'); | 1844 static FunctionKind kGetterFunction = new FunctionKind._internal('getter funct ion'); |
| 1874 static FunctionKind kSetterFunction = new FunctionKind._internal('setter funct ion'); | 1845 static FunctionKind kSetterFunction = new FunctionKind._internal('setter funct ion'); |
| 1875 static FunctionKind kConstructor = new FunctionKind._internal('constructor'); | 1846 static FunctionKind kConstructor = new FunctionKind._internal('constructor'); |
| 1876 static FunctionKind kImplicitGetterFunction = new FunctionKind._internal('impl icit getter function'); | 1847 static FunctionKind kImplicitGetterFunction = new FunctionKind._internal('impl icit getter function'); |
| 1877 static FunctionKind kImplicitSetterFunction = new FunctionKind._internal('impl icit setter function'); | 1848 static FunctionKind kImplicitSetterFunction = new FunctionKind._internal('impl icit setter function'); |
| (...skipping 545 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2423 return Native; | 2394 return Native; |
| 2424 } else if (s == 'Dart') { | 2395 } else if (s == 'Dart') { |
| 2425 return Dart; | 2396 return Dart; |
| 2426 } else if (s == 'Collected') { | 2397 } else if (s == 'Collected') { |
| 2427 return Collected; | 2398 return Collected; |
| 2428 } else if (s == 'Tag') { | 2399 } else if (s == 'Tag') { |
| 2429 return Tag; | 2400 return Tag; |
| 2430 } else if (s == 'Stub') { | 2401 } else if (s == 'Stub') { |
| 2431 return Stub; | 2402 return Stub; |
| 2432 } | 2403 } |
| 2433 print('do not understand code kind $s'); | 2404 Logger.root.severe('Unrecognized code kind: $s'); |
| 2434 throw new FallThroughError(); | 2405 throw new FallThroughError(); |
| 2435 } | 2406 } |
| 2436 static const Collected = const CodeKind._internal('Collected'); | 2407 static const Collected = const CodeKind._internal('Collected'); |
| 2437 static const Dart = const CodeKind._internal('Dart'); | 2408 static const Dart = const CodeKind._internal('Dart'); |
| 2438 static const Native = const CodeKind._internal('Native'); | 2409 static const Native = const CodeKind._internal('Native'); |
| 2439 static const Stub = const CodeKind._internal('Stub'); | 2410 static const Stub = const CodeKind._internal('Stub'); |
| 2440 static const Tag = const CodeKind._internal('Tag'); | 2411 static const Tag = const CodeKind._internal('Tag'); |
| 2441 } | 2412 } |
| 2442 | 2413 |
| 2443 class CodeInlineInterval { | 2414 class CodeInlineInterval { |
| (...skipping 453 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2897 var v = list[i]; | 2868 var v = list[i]; |
| 2898 if ((v is ObservableMap) && _isServiceMap(v)) { | 2869 if ((v is ObservableMap) && _isServiceMap(v)) { |
| 2899 list[i] = owner.getFromMap(v); | 2870 list[i] = owner.getFromMap(v); |
| 2900 } else if (v is ObservableList) { | 2871 } else if (v is ObservableList) { |
| 2901 _upgradeObservableList(v, owner); | 2872 _upgradeObservableList(v, owner); |
| 2902 } else if (v is ObservableMap) { | 2873 } else if (v is ObservableMap) { |
| 2903 _upgradeObservableMap(v, owner); | 2874 _upgradeObservableMap(v, owner); |
| 2904 } | 2875 } |
| 2905 } | 2876 } |
| 2906 } | 2877 } |
| OLD | NEW |