| OLD | NEW |
| 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 part of service; | 5 part of service; |
| 6 | 6 |
| 7 /// Helper function for canceling a Future<StreamSubscription>. | 7 /// Helper function for canceling a Future<StreamSubscription>. |
| 8 Future cancelFutureSubscription( | 8 Future cancelFutureSubscription( |
| 9 Future<StreamSubscription> subscriptionFuture) async { | 9 Future<StreamSubscription> subscriptionFuture) async { |
| 10 if (subscriptionFuture != null) { | 10 if (subscriptionFuture != null) { |
| (...skipping 488 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 499 @reflectable Isolate get isolate => null; | 499 @reflectable Isolate get isolate => null; |
| 500 | 500 |
| 501 // TODO(turnidge): The connection should not be stored in the VM object. | 501 // TODO(turnidge): The connection should not be stored in the VM object. |
| 502 bool get isDisconnected; | 502 bool get isDisconnected; |
| 503 | 503 |
| 504 // TODO(johnmccutchan): Ensure that isolates do not end up in _cache. | 504 // TODO(johnmccutchan): Ensure that isolates do not end up in _cache. |
| 505 Map<String,ServiceObject> _cache = new Map<String,ServiceObject>(); | 505 Map<String,ServiceObject> _cache = new Map<String,ServiceObject>(); |
| 506 final ObservableMap<String,Isolate> _isolateCache = | 506 final ObservableMap<String,Isolate> _isolateCache = |
| 507 new ObservableMap<String,Isolate>(); | 507 new ObservableMap<String,Isolate>(); |
| 508 | 508 |
| 509 @reflectable Iterable<Isolate> get isolates => _isolateCache.values; | 509 // The list of live isolates, ordered by isolate start time. |
| 510 final ObservableList<Isolate> isolates = new ObservableList<Isolate>(); |
| 510 | 511 |
| 511 @observable String version = 'unknown'; | 512 @observable String version = 'unknown'; |
| 512 @observable String targetCPU; | 513 @observable String targetCPU; |
| 513 @observable int architectureBits; | 514 @observable int architectureBits; |
| 514 @observable bool assertsEnabled = false; | 515 @observable bool assertsEnabled = false; |
| 515 @observable bool typeChecksEnabled = false; | 516 @observable bool typeChecksEnabled = false; |
| 516 @observable String pid = ''; | 517 @observable String pid = ''; |
| 517 @observable DateTime startTime; | 518 @observable DateTime startTime; |
| 518 @observable DateTime refreshTime; | 519 @observable DateTime refreshTime; |
| 519 @observable Duration get upTime => | 520 @observable Duration get upTime => |
| (...skipping 20 matching lines...) Expand all Loading... |
| 540 | 541 |
| 541 var eventIsolate = map['isolate']; | 542 var eventIsolate = map['isolate']; |
| 542 var event; | 543 var event; |
| 543 if (eventIsolate == null) { | 544 if (eventIsolate == null) { |
| 544 event = new ServiceObject._fromMap(vm, map); | 545 event = new ServiceObject._fromMap(vm, map); |
| 545 } else { | 546 } else { |
| 546 // getFromMap creates the Isolate if it hasn't been seen already. | 547 // getFromMap creates the Isolate if it hasn't been seen already. |
| 547 var isolate = getFromMap(map['isolate']); | 548 var isolate = getFromMap(map['isolate']); |
| 548 event = new ServiceObject._fromMap(isolate, map); | 549 event = new ServiceObject._fromMap(isolate, map); |
| 549 if (event.kind == ServiceEvent.kIsolateExit) { | 550 if (event.kind == ServiceEvent.kIsolateExit) { |
| 550 _removeIsolate(isolate.id); | 551 _isolateCache.remove(isolate.id); |
| 552 _buildIsolateList(); |
| 551 } | 553 } |
| 552 } | 554 } |
| 553 var eventStream = _eventStreams[streamId]; | 555 var eventStream = _eventStreams[streamId]; |
| 554 if (eventStream != null) { | 556 if (eventStream != null) { |
| 555 eventStream.addEvent(event); | 557 eventStream.addEvent(event); |
| 556 } else { | 558 } else { |
| 557 Logger.root.warning("Ignoring unexpected event on stream '${streamId}'"); | 559 Logger.root.warning("Ignoring unexpected event on stream '${streamId}'"); |
| 558 } | 560 } |
| 559 } | 561 } |
| 560 | 562 |
| 561 void _removeIsolate(String isolateId) { | 563 int _compareIsolates(Isolate a, Isolate b) { |
| 562 assert(_isolateCache.containsKey(isolateId)); | 564 var aStart = a.startTime; |
| 563 _isolateCache.remove(isolateId); | 565 var bStart = b.startTime; |
| 564 notifyPropertyChange(#isolates, true, false); | 566 if (aStart == null) { |
| 567 if (bStart == null) { |
| 568 return 0; |
| 569 } else { |
| 570 return 1; |
| 571 } |
| 572 } |
| 573 if (bStart == null) { |
| 574 return -1; |
| 575 } |
| 576 return aStart.compareTo(bStart); |
| 577 } |
| 578 |
| 579 void _buildIsolateList() { |
| 580 var isolateList = _isolateCache.values.toList(); |
| 581 isolateList.sort(_compareIsolates); |
| 582 isolates.clear(); |
| 583 isolates.addAll(isolateList); |
| 565 } | 584 } |
| 566 | 585 |
| 567 void _removeDeadIsolates(List newIsolates) { | 586 void _removeDeadIsolates(List newIsolates) { |
| 568 // Build a set of new isolates. | 587 // Build a set of new isolates. |
| 569 var newIsolateSet = new Set(); | 588 var newIsolateSet = new Set(); |
| 570 newIsolates.forEach((iso) => newIsolateSet.add(iso.id)); | 589 newIsolates.forEach((iso) => newIsolateSet.add(iso.id)); |
| 571 | 590 |
| 572 // Remove any old isolates which no longer exist. | 591 // Remove any old isolates which no longer exist. |
| 573 List toRemove = []; | 592 List toRemove = []; |
| 574 _isolateCache.forEach((id, _) { | 593 _isolateCache.forEach((id, _) { |
| 575 if (!newIsolateSet.contains(id)) { | 594 if (!newIsolateSet.contains(id)) { |
| 576 toRemove.add(id); | 595 toRemove.add(id); |
| 577 } | 596 } |
| 578 }); | 597 }); |
| 579 toRemove.forEach((id) => _removeIsolate(id)); | 598 toRemove.forEach((id) => _isolateCache.remove(id)); |
| 580 notifyPropertyChange(#isolates, true, false); | 599 _buildIsolateList(); |
| 581 } | 600 } |
| 582 | 601 |
| 583 static final String _isolateIdPrefix = 'isolates/'; | 602 static final String _isolateIdPrefix = 'isolates/'; |
| 584 | 603 |
| 585 ServiceObject getFromMap(ObservableMap map) { | 604 ServiceObject getFromMap(ObservableMap map) { |
| 586 if (map == null) { | 605 if (map == null) { |
| 587 return null; | 606 return null; |
| 588 } | 607 } |
| 589 String id = map['id']; | 608 String id = map['id']; |
| 590 if (!id.startsWith(_isolateIdPrefix)) { | 609 if (!id.startsWith(_isolateIdPrefix)) { |
| 591 // Currently the VM only supports upgrading Isolate ServiceObjects. | 610 // Currently the VM only supports upgrading Isolate ServiceObjects. |
| 592 throw new UnimplementedError(); | 611 throw new UnimplementedError(); |
| 593 } | 612 } |
| 594 | 613 |
| 595 // Check cache. | 614 // Check cache. |
| 596 var isolate = _isolateCache[id]; | 615 var isolate = _isolateCache[id]; |
| 597 if (isolate == null) { | 616 if (isolate == null) { |
| 598 // Add new isolate to the cache. | 617 // Add new isolate to the cache. |
| 599 isolate = new ServiceObject._fromMap(this, map); | 618 isolate = new ServiceObject._fromMap(this, map); |
| 600 _isolateCache[id] = isolate; | 619 _isolateCache[id] = isolate; |
| 601 notifyPropertyChange(#isolates, true, false); | 620 _buildIsolateList(); |
| 602 | 621 |
| 603 // Eagerly load the isolate. | 622 // Eagerly load the isolate. |
| 604 isolate.load().catchError((e, stack) { | 623 isolate.load().catchError((e, stack) { |
| 605 Logger.root.info('Eagerly loading an isolate failed: $e\n$stack'); | 624 Logger.root.info('Eagerly loading an isolate failed: $e\n$stack'); |
| 606 }); | 625 }); |
| 607 } else { | 626 } else { |
| 608 isolate.update(map); | 627 isolate.update(map); |
| 609 } | 628 } |
| 610 return isolate; | 629 return isolate; |
| 611 } | 630 } |
| (...skipping 582 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1194 return; | 1213 return; |
| 1195 } | 1214 } |
| 1196 _loaded = true; | 1215 _loaded = true; |
| 1197 loading = false; | 1216 loading = false; |
| 1198 | 1217 |
| 1199 _upgradeCollection(map, isolate); | 1218 _upgradeCollection(map, isolate); |
| 1200 rootLibrary = map['rootLib']; | 1219 rootLibrary = map['rootLib']; |
| 1201 if (map['entry'] != null) { | 1220 if (map['entry'] != null) { |
| 1202 entry = map['entry']; | 1221 entry = map['entry']; |
| 1203 } | 1222 } |
| 1223 var savedStartTime = startTime; |
| 1204 var startTimeInMillis = map['startTime']; | 1224 var startTimeInMillis = map['startTime']; |
| 1205 startTime = new DateTime.fromMillisecondsSinceEpoch(startTimeInMillis); | 1225 startTime = new DateTime.fromMillisecondsSinceEpoch(startTimeInMillis); |
| 1206 notifyPropertyChange(#upTime, 0, 1); | 1226 notifyPropertyChange(#upTime, 0, 1); |
| 1207 var countersMap = map['_tagCounters']; | 1227 var countersMap = map['_tagCounters']; |
| 1208 if (countersMap != null) { | 1228 if (countersMap != null) { |
| 1209 var names = countersMap['names']; | 1229 var names = countersMap['names']; |
| 1210 var counts = countersMap['counters']; | 1230 var counts = countersMap['counters']; |
| 1211 assert(names.length == counts.length); | 1231 assert(names.length == counts.length); |
| 1212 var sum = 0; | 1232 var sum = 0; |
| 1213 for (var i = 0; i < counts.length; i++) { | 1233 for (var i = 0; i < counts.length; i++) { |
| (...skipping 29 matching lines...) Expand all Loading... |
| 1243 _updateBreakpoints(map['breakpoints']); | 1263 _updateBreakpoints(map['breakpoints']); |
| 1244 exceptionsPauseInfo = map['_debuggerSettings']['_exceptions']; | 1264 exceptionsPauseInfo = map['_debuggerSettings']['_exceptions']; |
| 1245 | 1265 |
| 1246 pauseEvent = map['pauseEvent']; | 1266 pauseEvent = map['pauseEvent']; |
| 1247 _updateRunState(); | 1267 _updateRunState(); |
| 1248 error = map['error']; | 1268 error = map['error']; |
| 1249 | 1269 |
| 1250 libraries.clear(); | 1270 libraries.clear(); |
| 1251 libraries.addAll(map['libraries']); | 1271 libraries.addAll(map['libraries']); |
| 1252 libraries.sort(ServiceObject.LexicalSortName); | 1272 libraries.sort(ServiceObject.LexicalSortName); |
| 1273 if (savedStartTime == null) { |
| 1274 vm._buildIsolateList(); |
| 1275 } |
| 1253 } | 1276 } |
| 1254 | 1277 |
| 1255 Future<TagProfile> updateTagProfile() { | 1278 Future<TagProfile> updateTagProfile() { |
| 1256 return isolate.invokeRpcNoUpgrade('_getTagProfile', {}).then( | 1279 return isolate.invokeRpcNoUpgrade('_getTagProfile', {}).then( |
| 1257 (ObservableMap map) { | 1280 (ObservableMap map) { |
| 1258 var seconds = new DateTime.now().millisecondsSinceEpoch / 1000.0; | 1281 var seconds = new DateTime.now().millisecondsSinceEpoch / 1000.0; |
| 1259 tagProfile._processTagProfile(seconds, map); | 1282 tagProfile._processTagProfile(seconds, map); |
| 1260 return tagProfile; | 1283 return tagProfile; |
| 1261 }); | 1284 }); |
| 1262 } | 1285 } |
| (...skipping 298 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1561 } | 1584 } |
| 1562 | 1585 |
| 1563 Future<ObservableMap<String, ServiceMetric>> refreshNativeMetrics() { | 1586 Future<ObservableMap<String, ServiceMetric>> refreshNativeMetrics() { |
| 1564 return _refreshMetrics('Native', nativeMetrics); | 1587 return _refreshMetrics('Native', nativeMetrics); |
| 1565 } | 1588 } |
| 1566 | 1589 |
| 1567 Future refreshMetrics() { | 1590 Future refreshMetrics() { |
| 1568 return Future.wait([refreshDartMetrics(), refreshNativeMetrics()]); | 1591 return Future.wait([refreshDartMetrics(), refreshNativeMetrics()]); |
| 1569 } | 1592 } |
| 1570 | 1593 |
| 1571 String toString() => "Isolate($_id)"; | 1594 String toString() => "Isolate($name)"; |
| 1572 } | 1595 } |
| 1573 | 1596 |
| 1574 /// A [ServiceObject] which implements [ObservableMap]. | 1597 /// A [ServiceObject] which implements [ObservableMap]. |
| 1575 class ServiceMap extends ServiceObject implements ObservableMap { | 1598 class ServiceMap extends ServiceObject implements ObservableMap { |
| 1576 final ObservableMap _map = new ObservableMap(); | 1599 final ObservableMap _map = new ObservableMap(); |
| 1577 static String objectIdRingPrefix = 'objects/'; | 1600 static String objectIdRingPrefix = 'objects/'; |
| 1578 | 1601 |
| 1579 bool get canCache { | 1602 bool get canCache { |
| 1580 return (_type == 'Class' || | 1603 return (_type == 'Class' || |
| 1581 _type == 'Function' || | 1604 _type == 'Function' || |
| (...skipping 2080 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3662 var v = list[i]; | 3685 var v = list[i]; |
| 3663 if ((v is ObservableMap) && _isServiceMap(v)) { | 3686 if ((v is ObservableMap) && _isServiceMap(v)) { |
| 3664 list[i] = owner.getFromMap(v); | 3687 list[i] = owner.getFromMap(v); |
| 3665 } else if (v is ObservableList) { | 3688 } else if (v is ObservableList) { |
| 3666 _upgradeObservableList(v, owner); | 3689 _upgradeObservableList(v, owner); |
| 3667 } else if (v is ObservableMap) { | 3690 } else if (v is ObservableMap) { |
| 3668 _upgradeObservableMap(v, owner); | 3691 _upgradeObservableMap(v, owner); |
| 3669 } | 3692 } |
| 3670 } | 3693 } |
| 3671 } | 3694 } |
| OLD | NEW |