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

Unified Diff: runtime/bin/vmservice/client/lib/src/service/object.dart

Issue 206213004: Add a VM page to the observatory. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: before review Created 6 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/bin/vmservice/client/lib/src/service/object.dart
diff --git a/runtime/bin/vmservice/client/lib/src/service/object.dart b/runtime/bin/vmservice/client/lib/src/service/object.dart
index 63e253f021a4a60c53cc05b7034d73c2bfb178a6..3d384c5432026053af72f5bdbde7aa96a1054ffa 100644
--- a/runtime/bin/vmservice/client/lib/src/service/object.dart
+++ b/runtime/bin/vmservice/client/lib/src/service/object.dart
@@ -7,47 +7,73 @@ part of service;
/// A [ServiceObject] is an object known to the VM service and is tied
/// to an owning [Isolate].
abstract class ServiceObject extends Observable {
- Isolate _isolate;
+ /// The owner of this [ServiceObject]. This can be an [Isolate], a
+ /// [VM], or null.
+ @reflectable ServiceObject get owner => _owner;
+ ServiceObject _owner;
+
+ /// The [VM] which owns this [ServiceObject].
+ @reflectable VM get vm {
+ if (owner == null) {
+ assert(this is VM);
+ return this;
+ } else if (owner is VM) {
+ return owner;
+ } else {
+ assert(owner.owner is VM);
+ return owner.owner;
+ }
+ }
- /// Owning isolate.
- @reflectable Isolate get isolate => _isolate;
+ /// The [Isolate] which owns this [ServiceObject]. May be null.
+ @reflectable Isolate get isolate {
+ if (owner == null) {
+ return null;
+ } else if (this is Isolate) {
+ return this;
+ } else {
+ assert(owner is Isolate);
+ return owner;
+ }
+ }
+
+ /// The id of this object.
+ @reflectable String get id => _id;
+ String _id;
- /// Owning vm.
- @reflectable VM get vm => _isolate.vm;
+ /// The service type of this object.
+ @reflectable String get serviceType => _serviceType;
+ String _serviceType;
/// The complete service url of this object.
@reflectable String get link => isolate.relativeLink(_id);
/// The complete service url of this object with a '#/' prefix.
- @reflectable String get hashLink => isolate.relativeHashLink(_id);
+ @reflectable String get hashLink => '#/${link}';
set hashLink(var o) { /* silence polymer */ }
- String _id;
- /// The id of this object.
- @reflectable String get id => _id;
-
- String _serviceType;
- /// The service type of this object.
- @reflectable String get serviceType => _serviceType;
-
+ /// Returns true if [this] has only been partially initialized via
+ /// a reference. See [load].
+ bool isRef() => _ref;
bool _ref;
@observable String name;
@observable String vmName;
+ @observable String mainPort;
- ServiceObject(this._isolate, this._id, this._serviceType) {
+ ServiceObject(this._owner, this._id, this._serviceType) {
_ref = isRefType(_serviceType);
_serviceType = stripRef(_serviceType);
_created();
}
- ServiceObject.fromMap(this._isolate, ObservableMap m) {
- assert(isServiceMap(m));
- _id = m['id'];
- _ref = isRefType(m['type']);
- _serviceType = stripRef(m['type']);
+ ServiceObject.fromMap(this._owner, ObservableMap map) {
+ assert(isServiceMap(map));
+ _id = map['id'];
+ _ref = isRefType(map['type']);
+ _serviceType = stripRef(map['type']);
+ update(map);
_created();
- update(m);
}
/// If [this] was created from a reference, load the full object
@@ -64,13 +90,12 @@ abstract class ServiceObject extends Observable {
/// Reload [this]. Returns a future which completes to [this] or
/// a [ServiceError].
Future<ServiceObject> reload() {
- assert(isolate != null);
if (id == '') {
// Errors don't have ids.
assert(serviceType == 'Error');
return new Future.value(this);
}
- return isolate.vm.getAsMap(link).then(update);
+ return vm.getAsMap(link).then(update);
}
/// Update [this] using [m] as a source. [m] can be a reference.
@@ -92,16 +117,14 @@ abstract class ServiceObject extends Observable {
// update internal state from [map]. [map] can be a reference.
void _update(ObservableMap map);
- /// Returns true if [this] has only been partially initialized via
- /// a reference. See [load].
- bool isRef() => _ref;
-
void _created() {
var refNotice = _ref ? ' Created from reference.' : '';
Logger.root.info('Created ServiceObject for \'${_id}\' with type '
'\'${_serviceType}\'.' + refNotice);
}
+ // ------------------------------------------------------
+
/// Returns true if [map] is a service map. i.e. it has the following keys:
/// 'id' and a 'type'.
static bool isServiceMap(ObservableMap m) {
@@ -125,20 +148,80 @@ abstract class ServiceObject extends Observable {
}
/// State for a VM being inspected.
-abstract class VM extends Observable {
+abstract class VM extends ServiceObject {
@reflectable IsolateList _isolates;
@reflectable IsolateList get isolates => _isolates;
+ @reflectable String get link => "$id";
+
+ @observable String version = 'unknown';
+ @observable String architecture = 'unknown';
+ @observable double uptime = 0.0;
+
void _initOnce() {
assert(_isolates == null);
_isolates = new IsolateList(this);
+ name = "vm";
+ vmName = "vm";
}
- VM() {
+ VM() : super(null, "vm", "VM") {
_initOnce();
}
- /// Get [id] as an [ObservableMap] from the service directly.
+ static final RegExp _currentIsolateMatcher = new RegExp(r'isolates/\d+');
+ static final RegExp _currentObjectMatcher = new RegExp(r'isolates/\d+(/|$)');
+
+ String _parseObjectId(String id) {
+ Match m = _currentObjectMatcher.matchAsPrefix(id);
+ if (m == null) {
+ return null;
+ }
+ return m.input.substring(m.end);
+ }
+
+ String _parseIsolateId(String id) {
+ Match m = _currentIsolateMatcher.matchAsPrefix(id);
+ if (m == null) {
+ print("NO MATCH");
Cutch 2014/03/20 18:25:56 Logger.root.warning ?
turnidge 2014/03/20 19:08:02 Actually this happens legitimately on the /vm page
+ return '';
+ }
+ return id.substring(0, m.end);
+ }
+
+ Future<ServiceObject> _getDirect(String id) {
+ return vm.getAsMap(id).then((ObservableMap m) {
+ return _upgradeToServiceObject(vm, null, m);
+ });
+ }
+
+ Future<ServiceObject> get(String id) {
+ if (id.startsWith('isolates/')) {
+ String isolateId = _parseIsolateId(id);
+ if (isolateId == '') {
+ return reload();
+ } else {
+ Isolate isolate = _isolates.getIsolate(isolateId);
+ if (isolate == null) {
+ // TODO(turnidge): Isolate not found error.
+ return reload();
+ } else {
+ String objectId = _parseObjectId(id);
+ if (objectId == null) {
+ return isolate.reload();
+ } else {
+ return isolate.get(objectId);
+ }
+ }
+ }
+ } else if (id == 'vm') {
+ return reload();
+ } else {
+ return _getDirect(id);
+ }
+ }
+
+ /// Gets [id] as an [ObservableMap] from the service directly.
Future<ObservableMap> getAsMap(String id) {
return getString(id).then((response) {
try {
@@ -165,14 +248,27 @@ abstract class VM extends Observable {
/// Get [id] as a [String] from the service directly. See [getAsMap].
Future<String> getString(String id);
+
+ void _update(ObservableMap map) {
+ print("$map");
Cutch 2014/03/20 18:25:56 remove?
turnidge 2014/03/20 19:08:02 Done.
+ _ref = false;
+ version = map['version'];
+ architecture = map['architecture'];
+ uptime = map['uptime'];
+ _isolates.updateIsolates(map['isolates']);
+ }
}
/// State for a running isolate.
class Isolate extends ServiceObject {
- final VM vm;
String get link => _id;
String get hashLink => '#/$_id';
+ @observable bool pausedOnStart = false;
+ @observable bool pausedOnExit = false;
+ @observable bool running = false;
+ @observable bool idle = false;
+
ScriptCache _scripts;
/// Script cache.
ScriptCache get scripts => _scripts;
@@ -188,19 +284,18 @@ class Isolate extends ServiceObject {
void _initOnce() {
// Only called once.
- assert(_isolate == null);
- _isolate = this;
+ assert(_scripts == null);
_scripts = new ScriptCache(this);
_codes = new CodeCache(this);
_classes = new ClassCache(this);
_functions = new FunctionCache(this);
}
- Isolate.fromId(this.vm, String id) : super(null, id, '@Isolate') {
+ Isolate.fromId(VM vm, String id) : super(vm, id, '@Isolate') {
_initOnce();
}
- Isolate.fromMap(this.vm, Map map) : super.fromMap(null, map) {
+ Isolate.fromMap(VM vm, Map map) : super.fromMap(vm, map) {
_initOnce();
}
@@ -230,7 +325,7 @@ class Isolate extends ServiceObject {
}
}
- Future<ServiceObject> getDirect(String serviceId) {
+ Future<ServiceObject> _getDirect(String serviceId) {
return vm.getAsMap(relativeLink(serviceId)).then((ObservableMap m) {
return _upgradeToServiceObject(vm, this, m);
});
@@ -254,7 +349,7 @@ class Isolate extends ServiceObject {
if (_functions.cachesId(serviceId)) {
return _functions.get(serviceId);
}
- return getDirect(serviceId);
+ return _getDirect(serviceId);
}
@observable ServiceMap rootLib;
@@ -276,6 +371,11 @@ class Isolate extends ServiceObject {
void _update(ObservableMap map) {
upgradeCollection(map, vm, this);
+ mainPort = map['mainPort'];
+ name = map['name'];
+ if (ServiceObject.isRefType(map['type'])) {
+ return;
+ }
_ref = false;
if (map['rootLib'] == null ||
map['timers'] == null ||
@@ -287,10 +387,6 @@ class Isolate extends ServiceObject {
vmName = map['name'];
if (map['entry'] != null) {
entry = map['entry'];
- name = entry['name'];
- } else {
- // fred
- name = 'root';
}
if (map['topFrame'] != null) {
topFrame = map['topFrame'];
@@ -315,6 +411,12 @@ class Isolate extends ServiceObject {
oldHeapUsed = map['heap']['usedOld'];
newHeapCapacity = map['heap']['capacityNew'];
oldHeapCapacity = map['heap']['capacityOld'];
+
+ // Isolate status
+ pausedOnStart = map['pausedOnStart'];
+ pausedOnExit = map['pausedOnExit'];
+ running = map['topFrame'] != null;
+ idle = !pausedOnStart && !pausedOnExit && !running;
}
@reflectable CodeTrieNode profileTrieRoot;
@@ -364,28 +466,13 @@ class Isolate extends ServiceObject {
}
// TODO(johnmccutchan): Make this into an IsolateCache.
-class IsolateList extends ServiceObject {
+class IsolateList {
final VM _vm;
- VM get vm => _vm;
@observable final isolates = new ObservableMap<String, Isolate>();
- IsolateList(this._vm) : super(null, 'isolates', 'IsolateList') {
- name = 'IsolateList';
- vmName = name;
- }
- IsolateList.fromMap(this._vm, Map m) : super.fromMap(null, m) {
- name = 'IsolateList';
- vmName = name;
- }
-
- Future<ServiceObject> reload() {
- return vm.getAsMap(id).then(update);
- }
- void _update(ObservableMap map) {
- _updateIsolates(map['members']);
- }
+ IsolateList(this._vm);
- void _updateIsolates(List<Map> members) {
+ void updateIsolates(List<Map> members) {
// Find dead isolates.
var deadIsolates = [];
isolates.forEach((k, v) {
@@ -404,7 +491,7 @@ class IsolateList extends ServiceObject {
var id = map['id'];
var isolate = isolates[id];
if (isolate == null) {
- isolate = new Isolate.fromMap(vm, map);
+ isolate = new Isolate.fromMap(_vm, map);
Logger.root.info('Created ServiceObject for \'${isolate.id}\' with '
'type \'${isolate.serviceType}\'');
isolates[id] = isolate;
@@ -429,7 +516,7 @@ class IsolateList extends ServiceObject {
if (isolate != null) {
return isolate;
}
- isolate = new Isolate.fromId(vm, id);
+ isolate = new Isolate.fromId(_vm, id);
isolates[id] = isolate;
isolate.load();
return isolate;
@@ -444,7 +531,7 @@ class IsolateList extends ServiceObject {
isolate.update(m);
return isolate;
}
- isolate = new Isolate.fromMap(vm, m);
+ isolate = new Isolate.fromMap(_vm, m);
isolates[id] = isolate;
isolate.load();
return isolate;
@@ -509,7 +596,7 @@ class ServiceMap extends ServiceObject implements ObservableMap {
}
class ServiceError extends ServiceObject {
- ServiceError.fromMap(Isolate isolate, Map m) : super.fromMap(isolate, m);
+ ServiceError.fromMap(ServiceObject owner, Map m) : super.fromMap(owner, m);
@observable String kind;
@observable String message;

Powered by Google App Engine
This is Rietveld 408576698