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

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

Issue 897193002: Finish moving service protocol to json rpc. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: code review Created 5 years, 10 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] is an object known to the VM service and is tied 7 /// A [ServiceObject] represents a persistent object within the vm.
8 /// to an owning [Isolate].
9 abstract class ServiceObject extends Observable { 8 abstract class ServiceObject extends Observable {
10 static int LexicalSortName(ServiceObject o1, ServiceObject o2) { 9 static int LexicalSortName(ServiceObject o1, ServiceObject o2) {
11 return o1.name.compareTo(o2.name); 10 return o1.name.compareTo(o2.name);
12 } 11 }
13 12
14 List removeDuplicatesAndSortLexical(List<ServiceObject> list) { 13 List removeDuplicatesAndSortLexical(List<ServiceObject> list) {
15 return list.toSet().toList()..sort(LexicalSortName); 14 return list.toSet().toList()..sort(LexicalSortName);
16 } 15 }
17 16
18 /// The owner of this [ServiceObject]. This can be an [Isolate], a 17 /// The owner of this [ServiceObject]. This can be an [Isolate], a
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
83 82
84 // Kinds of Instance. 83 // Kinds of Instance.
85 bool get isMirrorReference => vmType == 'MirrorReference'; 84 bool get isMirrorReference => vmType == 'MirrorReference';
86 bool get isWeakProperty => vmType == 'WeakProperty'; 85 bool get isWeakProperty => vmType == 'WeakProperty';
87 bool get isClosure => false; 86 bool get isClosure => false;
88 bool get isPlainInstance { 87 bool get isPlainInstance {
89 return (type == 'Instance' && 88 return (type == 'Instance' &&
90 !isMirrorReference && !isWeakProperty && !isClosure); 89 !isMirrorReference && !isWeakProperty && !isClosure);
91 } 90 }
92 91
93 /// The complete service url of this object.
94 @reflectable String get link => _owner.relativeLink(_id);
95
96 /// Has this object been fully loaded? 92 /// Has this object been fully loaded?
97 bool get loaded => _loaded; 93 bool get loaded => _loaded;
98 bool _loaded = false; 94 bool _loaded = false;
99 // TODO(turnidge): Make loaded observable and get rid of loading 95 // TODO(turnidge): Make loaded observable and get rid of loading
100 // from Isolate. 96 // from Isolate.
101 97
102 /// Is this object cacheable? That is, is it impossible for the [id] 98 /// Is this object cacheable? That is, is it impossible for the [id]
103 /// of this object to change? 99 /// of this object to change?
104 bool get canCache => false; 100 bool get canCache => false;
105 101
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after
275 _vmType = _stripRef(map['_vmType']); 271 _vmType = _stripRef(map['_vmType']);
276 } else { 272 } else {
277 _vmType = _type; 273 _vmType = _type;
278 } 274 }
279 275
280 _update(map, mapIsRef); 276 _update(map, mapIsRef);
281 } 277 }
282 278
283 // Updates internal state from [map]. [map] can be a reference. 279 // Updates internal state from [map]. [map] can be a reference.
284 void _update(ObservableMap map, bool mapIsRef); 280 void _update(ObservableMap map, bool mapIsRef);
285
286 String relativeLink(String id) {
287 assert(id != null);
288 return "${link}/${id}";
289 }
290 } 281 }
291 282
292 abstract class Coverage { 283 abstract class Coverage {
293 // Following getters and functions will be provided by [ServiceObject]. 284 // Following getters and functions will be provided by [ServiceObject].
294 ServiceObjectOwner get owner; 285 ServiceObjectOwner get owner;
295 String get type; 286 String get type;
296 VM get vm; 287 VM get vm;
297 String relativeLink(String id);
298 288
299 /// Default handler for coverage data. 289 /// Default handler for coverage data.
300 void processCoverageData(List coverageData) { 290 void processCoverageData(List coverageData) {
301 coverageData.forEach((scriptCoverage) { 291 coverageData.forEach((scriptCoverage) {
302 assert(scriptCoverage['script'] != null); 292 assert(scriptCoverage['script'] != null);
303 scriptCoverage['script']._processHits(scriptCoverage['hits']); 293 scriptCoverage['script']._processHits(scriptCoverage['hits']);
304 }); 294 });
305 } 295 }
306 296
307 Future refreshCoverage() { 297 Future refreshCoverage() {
(...skipping 14 matching lines...) Expand all
322 } 312 }
323 313
324 abstract class ServiceObjectOwner extends ServiceObject { 314 abstract class ServiceObjectOwner extends ServiceObject {
325 /// Creates an empty [ServiceObjectOwner]. 315 /// Creates an empty [ServiceObjectOwner].
326 ServiceObjectOwner._empty(ServiceObjectOwner owner) : super._empty(owner); 316 ServiceObjectOwner._empty(ServiceObjectOwner owner) : super._empty(owner);
327 317
328 /// Builds a [ServiceObject] corresponding to the [id] from [map]. 318 /// Builds a [ServiceObject] corresponding to the [id] from [map].
329 /// The result may come from the cache. The result will not necessarily 319 /// The result may come from the cache. The result will not necessarily
330 /// be [loaded]. 320 /// be [loaded].
331 ServiceObject getFromMap(ObservableMap map); 321 ServiceObject getFromMap(ObservableMap map);
332
333 /// Creates a link to [id] relative to [this].
334 String relativeLink(String id);
335 } 322 }
336 323
337 /// State for a VM being inspected. 324 /// State for a VM being inspected.
338 abstract class VM extends ServiceObjectOwner { 325 abstract class VM extends ServiceObjectOwner {
339 @reflectable VM get vm => this; 326 @reflectable VM get vm => this;
340 @reflectable Isolate get isolate => null; 327 @reflectable Isolate get isolate => null;
341 328
342 @reflectable Iterable<Isolate> get isolates => _isolateCache.values; 329 @reflectable Iterable<Isolate> get isolates => _isolateCache.values;
343 330
344 @reflectable String get link => '$id';
345 @reflectable String relativeLink(String id) => '$id';
346
347 @observable String version = 'unknown'; 331 @observable String version = 'unknown';
348 @observable String targetCPU; 332 @observable String targetCPU;
349 @observable int architectureBits; 333 @observable int architectureBits;
350 @observable double uptime = 0.0; 334 @observable double uptime = 0.0;
351 @observable bool assertsEnabled = false; 335 @observable bool assertsEnabled = false;
352 @observable bool typeChecksEnabled = false; 336 @observable bool typeChecksEnabled = false;
353 @observable String pid = ''; 337 @observable String pid = '';
354 @observable DateTime lastUpdate; 338 @observable DateTime lastUpdate;
355 339
356 VM() : super._empty(null) { 340 VM() : super._empty(null) {
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
443 // Doesn't scale well. Change this to be more fine-grained. 427 // Doesn't scale well. Change this to be more fine-grained.
444 return reload().then((result) { 428 return reload().then((result) {
445 if (result is! VM) { 429 if (result is! VM) {
446 return null; 430 return null;
447 } 431 }
448 assert(result == this); 432 assert(result == this);
449 return _isolateCache[isolateId]; 433 return _isolateCache[isolateId];
450 }); 434 });
451 } 435 }
452 436
453 Future<ServiceObject> getDeprecated(String id) {
454 assert(id.startsWith('/') == false);
455 // Isolates are handled specially, since they can cache sub-objects.
456 if (id.startsWith(_isolatesPrefix)) {
457 String isolateId = _parseIsolateId(id);
458 String objectId = _parseObjectId(id);
459 return getIsolate(isolateId).then((isolate) {
460 if (isolate == null) {
461 // The isolate does not exist. Return the VM object instead.
462 //
463 // TODO(turnidge): Generate a service error?
464 return this;
465 }
466 if (objectId == null) {
467 return isolate.reload();
468 } else {
469 return isolate.getDeprecated(objectId);
470 }
471 });
472 }
473
474 var obj = _cache[id];
475 if (obj != null) {
476 return obj.reload();
477 }
478
479 // Cache miss. Get the object from the vm directly.
480 return _getAsMapDeprecated(id).then((ObservableMap map) {
481 var obj = new ServiceObject._fromMap(this, map);
482 if (obj.canCache) {
483 _cache.putIfAbsent(id, () => obj);
484 }
485 return obj;
486 });
487 }
488
489 dynamic _reviver(dynamic key, dynamic value) { 437 dynamic _reviver(dynamic key, dynamic value) {
490 return value; 438 return value;
491 } 439 }
492 440
493 ObservableMap _parseJSON(String response) { 441 ObservableMap _parseJSON(String response) {
494 var map; 442 var map;
495 try { 443 try {
496 var decoder = new JsonDecoder(_reviver); 444 var decoder = new JsonDecoder(_reviver);
497 map = decoder.convert(response); 445 map = decoder.convert(response);
498 } catch (e) { 446 } catch (e) {
(...skipping 21 matching lines...) Expand all
520 // Preemptively capture ServiceError and ServiceExceptions. 468 // Preemptively capture ServiceError and ServiceExceptions.
521 if (map['type'] == 'ServiceError') { 469 if (map['type'] == 'ServiceError') {
522 return new Future.error(new ServiceObject._fromMap(this, map)); 470 return new Future.error(new ServiceObject._fromMap(this, map));
523 } else if (map['type'] == 'ServiceException') { 471 } else if (map['type'] == 'ServiceException') {
524 return new Future.error(new ServiceObject._fromMap(this, map)); 472 return new Future.error(new ServiceObject._fromMap(this, map));
525 } 473 }
526 // map is now guaranteed to be a non-error/exception ServiceObject. 474 // map is now guaranteed to be a non-error/exception ServiceObject.
527 return new Future.value(map); 475 return new Future.value(map);
528 } 476 }
529 477
530 /// Gets [id] as an [ObservableMap] from the service directly. If
531 /// an error occurs, the future is completed as an error with a
532 /// ServiceError or ServiceException. Therefore any chained then() calls
533 /// will only receive a map encoding a valid ServiceObject.
534 Future<ObservableMap> _getAsMapDeprecated(String id) {
535 return getStringDeprecated(id).then((response) {
536 var map = _parseJSON(response);
537 if (Tracer.current != null) {
538 Tracer.current.trace("Received response for ${id}", map:map);
539 }
540 return _processMap(map);
541 }).catchError((error) {
542 // ServiceError, forward to VM's ServiceError stream.
543 errors.add(error);
544 return new Future.error(error);
545 }, test: (e) => e is ServiceError).catchError((exception) {
546 // ServiceException, forward to VM's ServiceException stream.
547 exceptions.add(exception);
548 return new Future.error(exception);
549 }, test: (e) => e is ServiceException);
550 }
551
552 /// Get [id] as a [String] from the service directly. See [getAsMap].
553 Future<String> getStringDeprecated(String id);
554
555 // Implemented in subclass. 478 // Implemented in subclass.
556 Future<String> invokeRpcRaw(String method, Map params); 479 Future<String> invokeRpcRaw(String method, Map params);
557 480
558 Future<ObservableMap> invokeRpcNoUpgrade(String method, Map params) { 481 Future<ObservableMap> invokeRpcNoUpgrade(String method, Map params) {
559 return invokeRpcRaw(method, params).then((String response) { 482 return invokeRpcRaw(method, params).then((String response) {
560 var map = _parseJSON(response); 483 var map = _parseJSON(response);
561 if (Tracer.current != null) { 484 if (Tracer.current != null) {
562 Tracer.current.trace("Received response for ${method}/${params}}", 485 Tracer.current.trace("Received response for ${method}/${params}}",
563 map:map); 486 map:map);
564 } 487 }
(...skipping 20 matching lines...) Expand all
585 _cache.putIfAbsent(id, () => obj); 508 _cache.putIfAbsent(id, () => obj);
586 } 509 }
587 return obj; 510 return obj;
588 }); 511 });
589 } 512 }
590 513
591 Future<ObservableMap> _fetchDirect() { 514 Future<ObservableMap> _fetchDirect() {
592 return invokeRpcNoUpgrade('getVM', {}); 515 return invokeRpcNoUpgrade('getVM', {});
593 } 516 }
594 517
518 Future<ServiceObject> getFlagList() {
519 return invokeRpc('getFlagList', {});
520 }
521
595 /// Force the VM to disconnect. 522 /// Force the VM to disconnect.
596 void disconnect(); 523 void disconnect();
597 /// Completes when the VM first connects. 524 /// Completes when the VM first connects.
598 Future get onConnect; 525 Future get onConnect;
599 /// Completes when the VM disconnects or there was an error connecting. 526 /// Completes when the VM disconnects or there was an error connecting.
600 Future get onDisconnect; 527 Future get onDisconnect;
601 528
602 void _update(ObservableMap map, bool mapIsRef) { 529 void _update(ObservableMap map, bool mapIsRef) {
603 if (mapIsRef) { 530 if (mapIsRef) {
604 return; 531 return;
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after
747 674
748 HeapSnapshot(this.isolate, ByteData data) : 675 HeapSnapshot(this.isolate, ByteData data) :
749 graph = new ObjectGraph(new ReadStream(data)), 676 graph = new ObjectGraph(new ReadStream(data)),
750 timeStamp = new DateTime.now() { 677 timeStamp = new DateTime.now() {
751 } 678 }
752 679
753 List<Future<ServiceObject>> getMostRetained({int classId, int limit}) { 680 List<Future<ServiceObject>> getMostRetained({int classId, int limit}) {
754 var result = []; 681 var result = [];
755 for (var v in graph.getMostRetained(classId: classId, limit: limit)) { 682 for (var v in graph.getMostRetained(classId: classId, limit: limit)) {
756 var address = v.addressForWordSize(isolate.vm.architectureBits ~/ 8); 683 var address = v.addressForWordSize(isolate.vm.architectureBits ~/ 8);
757 result.add(isolate.getDeprecated( 684 result.add(isolate.getObjectByAddress(address.toRadixString(16)).then((obj ) {
758 'address/${address.toRadixString(16)}?ref=true').then((obj) {
759 obj.retainedSize = v.retainedSize; 685 obj.retainedSize = v.retainedSize;
760 return new Future(() => obj); 686 return new Future(() => obj);
761 })); 687 }));
762 } 688 }
763 return result; 689 return result;
764 } 690 }
765 691
766 692
767 } 693 }
768 694
769 /// State for a running isolate. 695 /// State for a running isolate.
770 class Isolate extends ServiceObjectOwner with Coverage { 696 class Isolate extends ServiceObjectOwner with Coverage {
771 @reflectable VM get vm => owner; 697 @reflectable VM get vm => owner;
772 @reflectable Isolate get isolate => this; 698 @reflectable Isolate get isolate => this;
773 @observable ObservableMap counters = new ObservableMap(); 699 @observable ObservableMap counters = new ObservableMap();
774 700
775 String get link => '/${_id}';
776
777 @observable ServiceEvent pauseEvent = null; 701 @observable ServiceEvent pauseEvent = null;
778 bool get _isPaused => pauseEvent != null; 702 bool get _isPaused => pauseEvent != null;
779 703
780 @observable bool running = false; 704 @observable bool running = false;
781 @observable bool idle = false; 705 @observable bool idle = false;
782 @observable bool loading = true; 706 @observable bool loading = true;
783 @observable bool ioEnabled = false; 707 @observable bool ioEnabled = false;
784 708
785 Map<String,ServiceObject> _cache = new Map<String,ServiceObject>(); 709 Map<String,ServiceObject> _cache = new Map<String,ServiceObject>();
786 final TagProfile tagProfile = new TagProfile(20); 710 final TagProfile tagProfile = new TagProfile(20);
787 711
788 Isolate._empty(ServiceObjectOwner owner) : super._empty(owner) { 712 Isolate._empty(ServiceObjectOwner owner) : super._empty(owner) {
789 assert(owner is VM); 713 assert(owner is VM);
790 } 714 }
791 715
792 /// Creates a link to [id] relative to [this].
793 @reflectable String relativeLink(String id) => '/${this.id}/$id';
794
795 static const TAG_ROOT_ID = 'code/tag-0'; 716 static const TAG_ROOT_ID = 'code/tag-0';
796 717
797 /// Returns the Code object for the root tag. 718 /// Returns the Code object for the root tag.
798 Code tagRoot() { 719 Code tagRoot() {
799 // TODO(turnidge): Use get() here instead? 720 // TODO(turnidge): Use get() here instead?
800 return _cache[TAG_ROOT_ID]; 721 return _cache[TAG_ROOT_ID];
801 } 722 }
802 723
803 void processProfile(ServiceMap profile) { 724 void processProfile(ServiceMap profile) {
804 assert(profile.type == 'CpuProfile'); 725 assert(profile.type == 'CpuProfile');
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
883 return obj; 804 return obj;
884 } 805 }
885 // Build the object from the map directly. 806 // Build the object from the map directly.
886 obj = new ServiceObject._fromMap(this, map); 807 obj = new ServiceObject._fromMap(this, map);
887 if (obj != null && obj.canCache) { 808 if (obj != null && obj.canCache) {
888 _cache[id] = obj; 809 _cache[id] = obj;
889 } 810 }
890 return obj; 811 return obj;
891 } 812 }
892 813
893 Future<ServiceObject> getDeprecated(String id) {
894 // Do not allow null ids or empty ids.
895 assert(id != null && id != '');
896 var obj = _cache[id];
897 if (obj != null) {
898 return obj.reload();
899 }
900 // Cache miss. Get the object from the vm directly.
901 return vm._getAsMapDeprecated(relativeLink(id)).then((ObservableMap map) {
902 var obj = new ServiceObject._fromMap(this, map);
903 if (obj.canCache) {
904 _cache.putIfAbsent(id, () => obj);
905 }
906 return obj;
907 });
908 }
909
910 Future<ObservableMap> invokeRpcNoUpgrade(String method, Map params) { 814 Future<ObservableMap> invokeRpcNoUpgrade(String method, Map params) {
911 params['isolate'] = id; 815 params['isolateId'] = id;
912 return vm.invokeRpcNoUpgrade(method, params); 816 return vm.invokeRpcNoUpgrade(method, params);
913 } 817 }
914 818
915 Future<ServiceObject> invokeRpc(String method, Map params) { 819 Future<ServiceObject> invokeRpc(String method, Map params) {
916 return invokeRpcNoUpgrade(method, params).then((ObservableMap response) { 820 return invokeRpcNoUpgrade(method, params).then((ObservableMap response) {
917 var obj = new ServiceObject._fromMap(this, response); 821 var obj = new ServiceObject._fromMap(this, response);
918 if (obj.canCache) { 822 if (obj.canCache) {
919 _cache.putIfAbsent(id, () => obj); 823 _cache.putIfAbsent(id, () => obj);
920 } 824 }
921 return obj; 825 return obj;
(...skipping 398 matching lines...) Expand 10 before | Expand all | Expand 10 after
1320 } 1224 }
1321 1225
1322 Future<ServiceObject> getInstances(Class cls, var limit) { 1226 Future<ServiceObject> getInstances(Class cls, var limit) {
1323 Map params = { 1227 Map params = {
1324 'classId': cls.id, 1228 'classId': cls.id,
1325 'limit': limit.toString(), 1229 'limit': limit.toString(),
1326 }; 1230 };
1327 return invokeRpc('getInstances', params); 1231 return invokeRpc('getInstances', params);
1328 } 1232 }
1329 1233
1234 Future<ServiceObject> getObjectByAddress(String address, [bool ref=true]) {
1235 Map params = {
1236 'address': address,
1237 'ref': ref,
1238 };
1239 return invokeRpc('getObjectByAddress', params);
1240 }
1241
1330 final ObservableMap<String, ServiceMetric> dartMetrics = 1242 final ObservableMap<String, ServiceMetric> dartMetrics =
1331 new ObservableMap<String, ServiceMetric>(); 1243 new ObservableMap<String, ServiceMetric>();
1332 1244
1333 final ObservableMap<String, ServiceMetric> nativeMetrics = 1245 final ObservableMap<String, ServiceMetric> nativeMetrics =
1334 new ObservableMap<String, ServiceMetric>(); 1246 new ObservableMap<String, ServiceMetric>();
1335 1247
1336 Future<ObservableMap<String, ServiceMetric>> _refreshMetrics( 1248 Future<ObservableMap<String, ServiceMetric>> _refreshMetrics(
1337 String metricType, 1249 String metricType,
1338 ObservableMap<String, ServiceMetric> metricsMap) { 1250 ObservableMap<String, ServiceMetric> metricsMap) {
1339 return invokeRpc('getIsolateMetricList', 1251 return invokeRpc('getIsolateMetricList',
(...skipping 1602 matching lines...) Expand 10 before | Expand all | Expand 10 after
2942 var v = list[i]; 2854 var v = list[i];
2943 if ((v is ObservableMap) && _isServiceMap(v)) { 2855 if ((v is ObservableMap) && _isServiceMap(v)) {
2944 list[i] = owner.getFromMap(v); 2856 list[i] = owner.getFromMap(v);
2945 } else if (v is ObservableList) { 2857 } else if (v is ObservableList) {
2946 _upgradeObservableList(v, owner); 2858 _upgradeObservableList(v, owner);
2947 } else if (v is ObservableMap) { 2859 } else if (v is ObservableMap) {
2948 _upgradeObservableMap(v, owner); 2860 _upgradeObservableMap(v, owner);
2949 } 2861 }
2950 } 2862 }
2951 } 2863 }
OLDNEW
« no previous file with comments | « runtime/observatory/lib/src/elements/service_view.html ('k') | runtime/observatory/observatory.gypi » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698