Chromium Code Reviews| Index: runtime/bin/vmservice/client/lib/src/observatory/isolate.dart |
| diff --git a/runtime/bin/vmservice/client/lib/src/observatory/isolate.dart b/runtime/bin/vmservice/client/lib/src/observatory/isolate.dart |
| index 0135c4b6ef0701bf72d8c874b5fe42d319fe3ccd..7ba5243a93be7d0c644b878c947eca3172fb0076 100644 |
| --- a/runtime/bin/vmservice/client/lib/src/observatory/isolate.dart |
| +++ b/runtime/bin/vmservice/client/lib/src/observatory/isolate.dart |
| @@ -2,18 +2,34 @@ |
| // for details. All rights reserved. Use of this source code is governed by a |
| // BSD-style license that can be found in the LICENSE file. |
| -part of observatory; |
| - |
| +part of app; |
| /// State for a running isolate. |
| -class Isolate extends Observable { |
| - static ObservatoryApplication _application; |
| +class Isolate extends Observable implements ServiceObject { |
| + final VM vm; |
| + String _id; |
| + String _serviceType = 'Isolate'; |
| + Isolate get isolate => this; |
| + String get link => _id; |
| + String get id => _id; |
| + String get serviceType => _serviceType; |
| + |
| + Isolate(this.vm, this._id); |
| + |
| + /// Refresh [this]. Returns a future which completes to [this]. |
| + Future refresh() { |
| + return vm.fetchMap(_id).then((m) => update(m)).then((_) => this); |
| + } |
| + |
| + /// Creates a link to [objectId] relative to [this]. |
| + String relativeLink(String objectId) => '$id/$objectId'; |
| + /// Creates a relative link to [objectId] with a '#/' prefix. |
| + String hashLink(String objectId) => '#/${relativeLink(objectId)}'; |
| @observable Profile profile; |
| @observable final Map<String, Script> scripts = |
| toObservable(new Map<String, Script>()); |
| @observable final List<Code> codes = new List<Code>(); |
| - @observable String id; |
| @observable String name; |
| @observable String vmName; |
| @observable Map entry; |
| @@ -26,20 +42,11 @@ class Isolate extends Observable { |
| @observable Map topFrame = null; |
| @observable String fileAndLine = null; |
| - |
| - Isolate.fromId(this.id) : name = 'isolate' {} |
| - |
| - Isolate.fromMap(Map map) |
| - : id = map['id'], name = map['name'] { |
| - } |
| - Future refresh() { |
| - var request = '/$id/'; |
| - return _application.requestManager.requestMap(request).then((map) { |
| - update(map); |
| - }).catchError((e, trace) { |
| - Logger.root.severe('Error while updating isolate summary: $e\n$trace'); |
| - }); |
| + Isolate.fromId(this.vm, this._id) : name = 'isolate' {} |
| + |
| + Isolate.fromMap(this.vm, Map map) |
| + : _id = map['id'], name = map['name'] { |
| } |
| void update(Map map) { |
| @@ -122,4 +129,125 @@ class Isolate extends Observable { |
| script._processCoverageHits(coverage['hits']); |
| } |
| } |
| + |
| + // TODO(johnmccutchan): Kill. |
|
turnidge
2014/03/05 21:02:47
Maybe more verbose on the comment.
Cutch
2014/03/05 21:54:23
Done.
|
| + void _setModelResponse(String type, String modelName, dynamic model) { |
| + var response = { |
| + 'type': type, |
| + modelName: model |
| + }; |
| + vm.app.setResponse(response); |
| + } |
| + |
| + void _setResponseRequestError(HttpRequest request) { |
| + String error = '${request.status} ${request.statusText}'; |
| + if (request.status == 0) { |
| + error = 'No service found. Did you run with --enable-vm-service ?'; |
| + } |
| + vm.app.setResponseError(error, 'RequestError'); |
| + } |
| + |
| + void _requestCatchError(e, st) { |
| + if (e is ProgressEvent) { |
| + _setResponseRequestError(e.target); |
| + } else { |
| + vm.app.setResponseError('$e $st'); |
| + } |
| + } |
| + |
| + static final RegExp _codeMatcher = new RegExp(r'/code/'); |
| + static bool isCodeId(objectId) => _codeMatcher.hasMatch(objectId); |
| + static int codeAddressFromRequest(String objectId) { |
| + Match m = _codeMatcher.matchAsPrefix(objectId); |
| + if (m == null) { |
| + return 0; |
| + } |
| + try { |
| + var a = int.parse(m.input.substring(m.end), radix: 16); |
| + return a; |
| + } catch (e) { |
| + return 0; |
| + } |
| + } |
| + |
| + /// Handle 'Code' requests |
| + void _getCode(String objectId) { |
| + var address = codeAddressFromRequest(objectId); |
| + if (address == 0) { |
| + vm.app.setResponseError('$objectId is not a valid code request.'); |
| + return; |
| + } |
| + var code = isolate.findCodeByAddress(address); |
| + if (code != null) { |
| + Logger.root.info( |
| + 'Found code with 0x${address.toRadixString(16)} in isolate.'); |
| + _setModelResponse('Code', 'code', code); |
| + return; |
| + } |
| + getMap(objectId).then((map) { |
| + assert(map['type'] == 'Code'); |
| + var code = new Code.fromMap(map); |
| + Logger.root.info( |
| + 'Added code with 0x${address.toRadixString(16)} to isolate.'); |
| + isolate.codes.add(code); |
| + _setModelResponse('Code', 'code', code); |
| + }).catchError(_requestCatchError); |
| + } |
| + |
| + static final RegExp _scriptMatcher = new RegExp(r'scripts/.+'); |
| + static bool isScriptId(objectId) => _scriptMatcher.hasMatch(objectId); |
| + void _getScript(String objectId) { |
| + var script = scripts[objectId]; |
| + if ((script != null) && !script.needsSource) { |
| + Logger.root.info('Found script ${script.scriptRef['name']} in isolate'); |
| + _setModelResponse('Script', 'script', script); |
| + return; |
| + } |
| + if (script != null) { |
| + // The isolate has the script but no script source code. |
| + getMap(objectId).then((response) { |
| + assert(response['type'] == 'Script'); |
| + script._processSource(response['source']); |
| + Logger.root.info( |
| + 'Grabbed script ${script.scriptRef['name']} source.'); |
| + _setModelResponse('Script', 'script', script); |
| + }); |
| + return; |
| + } |
| + // New script. |
| + getMap(objectId).then((response) { |
| + assert(response['type'] == 'Script'); |
| + var script = new Script.fromMap(response); |
| + Logger.root.info( |
| + 'Added script ${script.scriptRef['name']} to isolate.'); |
| + _setModelResponse('Script', 'script', script); |
| + scripts[objectId] = script; |
| + }); |
| + } |
| + |
| + /// Requests [objectId] from [this]. Completes to a [ServiceObject]. |
| + Future<ServiceObject> get(String objectId) { |
| + if (isCodeId(objectId)) { |
| + _getCode(objectId); |
| + // TODO(johnmccutchan): FIX. |
| + return null; |
| + } |
| + if (isScriptId(objectId)) { |
| + _getScript(objectId); |
| + // TODO(johnmccutchan): FIX. |
| + return null; |
| + } |
| + return vm.fetchMap(relativeLink(objectId)).then((m) => |
| + upgradeToServiceObject(objectId, m)); |
| + } |
| + |
| + /// Requests [objectId] from [this]. Completes to a [Map]. |
| + Future<Map> getMap(String objectId) { |
|
turnidge
2014/03/05 21:02:47
Future<ObservableMap>
Cutch
2014/03/05 21:54:23
Done here and elsewhere.
|
| + return vm.fetchMap(relativeLink(objectId)); |
| + } |
| + |
| + /// Upgrades response ([m]) for [objectId] to a [ServiceObject]. |
| + ServiceObject upgradeToServiceObject(String objectId, Map m) { |
| + return new ServiceMap.fromMap(this, m); |
| + } |
| } |