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

Unified 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 side-by-side diff with in-line comments
Download patch
Index: runtime/observatory/lib/src/service/object.dart
diff --git a/runtime/observatory/lib/src/service/object.dart b/runtime/observatory/lib/src/service/object.dart
index 4a006d2e11cfd2880bf4157df1aaff0eaee2dedd..4603ece0e3d010d5315be9e9c15c4f340122a114 100644
--- a/runtime/observatory/lib/src/service/object.dart
+++ b/runtime/observatory/lib/src/service/object.dart
@@ -347,11 +347,13 @@ abstract class VM extends ServiceObjectOwner {
@observable String version = 'unknown';
@observable String targetCPU;
@observable int architectureBits;
- @observable double uptime = 0.0;
@observable bool assertsEnabled = false;
@observable bool typeChecksEnabled = false;
@observable String pid = '';
- @observable DateTime lastUpdate;
+ @observable DateTime startTime;
+ @observable DateTime refreshTime;
+ @observable Duration get upTime =>
+ (new DateTime.now().difference(startTime));
VM() : super._empty(null) {
name = 'vm';
@@ -367,19 +369,6 @@ abstract class VM extends ServiceObjectOwner {
final StreamController<ServiceEvent> events =
new StreamController.broadcast();
- bool _isIsolateLifecycleEvent(String eventType) {
- return _isIsolateExitEvent(eventType) ||
- _isIsolateStartEvent(eventType);
- }
-
- bool _isIsolateExitEvent(String eventType) {
- return (eventType == ServiceEvent.kIsolateExit);
- }
-
- bool _isIsolateStartEvent(String eventType) {
- return (eventType == ServiceEvent.kIsolateStart);
- }
-
void postServiceEvent(String response, ByteData data) {
var map;
try {
@@ -398,98 +387,42 @@ abstract class VM extends ServiceObjectOwner {
return;
}
- var eventType = map['eventType'];
-
- if (_isIsolateLifecycleEvent(eventType)) {
- String isolateId = map['isolate']['id'];
- var event;
- if (_isIsolateStartEvent(eventType)) {
- _onIsolateStart(map['isolate']);
- // By constructing the event *after* adding the isolate to the
- // isolate cache, the call to getFromMap will use the cached Isolate.
- event = new ServiceObject._fromMap(this, map);
- } else {
- assert(_isIsolateExitEvent(eventType));
- // By constructing the event *before* removing the isolate from the
- // isolate cache, the call to getFromMap will use the cached Isolate.
- event = new ServiceObject._fromMap(this, map);
- _onIsolateExit(isolateId);
+ var eventIsolate = map['isolate'];
+ if (eventIsolate == null) {
+ var event = new ServiceObject._fromMap(vm, map);
+ events.add(event);
+ } else {
+ // getFromMap creates the Isolate if it hasn't been seen already.
+ var isolate = getFromMap(map['isolate']);
+ var event = new ServiceObject._fromMap(isolate, map);
+ if (event.eventType == ServiceEvent.kIsolateExit) {
+ _removeIsolate(isolate.id);
}
- assert(event != null);
+ isolate._onEvent(event);
events.add(event);
- return;
}
-
- // Extract the owning isolate from the event itself.
- String owningIsolateId = map['isolate']['id'];
- getIsolate(owningIsolateId).then((owningIsolate) {
- if (owningIsolate == null) {
- // TODO(koda): Do we care about GC events in VM isolate?
- Logger.root.severe('Ignoring event with unknown isolate id: '
- '$owningIsolateId');
- return;
- }
- var event = new ServiceObject._fromMap(owningIsolate, map);
- owningIsolate._onEvent(event);
- events.add(event);
- });
}
- Isolate _onIsolateStart(Map isolateMap) {
- var isolateId = isolateMap['id'];
- assert(!_isolateCache.containsKey(isolateId));
- Isolate isolate = new ServiceObject._fromMap(this, isolateMap);
- _isolateCache[isolateId] = isolate;
- notifyPropertyChange(#isolates, true, false);
- // Eagerly load the isolate.
- isolate.load().catchError((e) {
- Logger.root.info('Eagerly loading an isolate failed: $e');
- });
- return isolate;
- }
-
- void _onIsolateExit(String isolateId) {
+ void _removeIsolate(String isolateId) {
assert(_isolateCache.containsKey(isolateId));
_isolateCache.remove(isolateId);
notifyPropertyChange(#isolates, true, false);
}
- void _updateIsolatesFromList(List isolateList) {
- var shutdownIsolates = <String>[];
- var createdIsolates = <Map>[];
- var isolateStillExists = <String, bool>{};
-
- // Start with the assumption that all isolates are gone.
- for (var isolateId in _isolateCache.keys) {
- isolateStillExists[isolateId] = false;
- }
-
- // Find created isolates and mark existing isolates as living.
- for (var isolateMap in isolateList) {
- var isolateId = isolateMap['id'];
- if (!_isolateCache.containsKey(isolateId)) {
- createdIsolates.add(isolateMap);
- } else {
- isolateStillExists[isolateId] = true;
- }
- }
+ void _removeDeadIsolates(List newIsolates) {
+ // Build a set of new isolates.
+ var newIsolateSet = new Set();
+ newIsolates.forEach((iso) => newIsolateSet.add(iso.id));
- // Find shutdown isolates.
- isolateStillExists.forEach((isolateId, exists) {
- if (!exists) {
- shutdownIsolates.add(isolateId);
+ // Remove any old isolates which no longer exist.
+ List toRemove = [];
+ _isolateCache.forEach((id, _) {
+ if (!newIsolateSet.contains(id)) {
+ toRemove.add(id);
}
});
-
- // Process shutdown.
- for (var isolateId in shutdownIsolates) {
- _onIsolateExit(isolateId);
- }
-
- // Process creation.
- for (var isolateMap in createdIsolates) {
- _onIsolateStart(isolateMap);
- }
+ toRemove.forEach((id) => _removeIsolate(id));
+ notifyPropertyChange(#isolates, true, false);
}
static final String _isolateIdPrefix = 'isolates/';
@@ -507,11 +440,16 @@ abstract class VM extends ServiceObjectOwner {
// Check cache.
var isolate = _isolateCache[id];
if (isolate == null) {
- // We should never see an unknown isolate here.
- throw new UnimplementedError();
- }
- var mapIsRef = _hasRef(map['type']);
- if (!mapIsRef) {
+ // Add new isolate to the cache.
+ isolate = new ServiceObject._fromMap(this, map);
+ _isolateCache[id] = isolate;
+ notifyPropertyChange(#isolates, true, false);
+
+ // Eagerly load the isolate.
+ isolate.load().catchError((e, stack) {
+ Logger.root.info('Eagerly loading an isolate failed: $e\n$stack');
+ });
+ } else {
isolate.update(map);
}
return isolate;
@@ -624,17 +562,23 @@ abstract class VM extends ServiceObjectOwner {
if (mapIsRef) {
return;
}
+ // Note that upgrading the collection creates any isolates in the
+ // isolate list which are new.
+ _upgradeCollection(map, vm);
+
_loaded = true;
version = map['version'];
targetCPU = map['targetCPU'];
architectureBits = map['architectureBits'];
- uptime = map['uptime'];
- var dateInMillis = int.parse(map['date']);
- lastUpdate = new DateTime.fromMillisecondsSinceEpoch(dateInMillis);
+ var startTimeMillis = map['startTime'];
+ startTime = new DateTime.fromMillisecondsSinceEpoch(startTimeMillis);
+ var refreshTimeMillis = map['refreshTime'];
+ refreshTime = new DateTime.fromMillisecondsSinceEpoch(refreshTimeMillis);
+ notifyPropertyChange(#upTime, 0, 1);
assertsEnabled = map['assertsEnabled'];
pid = map['pid'];
typeChecksEnabled = map['typeChecksEnabled'];
- _updateIsolatesFromList(map['isolates']);
+ _removeDeadIsolates(map['isolates']);
}
// Reload all isolates.
@@ -780,9 +724,12 @@ class HeapSnapshot {
class Isolate extends ServiceObjectOwner with Coverage {
@reflectable VM get vm => owner;
@reflectable Isolate get isolate => this;
- @observable ObservableMap counters = new ObservableMap();
+ @observable int number;
+ @observable DateTime startTime;
+ @observable Duration get upTime =>
+ (new DateTime.now().difference(startTime));
- @observable ServiceEvent pauseEvent = null;
+ @observable ObservableMap counters = new ObservableMap();
void _updateRunState() {
topFrame = (pauseEvent != null ? pauseEvent.topFrame : null);
@@ -796,6 +743,7 @@ class Isolate extends ServiceObjectOwner with Coverage {
notifyPropertyChange(#idle, 0, 1);
}
+ @observable ServiceEvent pauseEvent = null;
@observable bool paused = false;
@observable bool running = false;
@observable bool idle = false;
@@ -863,13 +811,15 @@ class Isolate extends ServiceObjectOwner with Coverage {
if (map == null) {
return null;
}
+ var mapType = _stripRef(map['type']);
+ if (mapType == 'Isolate') {
+ // There are sometimes isolate refs in ServiceEvents.
+ return vm.getFromMap(map);
+ }
String mapId = map['id'];
var obj = (mapId != null) ? _cache[mapId] : null;
if (obj != null) {
- var mapIsRef = _hasRef(map['type']);
- if (!mapIsRef) {
- obj.update(map);
- }
+ obj.update(map);
return obj;
}
// Build the object from the map directly.
@@ -917,7 +867,6 @@ class Isolate extends ServiceObjectOwner with Coverage {
@observable String name;
@observable String vmName;
- @observable String mainPort;
@observable ServiceFunction entry;
@observable final Map<String, double> timers =
@@ -953,9 +902,9 @@ class Isolate extends ServiceObjectOwner with Coverage {
}
void _update(ObservableMap map, bool mapIsRef) {
- mainPort = map['mainPort'];
name = map['name'];
vmName = map['name'];
+ number = int.parse(map['number'], onError:(_) => null);
if (mapIsRef) {
return;
}
@@ -973,7 +922,9 @@ class Isolate extends ServiceObjectOwner with Coverage {
if (map['entry'] != null) {
entry = map['entry'];
}
-
+ var startTimeInMillis = map['startTime'];
+ startTime = new DateTime.fromMillisecondsSinceEpoch(startTimeInMillis);
+ notifyPropertyChange(#upTime, 0, 1);
var countersMap = map['tagCounters'];
if (countersMap != null) {
var names = countersMap['names'];
@@ -1041,21 +992,21 @@ class Isolate extends ServiceObjectOwner with Coverage {
ObservableMap<int, Breakpoint> breakpoints = new ObservableMap();
void _updateBreakpoints(List newBpts) {
- // Build a map of new breakpoints.
- var newBptMap = {};
- newBpts.forEach((bpt) => (newBptMap[bpt.number] = bpt));
+ // Build a set of new breakpoints.
+ var newBptSet = new Set();
+ newBpts.forEach((bpt) => newBptSet.add(bpt.number));
// Remove any old breakpoints which no longer exist.
List toRemove = [];
breakpoints.forEach((key, _) {
- if (!newBptMap.containsKey(key)) {
+ if (!newBptSet.contains(key)) {
toRemove.add(key);
}
});
toRemove.forEach((key) => breakpoints.remove(key));
// Add all new breakpoints.
- breakpoints.addAll(newBptMap);
+ newBpts.forEach((bpt) => (breakpoints[bpt.number] = bpt));
}
void _addBreakpoint(Breakpoint bpt) {
@@ -1068,13 +1019,17 @@ class Isolate extends ServiceObjectOwner with Coverage {
}
void _onEvent(ServiceEvent event) {
- assert(event.eventType != ServiceEvent.kIsolateStart &&
- event.eventType != ServiceEvent.kIsolateExit);
switch(event.eventType) {
+ case ServiceEvent.kIsolateStart:
+ case ServiceEvent.kIsolateExit:
+ // Handled elsewhere.
+ break;
+
case ServiceEvent.kBreakpointAdded:
_addBreakpoint(event.breakpoint);
break;
+ case ServiceEvent.kIsolateUpdate:
case ServiceEvent.kBreakpointResolved:
// Update occurs as side-effect of caching.
break;
@@ -1145,6 +1100,7 @@ class Isolate extends ServiceObjectOwner with Coverage {
// TODO(turnidge): Handle this more gracefully.
Logger.root.severe(result.message);
}
+ return result;
});
}
@@ -1154,6 +1110,7 @@ class Isolate extends ServiceObjectOwner with Coverage {
// TODO(turnidge): Handle this more gracefully.
Logger.root.severe(result.message);
}
+ return result;
});
}
@@ -1163,6 +1120,7 @@ class Isolate extends ServiceObjectOwner with Coverage {
// TODO(turnidge): Handle this more gracefully.
Logger.root.severe(result.message);
}
+ return result;
});
}
@@ -1172,6 +1130,7 @@ class Isolate extends ServiceObjectOwner with Coverage {
// TODO(turnidge): Handle this more gracefully.
Logger.root.severe(result.message);
}
+ return result;
});
}
@@ -1181,9 +1140,17 @@ class Isolate extends ServiceObjectOwner with Coverage {
// TODO(turnidge): Handle this more gracefully.
Logger.root.severe(result.message);
}
+ return result;
});
}
+ Future setName(String newName) {
+ Map params = {
+ 'name': newName,
+ };
+ return invokeRpc('setName', params);
+ }
+
Future<ServiceMap> getStack() {
return invokeRpc('getStack', {}).then((result) {
if (result is DartError) {
@@ -1426,6 +1393,7 @@ class ServiceEvent extends ServiceObject {
/// The possible 'eventType' values.
static const kIsolateStart = 'IsolateStart';
static const kIsolateExit = 'IsolateExit';
+ static const kIsolateUpdate = 'IsolateUpdate';
static const kPauseStart = 'PauseStart';
static const kPauseExit = 'PauseExit';
static const kPauseBreakpoint = 'PauseBreakpoint';
@@ -1455,6 +1423,7 @@ class ServiceEvent extends ServiceObject {
void _update(ObservableMap map, bool mapIsRef) {
_loaded = true;
_upgradeCollection(map, owner);
+ assert(map['isolate'] == null || owner == map['isolate']);
eventType = map['eventType'];
name = 'ServiceEvent $eventType';
vmName = name;
@@ -1868,7 +1837,7 @@ class FunctionKind {
case 'Stub': return kStub;
case 'Tag': return kTag;
}
- print('did not understand $value');
+ Logger.root.severe('Unrecognized function kind: $value');
throw new FallThroughError();
}
@@ -2494,7 +2463,7 @@ class CodeKind {
} else if (s == 'Stub') {
return Stub;
}
- print('do not understand code kind $s');
+ Logger.root.severe('Unrecognized code kind: $s');
throw new FallThroughError();
}
static const Collected = const CodeKind._internal('Collected');
« 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