Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(3)

Side by Side Diff: runtime/observatory/lib/src/service/object.dart

Issue 1007863003: Allow Observatory debugger to switch isolates. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 329 matching lines...) Expand 10 before | Expand all | Expand 10 after
340 // TODO(johnmccutchan): Ensure that isolates do not end up in _cache. 340 // TODO(johnmccutchan): Ensure that isolates do not end up in _cache.
341 Map<String,ServiceObject> _cache = new Map<String,ServiceObject>(); 341 Map<String,ServiceObject> _cache = new Map<String,ServiceObject>();
342 final ObservableMap<String,Isolate> _isolateCache = 342 final ObservableMap<String,Isolate> _isolateCache =
343 new ObservableMap<String,Isolate>(); 343 new ObservableMap<String,Isolate>();
344 344
345 @reflectable Iterable<Isolate> get isolates => _isolateCache.values; 345 @reflectable Iterable<Isolate> get isolates => _isolateCache.values;
346 346
347 @observable String version = 'unknown'; 347 @observable String version = 'unknown';
348 @observable String targetCPU; 348 @observable String targetCPU;
349 @observable int architectureBits; 349 @observable int architectureBits;
350 @observable double uptime = 0.0;
351 @observable bool assertsEnabled = false; 350 @observable bool assertsEnabled = false;
352 @observable bool typeChecksEnabled = false; 351 @observable bool typeChecksEnabled = false;
353 @observable String pid = ''; 352 @observable String pid = '';
354 @observable DateTime lastUpdate; 353 @observable DateTime startTime;
354 @observable DateTime refreshTime;
355 @observable Duration get upTime =>
356 (new DateTime.now().difference(startTime));
355 357
356 VM() : super._empty(null) { 358 VM() : super._empty(null) {
357 name = 'vm'; 359 name = 'vm';
358 vmName = 'vm'; 360 vmName = 'vm';
359 _cache['vm'] = this; 361 _cache['vm'] = this;
360 update(toObservable({'id':'vm', 'type':'@VM'})); 362 update(toObservable({'id':'vm', 'type':'@VM'}));
361 } 363 }
362 364
363 final StreamController<ServiceException> exceptions = 365 final StreamController<ServiceException> exceptions =
364 new StreamController.broadcast(); 366 new StreamController.broadcast();
365 final StreamController<ServiceError> errors = 367 final StreamController<ServiceError> errors =
366 new StreamController.broadcast(); 368 new StreamController.broadcast();
367 final StreamController<ServiceEvent> events = 369 final StreamController<ServiceEvent> events =
368 new StreamController.broadcast(); 370 new StreamController.broadcast();
369 371
370 bool _isIsolateLifecycleEvent(String eventType) {
371 return _isIsolateExitEvent(eventType) ||
372 _isIsolateStartEvent(eventType);
373 }
374
375 bool _isIsolateExitEvent(String eventType) {
376 return (eventType == ServiceEvent.kIsolateExit);
377 }
378
379 bool _isIsolateStartEvent(String eventType) {
380 return (eventType == ServiceEvent.kIsolateStart);
381 }
382
383 void postServiceEvent(String response, ByteData data) { 372 void postServiceEvent(String response, ByteData data) {
384 var map; 373 var map;
385 try { 374 try {
386 map = _parseJSON(response); 375 map = _parseJSON(response);
387 assert(!map.containsKey('_data')); 376 assert(!map.containsKey('_data'));
388 if (data != null) { 377 if (data != null) {
389 map['_data'] = data; 378 map['_data'] = data;
390 } 379 }
391 } catch (e, st) { 380 } catch (e, st) {
392 Logger.root.severe('Ignoring malformed event response: ${response}'); 381 Logger.root.severe('Ignoring malformed event response: ${response}');
393 return; 382 return;
394 } 383 }
395 if (map['type'] != 'ServiceEvent') { 384 if (map['type'] != 'ServiceEvent') {
396 Logger.root.severe( 385 Logger.root.severe(
397 "Expected 'ServiceEvent' but found '${map['type']}'"); 386 "Expected 'ServiceEvent' but found '${map['type']}'");
398 return; 387 return;
399 } 388 }
400 389
401 var eventType = map['eventType']; 390 var eventIsolate = map['isolate'];
402 391 if (eventIsolate == null) {
403 if (_isIsolateLifecycleEvent(eventType)) { 392 var event = new ServiceObject._fromMap(vm, map);
404 String isolateId = map['isolate']['id']; 393 events.add(event);
405 var event; 394 } else {
406 if (_isIsolateStartEvent(eventType)) { 395 // getFromMap creates the Isolate if it hasn't been seen already.
407 _onIsolateStart(map['isolate']); 396 var isolate = getFromMap(map['isolate']);
408 // By constructing the event *after* adding the isolate to the 397 var event = new ServiceObject._fromMap(isolate, map);
409 // isolate cache, the call to getFromMap will use the cached Isolate. 398 if (event.eventType == ServiceEvent.kIsolateExit) {
410 event = new ServiceObject._fromMap(this, map); 399 _removeIsolate(isolate.id);
411 } else {
412 assert(_isIsolateExitEvent(eventType));
413 // By constructing the event *before* removing the isolate from the
414 // isolate cache, the call to getFromMap will use the cached Isolate.
415 event = new ServiceObject._fromMap(this, map);
416 _onIsolateExit(isolateId);
417 } 400 }
418 assert(event != null); 401 isolate._onEvent(event);
419 events.add(event); 402 events.add(event);
420 return;
421 } 403 }
422
423 // Extract the owning isolate from the event itself.
424 String owningIsolateId = map['isolate']['id'];
425 getIsolate(owningIsolateId).then((owningIsolate) {
426 if (owningIsolate == null) {
427 // TODO(koda): Do we care about GC events in VM isolate?
428 Logger.root.severe('Ignoring event with unknown isolate id: '
429 '$owningIsolateId');
430 return;
431 }
432 var event = new ServiceObject._fromMap(owningIsolate, map);
433 owningIsolate._onEvent(event);
434 events.add(event);
435 });
436 } 404 }
437 405
438 Isolate _onIsolateStart(Map isolateMap) { 406 void _removeIsolate(String isolateId) {
439 var isolateId = isolateMap['id'];
440 assert(!_isolateCache.containsKey(isolateId));
441 Isolate isolate = new ServiceObject._fromMap(this, isolateMap);
442 _isolateCache[isolateId] = isolate;
443 notifyPropertyChange(#isolates, true, false);
444 // Eagerly load the isolate.
445 isolate.load().catchError((e) {
446 Logger.root.info('Eagerly loading an isolate failed: $e');
447 });
448 return isolate;
449 }
450
451 void _onIsolateExit(String isolateId) {
452 assert(_isolateCache.containsKey(isolateId)); 407 assert(_isolateCache.containsKey(isolateId));
453 _isolateCache.remove(isolateId); 408 _isolateCache.remove(isolateId);
454 notifyPropertyChange(#isolates, true, false); 409 notifyPropertyChange(#isolates, true, false);
455 } 410 }
456 411
457 void _updateIsolatesFromList(List isolateList) { 412 void _removeDeadIsolates(List newIsolates) {
458 var shutdownIsolates = <String>[]; 413 // Build a set of new isolates.
459 var createdIsolates = <Map>[]; 414 var newIsolateSet = new Set();
460 var isolateStillExists = <String, bool>{}; 415 newIsolates.forEach((iso) => newIsolateSet.add(iso.id));
461 416
462 // Start with the assumption that all isolates are gone. 417 // Remove any old isolates which no longer exist.
463 for (var isolateId in _isolateCache.keys) { 418 List toRemove = [];
464 isolateStillExists[isolateId] = false; 419 _isolateCache.forEach((id, _) {
465 } 420 if (!newIsolateSet.contains(id)) {
466 421 toRemove.add(id);
467 // Find created isolates and mark existing isolates as living.
468 for (var isolateMap in isolateList) {
469 var isolateId = isolateMap['id'];
470 if (!_isolateCache.containsKey(isolateId)) {
471 createdIsolates.add(isolateMap);
472 } else {
473 isolateStillExists[isolateId] = true;
474 }
475 }
476
477 // Find shutdown isolates.
478 isolateStillExists.forEach((isolateId, exists) {
479 if (!exists) {
480 shutdownIsolates.add(isolateId);
481 } 422 }
482 }); 423 });
483 424 toRemove.forEach((id) => _removeIsolate(id));
484 // Process shutdown. 425 notifyPropertyChange(#isolates, true, false);
485 for (var isolateId in shutdownIsolates) {
486 _onIsolateExit(isolateId);
487 }
488
489 // Process creation.
490 for (var isolateMap in createdIsolates) {
491 _onIsolateStart(isolateMap);
492 }
493 } 426 }
494 427
495 static final String _isolateIdPrefix = 'isolates/'; 428 static final String _isolateIdPrefix = 'isolates/';
496 429
497 ServiceObject getFromMap(ObservableMap map) { 430 ServiceObject getFromMap(ObservableMap map) {
498 if (map == null) { 431 if (map == null) {
499 return null; 432 return null;
500 } 433 }
501 String id = map['id']; 434 String id = map['id'];
502 if (!id.startsWith(_isolateIdPrefix)) { 435 if (!id.startsWith(_isolateIdPrefix)) {
503 // Currently the VM only supports upgrading Isolate ServiceObjects. 436 // Currently the VM only supports upgrading Isolate ServiceObjects.
504 throw new UnimplementedError(); 437 throw new UnimplementedError();
505 } 438 }
506 439
507 // Check cache. 440 // Check cache.
508 var isolate = _isolateCache[id]; 441 var isolate = _isolateCache[id];
509 if (isolate == null) { 442 if (isolate == null) {
510 // We should never see an unknown isolate here. 443 // Add new isolate to the cache.
511 throw new UnimplementedError(); 444 isolate = new ServiceObject._fromMap(this, map);
512 } 445 _isolateCache[id] = isolate;
513 var mapIsRef = _hasRef(map['type']); 446 notifyPropertyChange(#isolates, true, false);
514 if (!mapIsRef) { 447
448 // Eagerly load the isolate.
449 isolate.load().catchError((e, stack) {
450 Logger.root.info('Eagerly loading an isolate failed: $e\n$stack');
451 });
452 } else {
515 isolate.update(map); 453 isolate.update(map);
516 } 454 }
517 return isolate; 455 return isolate;
518 } 456 }
519 457
520 // Note that this function does not reload the isolate if it found 458 // Note that this function does not reload the isolate if it found
521 // in the cache. 459 // in the cache.
522 Future<ServiceObject> getIsolate(String isolateId) { 460 Future<ServiceObject> getIsolate(String isolateId) {
523 if (!loaded) { 461 if (!loaded) {
524 // Trigger a VM load, then get the isolate. 462 // Trigger a VM load, then get the isolate.
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
617 void disconnect(); 555 void disconnect();
618 /// Completes when the VM first connects. 556 /// Completes when the VM first connects.
619 Future get onConnect; 557 Future get onConnect;
620 /// Completes when the VM disconnects or there was an error connecting. 558 /// Completes when the VM disconnects or there was an error connecting.
621 Future get onDisconnect; 559 Future get onDisconnect;
622 560
623 void _update(ObservableMap map, bool mapIsRef) { 561 void _update(ObservableMap map, bool mapIsRef) {
624 if (mapIsRef) { 562 if (mapIsRef) {
625 return; 563 return;
626 } 564 }
565 // Note that upgrading the collection creates any isolates in the
566 // isolate list which are new.
567 _upgradeCollection(map, vm);
568
627 _loaded = true; 569 _loaded = true;
628 version = map['version']; 570 version = map['version'];
629 targetCPU = map['targetCPU']; 571 targetCPU = map['targetCPU'];
630 architectureBits = map['architectureBits']; 572 architectureBits = map['architectureBits'];
631 uptime = map['uptime']; 573 var startTimeMillis = map['startTime'];
632 var dateInMillis = int.parse(map['date']); 574 startTime = new DateTime.fromMillisecondsSinceEpoch(startTimeMillis);
633 lastUpdate = new DateTime.fromMillisecondsSinceEpoch(dateInMillis); 575 var refreshTimeMillis = map['refreshTime'];
576 refreshTime = new DateTime.fromMillisecondsSinceEpoch(refreshTimeMillis);
577 notifyPropertyChange(#upTime, 0, 1);
634 assertsEnabled = map['assertsEnabled']; 578 assertsEnabled = map['assertsEnabled'];
635 pid = map['pid']; 579 pid = map['pid'];
636 typeChecksEnabled = map['typeChecksEnabled']; 580 typeChecksEnabled = map['typeChecksEnabled'];
637 _updateIsolatesFromList(map['isolates']); 581 _removeDeadIsolates(map['isolates']);
638 } 582 }
639 583
640 // Reload all isolates. 584 // Reload all isolates.
641 Future reloadIsolates() { 585 Future reloadIsolates() {
642 var reloads = []; 586 var reloads = [];
643 for (var isolate in isolates) { 587 for (var isolate in isolates) {
644 var reload = isolate.reload().catchError((e) { 588 var reload = isolate.reload().catchError((e) {
645 Logger.root.info('Bulk reloading of isolates failed: $e'); 589 Logger.root.info('Bulk reloading of isolates failed: $e');
646 }); 590 });
647 reloads.add(reload); 591 reloads.add(reload);
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
773 return result; 717 return result;
774 } 718 }
775 719
776 720
777 } 721 }
778 722
779 /// State for a running isolate. 723 /// State for a running isolate.
780 class Isolate extends ServiceObjectOwner with Coverage { 724 class Isolate extends ServiceObjectOwner with Coverage {
781 @reflectable VM get vm => owner; 725 @reflectable VM get vm => owner;
782 @reflectable Isolate get isolate => this; 726 @reflectable Isolate get isolate => this;
727 @observable int number;
728 @observable DateTime startTime;
729 @observable Duration get upTime =>
730 (new DateTime.now().difference(startTime));
731
783 @observable ObservableMap counters = new ObservableMap(); 732 @observable ObservableMap counters = new ObservableMap();
784 733
785 @observable ServiceEvent pauseEvent = null;
786
787 void _updateRunState() { 734 void _updateRunState() {
788 topFrame = (pauseEvent != null ? pauseEvent.topFrame : null); 735 topFrame = (pauseEvent != null ? pauseEvent.topFrame : null);
789 paused = (pauseEvent != null && 736 paused = (pauseEvent != null &&
790 pauseEvent.eventType != ServiceEvent.kResume); 737 pauseEvent.eventType != ServiceEvent.kResume);
791 running = (!paused && topFrame != null); 738 running = (!paused && topFrame != null);
792 idle = (!paused && topFrame == null); 739 idle = (!paused && topFrame == null);
793 notifyPropertyChange(#topFrame, 0, 1); 740 notifyPropertyChange(#topFrame, 0, 1);
794 notifyPropertyChange(#paused, 0, 1); 741 notifyPropertyChange(#paused, 0, 1);
795 notifyPropertyChange(#running, 0, 1); 742 notifyPropertyChange(#running, 0, 1);
796 notifyPropertyChange(#idle, 0, 1); 743 notifyPropertyChange(#idle, 0, 1);
797 } 744 }
798 745
746 @observable ServiceEvent pauseEvent = null;
799 @observable bool paused = false; 747 @observable bool paused = false;
800 @observable bool running = false; 748 @observable bool running = false;
801 @observable bool idle = false; 749 @observable bool idle = false;
802 @observable bool loading = true; 750 @observable bool loading = true;
803 751
804 @observable bool ioEnabled = false; 752 @observable bool ioEnabled = false;
805 753
806 Map<String,ServiceObject> _cache = new Map<String,ServiceObject>(); 754 Map<String,ServiceObject> _cache = new Map<String,ServiceObject>();
807 final TagProfile tagProfile = new TagProfile(20); 755 final TagProfile tagProfile = new TagProfile(20);
808 756
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
856 } 804 }
857 } 805 }
858 assert(objectClass != null); 806 assert(objectClass != null);
859 return new Future.value(objectClass); 807 return new Future.value(objectClass);
860 } 808 }
861 809
862 ServiceObject getFromMap(ObservableMap map) { 810 ServiceObject getFromMap(ObservableMap map) {
863 if (map == null) { 811 if (map == null) {
864 return null; 812 return null;
865 } 813 }
814 var mapType = _stripRef(map['type']);
815 if (mapType == 'Isolate') {
816 // There are sometimes isolate refs in ServiceEvents.
817 return vm.getFromMap(map);
818 }
866 String mapId = map['id']; 819 String mapId = map['id'];
867 var obj = (mapId != null) ? _cache[mapId] : null; 820 var obj = (mapId != null) ? _cache[mapId] : null;
868 if (obj != null) { 821 if (obj != null) {
869 var mapIsRef = _hasRef(map['type']); 822 obj.update(map);
870 if (!mapIsRef) {
871 obj.update(map);
872 }
873 return obj; 823 return obj;
874 } 824 }
875 // Build the object from the map directly. 825 // Build the object from the map directly.
876 obj = new ServiceObject._fromMap(this, map); 826 obj = new ServiceObject._fromMap(this, map);
877 if ((obj != null) && obj.canCache) { 827 if ((obj != null) && obj.canCache) {
878 _cache[mapId] = obj; 828 _cache[mapId] = obj;
879 } 829 }
880 return obj; 830 return obj;
881 } 831 }
882 832
(...skipping 27 matching lines...) Expand all
910 @observable Class objectClass; 860 @observable Class objectClass;
911 @observable final rootClasses = new ObservableList<Class>(); 861 @observable final rootClasses = new ObservableList<Class>();
912 862
913 @observable Library rootLib; 863 @observable Library rootLib;
914 @observable ObservableList<Library> libraries = 864 @observable ObservableList<Library> libraries =
915 new ObservableList<Library>(); 865 new ObservableList<Library>();
916 @observable ObservableMap topFrame; 866 @observable ObservableMap topFrame;
917 867
918 @observable String name; 868 @observable String name;
919 @observable String vmName; 869 @observable String vmName;
920 @observable String mainPort;
921 @observable ServiceFunction entry; 870 @observable ServiceFunction entry;
922 871
923 @observable final Map<String, double> timers = 872 @observable final Map<String, double> timers =
924 toObservable(new Map<String, double>()); 873 toObservable(new Map<String, double>());
925 874
926 final HeapSpace newSpace = new HeapSpace(); 875 final HeapSpace newSpace = new HeapSpace();
927 final HeapSpace oldSpace = new HeapSpace(); 876 final HeapSpace oldSpace = new HeapSpace();
928 877
929 @observable String fileAndLine; 878 @observable String fileAndLine;
930 879
(...skipping 15 matching lines...) Expand all
946 } 895 }
947 return _snapshotFetch.future; 896 return _snapshotFetch.future;
948 } 897 }
949 898
950 void updateHeapsFromMap(ObservableMap map) { 899 void updateHeapsFromMap(ObservableMap map) {
951 newSpace.update(map['new']); 900 newSpace.update(map['new']);
952 oldSpace.update(map['old']); 901 oldSpace.update(map['old']);
953 } 902 }
954 903
955 void _update(ObservableMap map, bool mapIsRef) { 904 void _update(ObservableMap map, bool mapIsRef) {
956 mainPort = map['mainPort'];
957 name = map['name']; 905 name = map['name'];
958 vmName = map['name']; 906 vmName = map['name'];
907 number = int.parse(map['number'], onError:(_) => null);
959 if (mapIsRef) { 908 if (mapIsRef) {
960 return; 909 return;
961 } 910 }
962 _loaded = true; 911 _loaded = true;
963 loading = false; 912 loading = false;
964 913
965 _upgradeCollection(map, isolate); 914 _upgradeCollection(map, isolate);
966 if (map['rootLib'] == null || 915 if (map['rootLib'] == null ||
967 map['timers'] == null || 916 map['timers'] == null ||
968 map['heaps'] == null) { 917 map['heaps'] == null) {
969 Logger.root.severe("Malformed 'Isolate' response: $map"); 918 Logger.root.severe("Malformed 'Isolate' response: $map");
970 return; 919 return;
971 } 920 }
972 rootLib = map['rootLib']; 921 rootLib = map['rootLib'];
973 if (map['entry'] != null) { 922 if (map['entry'] != null) {
974 entry = map['entry']; 923 entry = map['entry'];
975 } 924 }
976 925 var startTimeInMillis = map['startTime'];
926 startTime = new DateTime.fromMillisecondsSinceEpoch(startTimeInMillis);
927 notifyPropertyChange(#upTime, 0, 1);
977 var countersMap = map['tagCounters']; 928 var countersMap = map['tagCounters'];
978 if (countersMap != null) { 929 if (countersMap != null) {
979 var names = countersMap['names']; 930 var names = countersMap['names'];
980 var counts = countersMap['counters']; 931 var counts = countersMap['counters'];
981 assert(names.length == counts.length); 932 assert(names.length == counts.length);
982 var sum = 0; 933 var sum = 0;
983 for (var i = 0; i < counts.length; i++) { 934 for (var i = 0; i < counts.length; i++) {
984 sum += counts[i]; 935 sum += counts[i];
985 } 936 }
986 // TODO: Why does this not work without this? 937 // TODO: Why does this not work without this?
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
1034 (ObservableMap map) { 985 (ObservableMap map) {
1035 var seconds = new DateTime.now().millisecondsSinceEpoch / 1000.0; 986 var seconds = new DateTime.now().millisecondsSinceEpoch / 1000.0;
1036 tagProfile._processTagProfile(seconds, map); 987 tagProfile._processTagProfile(seconds, map);
1037 return tagProfile; 988 return tagProfile;
1038 }); 989 });
1039 } 990 }
1040 991
1041 ObservableMap<int, Breakpoint> breakpoints = new ObservableMap(); 992 ObservableMap<int, Breakpoint> breakpoints = new ObservableMap();
1042 993
1043 void _updateBreakpoints(List newBpts) { 994 void _updateBreakpoints(List newBpts) {
1044 // Build a map of new breakpoints. 995 // Build a set of new breakpoints.
1045 var newBptMap = {}; 996 var newBptSet = new Set();
1046 newBpts.forEach((bpt) => (newBptMap[bpt.number] = bpt)); 997 newBpts.forEach((bpt) => newBptSet.add(bpt.number));
1047 998
1048 // Remove any old breakpoints which no longer exist. 999 // Remove any old breakpoints which no longer exist.
1049 List toRemove = []; 1000 List toRemove = [];
1050 breakpoints.forEach((key, _) { 1001 breakpoints.forEach((key, _) {
1051 if (!newBptMap.containsKey(key)) { 1002 if (!newBptSet.contains(key)) {
1052 toRemove.add(key); 1003 toRemove.add(key);
1053 } 1004 }
1054 }); 1005 });
1055 toRemove.forEach((key) => breakpoints.remove(key)); 1006 toRemove.forEach((key) => breakpoints.remove(key));
1056 1007
1057 // Add all new breakpoints. 1008 // Add all new breakpoints.
1058 breakpoints.addAll(newBptMap); 1009 newBpts.forEach((bpt) => (breakpoints[bpt.number] = bpt));
1059 } 1010 }
1060 1011
1061 void _addBreakpoint(Breakpoint bpt) { 1012 void _addBreakpoint(Breakpoint bpt) {
1062 breakpoints[bpt.number] = bpt; 1013 breakpoints[bpt.number] = bpt;
1063 } 1014 }
1064 1015
1065 void _removeBreakpoint(Breakpoint bpt) { 1016 void _removeBreakpoint(Breakpoint bpt) {
1066 breakpoints.remove(bpt.number); 1017 breakpoints.remove(bpt.number);
1067 bpt.remove(); 1018 bpt.remove();
1068 } 1019 }
1069 1020
1070 void _onEvent(ServiceEvent event) { 1021 void _onEvent(ServiceEvent event) {
1071 assert(event.eventType != ServiceEvent.kIsolateStart &&
1072 event.eventType != ServiceEvent.kIsolateExit);
1073 switch(event.eventType) { 1022 switch(event.eventType) {
1023 case ServiceEvent.kIsolateStart:
1024 case ServiceEvent.kIsolateExit:
1025 // Handled elsewhere.
1026 break;
1027
1074 case ServiceEvent.kBreakpointAdded: 1028 case ServiceEvent.kBreakpointAdded:
1075 _addBreakpoint(event.breakpoint); 1029 _addBreakpoint(event.breakpoint);
1076 break; 1030 break;
1077 1031
1032 case ServiceEvent.kIsolateUpdate:
1078 case ServiceEvent.kBreakpointResolved: 1033 case ServiceEvent.kBreakpointResolved:
1079 // Update occurs as side-effect of caching. 1034 // Update occurs as side-effect of caching.
1080 break; 1035 break;
1081 1036
1082 case ServiceEvent.kBreakpointRemoved: 1037 case ServiceEvent.kBreakpointRemoved:
1083 _removeBreakpoint(event.breakpoint); 1038 _removeBreakpoint(event.breakpoint);
1084 break; 1039 break;
1085 1040
1086 case ServiceEvent.kPauseStart: 1041 case ServiceEvent.kPauseStart:
1087 case ServiceEvent.kPauseExit: 1042 case ServiceEvent.kPauseExit:
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
1138 return invokeRpc('removeBreakpoint', 1093 return invokeRpc('removeBreakpoint',
1139 { 'breakpointId': bpt.id }); 1094 { 'breakpointId': bpt.id });
1140 } 1095 }
1141 1096
1142 Future pause() { 1097 Future pause() {
1143 return invokeRpc('pause', {}).then((result) { 1098 return invokeRpc('pause', {}).then((result) {
1144 if (result is DartError) { 1099 if (result is DartError) {
1145 // TODO(turnidge): Handle this more gracefully. 1100 // TODO(turnidge): Handle this more gracefully.
1146 Logger.root.severe(result.message); 1101 Logger.root.severe(result.message);
1147 } 1102 }
1103 return result;
1148 }); 1104 });
1149 } 1105 }
1150 1106
1151 Future resume() { 1107 Future resume() {
1152 return invokeRpc('resume', {}).then((result) { 1108 return invokeRpc('resume', {}).then((result) {
1153 if (result is DartError) { 1109 if (result is DartError) {
1154 // TODO(turnidge): Handle this more gracefully. 1110 // TODO(turnidge): Handle this more gracefully.
1155 Logger.root.severe(result.message); 1111 Logger.root.severe(result.message);
1156 } 1112 }
1113 return result;
1157 }); 1114 });
1158 } 1115 }
1159 1116
1160 Future stepInto() { 1117 Future stepInto() {
1161 return invokeRpc('resume', {'step': 'into'}).then((result) { 1118 return invokeRpc('resume', {'step': 'into'}).then((result) {
1162 if (result is DartError) { 1119 if (result is DartError) {
1163 // TODO(turnidge): Handle this more gracefully. 1120 // TODO(turnidge): Handle this more gracefully.
1164 Logger.root.severe(result.message); 1121 Logger.root.severe(result.message);
1165 } 1122 }
1123 return result;
1166 }); 1124 });
1167 } 1125 }
1168 1126
1169 Future stepOver() { 1127 Future stepOver() {
1170 return invokeRpc('resume', {'step': 'over'}).then((result) { 1128 return invokeRpc('resume', {'step': 'over'}).then((result) {
1171 if (result is DartError) { 1129 if (result is DartError) {
1172 // TODO(turnidge): Handle this more gracefully. 1130 // TODO(turnidge): Handle this more gracefully.
1173 Logger.root.severe(result.message); 1131 Logger.root.severe(result.message);
1174 } 1132 }
1133 return result;
1175 }); 1134 });
1176 } 1135 }
1177 1136
1178 Future stepOut() { 1137 Future stepOut() {
1179 return invokeRpc('resume', {'step': 'out'}).then((result) { 1138 return invokeRpc('resume', {'step': 'out'}).then((result) {
1180 if (result is DartError) { 1139 if (result is DartError) {
1181 // TODO(turnidge): Handle this more gracefully. 1140 // TODO(turnidge): Handle this more gracefully.
1182 Logger.root.severe(result.message); 1141 Logger.root.severe(result.message);
1183 } 1142 }
1143 return result;
1184 }); 1144 });
1185 } 1145 }
1186 1146
1147 Future setName(String newName) {
1148 Map params = {
1149 'name': newName,
1150 };
1151 return invokeRpc('setName', params);
1152 }
1153
1187 Future<ServiceMap> getStack() { 1154 Future<ServiceMap> getStack() {
1188 return invokeRpc('getStack', {}).then((result) { 1155 return invokeRpc('getStack', {}).then((result) {
1189 if (result is DartError) { 1156 if (result is DartError) {
1190 // TODO(turnidge): Handle this more gracefully. 1157 // TODO(turnidge): Handle this more gracefully.
1191 Logger.root.severe(result.message); 1158 Logger.root.severe(result.message);
1192 } 1159 }
1193 return result; 1160 return result;
1194 }); 1161 });
1195 } 1162 }
1196 1163
(...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after
1419 } 1386 }
1420 1387
1421 String toString() => 'ServiceException($message)'; 1388 String toString() => 'ServiceException($message)';
1422 } 1389 }
1423 1390
1424 /// A [ServiceEvent] is an asynchronous event notification from the vm. 1391 /// A [ServiceEvent] is an asynchronous event notification from the vm.
1425 class ServiceEvent extends ServiceObject { 1392 class ServiceEvent extends ServiceObject {
1426 /// The possible 'eventType' values. 1393 /// The possible 'eventType' values.
1427 static const kIsolateStart = 'IsolateStart'; 1394 static const kIsolateStart = 'IsolateStart';
1428 static const kIsolateExit = 'IsolateExit'; 1395 static const kIsolateExit = 'IsolateExit';
1396 static const kIsolateUpdate = 'IsolateUpdate';
1429 static const kPauseStart = 'PauseStart'; 1397 static const kPauseStart = 'PauseStart';
1430 static const kPauseExit = 'PauseExit'; 1398 static const kPauseExit = 'PauseExit';
1431 static const kPauseBreakpoint = 'PauseBreakpoint'; 1399 static const kPauseBreakpoint = 'PauseBreakpoint';
1432 static const kPauseInterrupted = 'PauseInterrupted'; 1400 static const kPauseInterrupted = 'PauseInterrupted';
1433 static const kPauseException = 'PauseException'; 1401 static const kPauseException = 'PauseException';
1434 static const kResume = 'Resume'; 1402 static const kResume = 'Resume';
1435 static const kBreakpointAdded = 'BreakpointAdded'; 1403 static const kBreakpointAdded = 'BreakpointAdded';
1436 static const kBreakpointResolved = 'BreakpointResolved'; 1404 static const kBreakpointResolved = 'BreakpointResolved';
1437 static const kBreakpointRemoved = 'BreakpointRemoved'; 1405 static const kBreakpointRemoved = 'BreakpointRemoved';
1438 static const kGraph = '_Graph'; 1406 static const kGraph = '_Graph';
1439 static const kGC = 'GC'; 1407 static const kGC = 'GC';
1440 static const kVMDisconnected = 'VMDisconnected'; 1408 static const kVMDisconnected = 'VMDisconnected';
1441 1409
1442 ServiceEvent._empty(ServiceObjectOwner owner) : super._empty(owner); 1410 ServiceEvent._empty(ServiceObjectOwner owner) : super._empty(owner);
1443 1411
1444 ServiceEvent.vmDisconencted() : super._empty(null) { 1412 ServiceEvent.vmDisconencted() : super._empty(null) {
1445 eventType = kVMDisconnected; 1413 eventType = kVMDisconnected;
1446 } 1414 }
1447 1415
1448 @observable String eventType; 1416 @observable String eventType;
1449 @observable Breakpoint breakpoint; 1417 @observable Breakpoint breakpoint;
1450 @observable ServiceMap topFrame; 1418 @observable ServiceMap topFrame;
1451 @observable ServiceMap exception; 1419 @observable ServiceMap exception;
1452 @observable ByteData data; 1420 @observable ByteData data;
1453 @observable int count; 1421 @observable int count;
1454 1422
1455 void _update(ObservableMap map, bool mapIsRef) { 1423 void _update(ObservableMap map, bool mapIsRef) {
1456 _loaded = true; 1424 _loaded = true;
1457 _upgradeCollection(map, owner); 1425 _upgradeCollection(map, owner);
1426 assert(map['isolate'] == null || owner == map['isolate']);
1458 eventType = map['eventType']; 1427 eventType = map['eventType'];
1459 name = 'ServiceEvent $eventType'; 1428 name = 'ServiceEvent $eventType';
1460 vmName = name; 1429 vmName = name;
1461 if (map['breakpoint'] != null) { 1430 if (map['breakpoint'] != null) {
1462 breakpoint = map['breakpoint']; 1431 breakpoint = map['breakpoint'];
1463 } 1432 }
1464 if (map['topFrame'] != null) { 1433 if (map['topFrame'] != null) {
1465 topFrame = map['topFrame']; 1434 topFrame = map['topFrame'];
1466 } 1435 }
1467 if (map['exception'] != null) { 1436 if (map['exception'] != null) {
(...skipping 393 matching lines...) Expand 10 before | Expand all | Expand 10 after
1861 case 'kIrregexpFunction': return kIrregexpFunction; 1830 case 'kIrregexpFunction': return kIrregexpFunction;
1862 case 'kStaticInitializer': return kStaticInitializer; 1831 case 'kStaticInitializer': return kStaticInitializer;
1863 case 'kMethodExtractor': return kMethodExtractor; 1832 case 'kMethodExtractor': return kMethodExtractor;
1864 case 'kNoSuchMethodDispatcher': return kNoSuchMethodDispatcher; 1833 case 'kNoSuchMethodDispatcher': return kNoSuchMethodDispatcher;
1865 case 'kInvokeFieldDispatcher': return kInvokeFieldDispatcher; 1834 case 'kInvokeFieldDispatcher': return kInvokeFieldDispatcher;
1866 case 'Collected': return kCollected; 1835 case 'Collected': return kCollected;
1867 case 'Native': return kNative; 1836 case 'Native': return kNative;
1868 case 'Stub': return kStub; 1837 case 'Stub': return kStub;
1869 case 'Tag': return kTag; 1838 case 'Tag': return kTag;
1870 } 1839 }
1871 print('did not understand $value'); 1840 Logger.root.severe('Unrecognized function kind: $value');
1872 throw new FallThroughError(); 1841 throw new FallThroughError();
1873 } 1842 }
1874 1843
1875 static FunctionKind kRegularFunction = new FunctionKind._internal('function'); 1844 static FunctionKind kRegularFunction = new FunctionKind._internal('function');
1876 static FunctionKind kClosureFunction = new FunctionKind._internal('closure fun ction'); 1845 static FunctionKind kClosureFunction = new FunctionKind._internal('closure fun ction');
1877 static FunctionKind kGetterFunction = new FunctionKind._internal('getter funct ion'); 1846 static FunctionKind kGetterFunction = new FunctionKind._internal('getter funct ion');
1878 static FunctionKind kSetterFunction = new FunctionKind._internal('setter funct ion'); 1847 static FunctionKind kSetterFunction = new FunctionKind._internal('setter funct ion');
1879 static FunctionKind kConstructor = new FunctionKind._internal('constructor'); 1848 static FunctionKind kConstructor = new FunctionKind._internal('constructor');
1880 static FunctionKind kImplicitGetterFunction = new FunctionKind._internal('impl icit getter function'); 1849 static FunctionKind kImplicitGetterFunction = new FunctionKind._internal('impl icit getter function');
1881 static FunctionKind kImplicitSetterFunction = new FunctionKind._internal('impl icit setter function'); 1850 static FunctionKind kImplicitSetterFunction = new FunctionKind._internal('impl icit setter function');
(...skipping 605 matching lines...) Expand 10 before | Expand all | Expand 10 after
2487 return Native; 2456 return Native;
2488 } else if (s == 'Dart') { 2457 } else if (s == 'Dart') {
2489 return Dart; 2458 return Dart;
2490 } else if (s == 'Collected') { 2459 } else if (s == 'Collected') {
2491 return Collected; 2460 return Collected;
2492 } else if (s == 'Tag') { 2461 } else if (s == 'Tag') {
2493 return Tag; 2462 return Tag;
2494 } else if (s == 'Stub') { 2463 } else if (s == 'Stub') {
2495 return Stub; 2464 return Stub;
2496 } 2465 }
2497 print('do not understand code kind $s'); 2466 Logger.root.severe('Unrecognized code kind: $s');
2498 throw new FallThroughError(); 2467 throw new FallThroughError();
2499 } 2468 }
2500 static const Collected = const CodeKind._internal('Collected'); 2469 static const Collected = const CodeKind._internal('Collected');
2501 static const Dart = const CodeKind._internal('Dart'); 2470 static const Dart = const CodeKind._internal('Dart');
2502 static const Native = const CodeKind._internal('Native'); 2471 static const Native = const CodeKind._internal('Native');
2503 static const Stub = const CodeKind._internal('Stub'); 2472 static const Stub = const CodeKind._internal('Stub');
2504 static const Tag = const CodeKind._internal('Tag'); 2473 static const Tag = const CodeKind._internal('Tag');
2505 } 2474 }
2506 2475
2507 class CodeInlineInterval { 2476 class CodeInlineInterval {
(...skipping 453 matching lines...) Expand 10 before | Expand all | Expand 10 after
2961 var v = list[i]; 2930 var v = list[i];
2962 if ((v is ObservableMap) && _isServiceMap(v)) { 2931 if ((v is ObservableMap) && _isServiceMap(v)) {
2963 list[i] = owner.getFromMap(v); 2932 list[i] = owner.getFromMap(v);
2964 } else if (v is ObservableList) { 2933 } else if (v is ObservableList) {
2965 _upgradeObservableList(v, owner); 2934 _upgradeObservableList(v, owner);
2966 } else if (v is ObservableMap) { 2935 } else if (v is ObservableMap) {
2967 _upgradeObservableMap(v, owner); 2936 _upgradeObservableMap(v, owner);
2968 } 2937 }
2969 } 2938 }
2970 } 2939 }
OLDNEW
« no previous file with comments | « runtime/observatory/lib/src/elements/vm_view.html ('k') | runtime/observatory/test/isolate_lifecycle_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698