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

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

Issue 1584173003: Use getSourceReport for coverage/callsites in Observatory. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: cleanups Created 4 years, 11 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
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 // Some value smaller than the object ring, so requesting a large array 7 // Some value smaller than the object ring, so requesting a large array
8 // doesn't result in an expired ref because the elements lapped it in the 8 // doesn't result in an expired ref because the elements lapped it in the
9 // object ring. 9 // object ring.
10 const int kDefaultFieldLimit = 100; 10 const int kDefaultFieldLimit = 100;
(...skipping 377 matching lines...) Expand 10 before | Expand all | Expand 10 after
388 clazz = map['class']; 388 clazz = map['class'];
389 } 389 }
390 390
391 if (mapIsRef) { 391 if (mapIsRef) {
392 return; 392 return;
393 } 393 }
394 size = map['size']; 394 size = map['size'];
395 } 395 }
396 } 396 }
397 397
398 abstract class Coverage {
399 // Following getters and functions will be provided by [ServiceObject].
400 String get id;
401 Isolate get isolate;
402
403 Future refreshCoverage() {
404 return refreshCallSiteData();
405 }
406
407 /// Default handler for coverage data.
408 void processCallSiteData(List coverageData) {
409 coverageData.forEach((scriptCoverage) {
410 assert(scriptCoverage['script'] != null);
411 scriptCoverage['script']._processCallSites(scriptCoverage['callSites']);
412 });
413 }
414
415 Future refreshCallSiteData() {
416 Map params = {};
417 if (this is! Isolate) {
418 params['targetId'] = id;
419 }
420 return isolate.invokeRpcNoUpgrade('_getCallSiteData', params).then(
421 (ObservableMap map) {
422 var coverage = new ServiceObject._fromMap(isolate, map);
423 assert(coverage.type == 'CodeCoverage');
424 var coverageList = coverage['coverage'];
425 assert(coverageList != null);
426 processCallSiteData(coverageList);
427 return this;
428 });
429 }
430 }
431
432 abstract class ServiceObjectOwner extends ServiceObject { 398 abstract class ServiceObjectOwner extends ServiceObject {
433 /// Creates an empty [ServiceObjectOwner]. 399 /// Creates an empty [ServiceObjectOwner].
434 ServiceObjectOwner._empty(ServiceObjectOwner owner) : super._empty(owner); 400 ServiceObjectOwner._empty(ServiceObjectOwner owner) : super._empty(owner);
435 401
436 /// Builds a [ServiceObject] corresponding to the [id] from [map]. 402 /// Builds a [ServiceObject] corresponding to the [id] from [map].
437 /// The result may come from the cache. The result will not necessarily 403 /// The result may come from the cache. The result will not necessarily
438 /// be [loaded]. 404 /// be [loaded].
439 ServiceObject getFromMap(ObservableMap map); 405 ServiceObject getFromMap(ObservableMap map);
440 } 406 }
441 407
(...skipping 686 matching lines...) Expand 10 before | Expand all | Expand 10 after
1128 print("${obj.runtimeType} should be a HeapObject"); 1094 print("${obj.runtimeType} should be a HeapObject");
1129 } 1095 }
1130 return obj; 1096 return obj;
1131 })); 1097 }));
1132 } 1098 }
1133 return result; 1099 return result;
1134 } 1100 }
1135 } 1101 }
1136 1102
1137 /// State for a running isolate. 1103 /// State for a running isolate.
1138 class Isolate extends ServiceObjectOwner with Coverage { 1104 class Isolate extends ServiceObjectOwner {
1139 static const kLoggingStream = '_Logging'; 1105 static const kLoggingStream = '_Logging';
1140 static const kExtensionStream = 'Extension'; 1106 static const kExtensionStream = 'Extension';
1141 1107
1142 @reflectable VM get vm => owner; 1108 @reflectable VM get vm => owner;
1143 @reflectable Isolate get isolate => this; 1109 @reflectable Isolate get isolate => this;
1144 @observable int number; 1110 @observable int number;
1145 @observable int originNumber; 1111 @observable int originNumber;
1146 @observable DateTime startTime; 1112 @observable DateTime startTime;
1147 @observable Duration get upTime { 1113 @observable Duration get upTime {
1148 if (startTime == null) { 1114 if (startTime == null) {
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
1187 if (value is Code) { 1153 if (value is Code) {
1188 Code code = value; 1154 Code code = value;
1189 code.profile = null; 1155 code.profile = null;
1190 } else if (value is ServiceFunction) { 1156 } else if (value is ServiceFunction) {
1191 ServiceFunction function = value; 1157 ServiceFunction function = value;
1192 function.profile = null; 1158 function.profile = null;
1193 } 1159 }
1194 }); 1160 });
1195 } 1161 }
1196 1162
1163 static const kCallSitesReport = '_CallSites';
1164
1165 Future<ServiceMap> getSourceReport(List<String> report_kinds,
1166 [Script script,
1167 int startPos,
1168 int endPos]) {
1169 var params = { 'reports' : report_kinds };
1170 if (script != null) {
1171 params['scriptId'] = script.id;
1172 }
1173 if (startPos != null) {
1174 params['tokenPos'] = startPos;
1175 }
1176 if (endPos != null) {
1177 params['endTokenPos'] = endPos;
1178 }
1179 return invokeRpc('_getSourceReport', params);
1180 }
1181
1197 /// Fetches and builds the class hierarchy for this isolate. Returns the 1182 /// Fetches and builds the class hierarchy for this isolate. Returns the
1198 /// Object class object. 1183 /// Object class object.
1199 Future<Class> getClassHierarchy() { 1184 Future<Class> getClassHierarchy() {
1200 return invokeRpc('getClassList', {}) 1185 return invokeRpc('getClassList', {})
1201 .then(_loadClasses) 1186 .then(_loadClasses)
1202 .then(_buildClassHierarchy); 1187 .then(_buildClassHierarchy);
1203 } 1188 }
1204 1189
1205 Future<ServiceObject> getPorts() { 1190 Future<ServiceObject> getPorts() {
1206 return invokeRpc('_getPorts', {}); 1191 return invokeRpc('_getPorts', {});
(...skipping 901 matching lines...) Expand 10 before | Expand all | Expand 10 after
2108 2093
2109 LibraryDependency._(this.isImport, this.isDeferred, this.prefix, this.target); 2094 LibraryDependency._(this.isImport, this.isDeferred, this.prefix, this.target);
2110 2095
2111 static _fromMap(map) => new LibraryDependency._(map["isImport"], 2096 static _fromMap(map) => new LibraryDependency._(map["isImport"],
2112 map["isDeferred"], 2097 map["isDeferred"],
2113 map["prefix"], 2098 map["prefix"],
2114 map["target"]); 2099 map["target"]);
2115 } 2100 }
2116 2101
2117 2102
2118 class Library extends HeapObject with Coverage { 2103 class Library extends HeapObject {
2119 @observable String uri; 2104 @observable String uri;
2120 @reflectable final dependencies = new ObservableList<LibraryDependency>(); 2105 @reflectable final dependencies = new ObservableList<LibraryDependency>();
2121 @reflectable final scripts = new ObservableList<Script>(); 2106 @reflectable final scripts = new ObservableList<Script>();
2122 @reflectable final classes = new ObservableList<Class>(); 2107 @reflectable final classes = new ObservableList<Class>();
2123 @reflectable final variables = new ObservableList<Field>(); 2108 @reflectable final variables = new ObservableList<Field>();
2124 @reflectable final functions = new ObservableList<ServiceFunction>(); 2109 @reflectable final functions = new ObservableList<ServiceFunction>();
2125 2110
2126 bool get canCache => true; 2111 bool get canCache => true;
2127 bool get immutable => false; 2112 bool get immutable => false;
2128 2113
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
2206 void update(List stats) { 2191 void update(List stats) {
2207 accumulated.instances = stats[ACCUMULATED]; 2192 accumulated.instances = stats[ACCUMULATED];
2208 accumulated.bytes = stats[ACCUMULATED_SIZE]; 2193 accumulated.bytes = stats[ACCUMULATED_SIZE];
2209 current.instances = stats[LIVE_AFTER_GC] + stats[ALLOCATED_SINCE_GC]; 2194 current.instances = stats[LIVE_AFTER_GC] + stats[ALLOCATED_SINCE_GC];
2210 current.bytes = stats[LIVE_AFTER_GC_SIZE] + stats[ALLOCATED_SINCE_GC_SIZE]; 2195 current.bytes = stats[LIVE_AFTER_GC_SIZE] + stats[ALLOCATED_SINCE_GC_SIZE];
2211 } 2196 }
2212 2197
2213 bool get empty => accumulated.empty && current.empty; 2198 bool get empty => accumulated.empty && current.empty;
2214 } 2199 }
2215 2200
2216 class Class extends HeapObject with Coverage { 2201 class Class extends HeapObject {
2217 @observable Library library; 2202 @observable Library library;
2218 2203
2219 @observable bool isAbstract; 2204 @observable bool isAbstract;
2220 @observable bool isConst; 2205 @observable bool isConst;
2221 @observable bool isFinalized; 2206 @observable bool isFinalized;
2222 @observable bool isPatch; 2207 @observable bool isPatch;
2223 @observable bool isImplemented; 2208 @observable bool isImplemented;
2224 2209
2225 @observable SourceLocation location; 2210 @observable SourceLocation location;
2226 2211
(...skipping 358 matching lines...) Expand 10 before | Expand all | Expand 10 after
2585 static FunctionKind kNoSuchMethodDispatcher = new FunctionKind._internal('noSu chMethod dispatcher'); 2570 static FunctionKind kNoSuchMethodDispatcher = new FunctionKind._internal('noSu chMethod dispatcher');
2586 static FunctionKind kInvokeFieldDispatcher = new FunctionKind._internal('invok e field dispatcher'); 2571 static FunctionKind kInvokeFieldDispatcher = new FunctionKind._internal('invok e field dispatcher');
2587 static FunctionKind kCollected = new FunctionKind._internal('Collected'); 2572 static FunctionKind kCollected = new FunctionKind._internal('Collected');
2588 static FunctionKind kNative = new FunctionKind._internal('Native'); 2573 static FunctionKind kNative = new FunctionKind._internal('Native');
2589 static FunctionKind kTag = new FunctionKind._internal('Tag'); 2574 static FunctionKind kTag = new FunctionKind._internal('Tag');
2590 static FunctionKind kStub = new FunctionKind._internal('Stub'); 2575 static FunctionKind kStub = new FunctionKind._internal('Stub');
2591 static FunctionKind kSignatureFunction = new FunctionKind._internal('Signature Function'); 2576 static FunctionKind kSignatureFunction = new FunctionKind._internal('Signature Function');
2592 static FunctionKind kUNKNOWN = new FunctionKind._internal('UNKNOWN'); 2577 static FunctionKind kUNKNOWN = new FunctionKind._internal('UNKNOWN');
2593 } 2578 }
2594 2579
2595 class ServiceFunction extends HeapObject with Coverage { 2580 class ServiceFunction extends HeapObject {
2596 // owner is a Library, Class, or ServiceFunction. 2581 // owner is a Library, Class, or ServiceFunction.
2597 @observable ServiceObject dartOwner; 2582 @observable ServiceObject dartOwner;
2598 @observable Library library; 2583 @observable Library library;
2599 @observable bool isStatic; 2584 @observable bool isStatic;
2600 @observable bool isConst; 2585 @observable bool isConst;
2601 @observable SourceLocation location; 2586 @observable SourceLocation location;
2602 @observable Code code; 2587 @observable Code code;
2603 @observable Code unoptimizedCode; 2588 @observable Code unoptimizedCode;
2604 @observable bool isOptimizable; 2589 @observable bool isOptimizable;
2605 @observable bool isInlinable; 2590 @observable bool isInlinable;
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
2731 } 2716 }
2732 2717
2733 String toString() => 'Field(${dartOwner.name}.$name)'; 2718 String toString() => 'Field(${dartOwner.name}.$name)';
2734 } 2719 }
2735 2720
2736 2721
2737 class ScriptLine extends Observable { 2722 class ScriptLine extends Observable {
2738 final Script script; 2723 final Script script;
2739 final int line; 2724 final int line;
2740 final String text; 2725 final String text;
2741 @observable int hits;
2742 @observable bool possibleBpt = true; 2726 @observable bool possibleBpt = true;
2743 @observable bool breakpointResolved = false; 2727 @observable bool breakpointResolved = false;
2744 @observable Set<Breakpoint> breakpoints; 2728 @observable Set<Breakpoint> breakpoints;
2745 2729
2746 bool get isBlank { 2730 bool get isBlank {
2747 // Compute isBlank on demand. 2731 // Compute isBlank on demand.
2748 if (_isBlank == null) { 2732 if (_isBlank == null) {
2749 _isBlank = text.trim().isEmpty; 2733 _isBlank = text.trim().isEmpty;
2750 } 2734 }
2751 return _isBlank; 2735 return _isBlank;
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
2843 2827
2844 operator ==(other) { 2828 operator ==(other) {
2845 return (script == other.script) && (tokenPos == other.tokenPos); 2829 return (script == other.script) && (tokenPos == other.tokenPos);
2846 } 2830 }
2847 int get hashCode => (script.hashCode << 8) | tokenPos; 2831 int get hashCode => (script.hashCode << 8) | tokenPos;
2848 2832
2849 String toString() => "CallSite($name, $tokenPos)"; 2833 String toString() => "CallSite($name, $tokenPos)";
2850 } 2834 }
2851 2835
2852 class CallSiteEntry { 2836 class CallSiteEntry {
2853 final /* Class | Library */ receiverContainer; 2837 final /* Class | Library */ receiver;
2854 final int count; 2838 final int count;
2855 final ServiceFunction target; 2839 final ServiceFunction target;
2856 2840
2857 CallSiteEntry(this.receiverContainer, this.count, this.target); 2841 CallSiteEntry(this.receiver, this.count, this.target);
2858 2842
2859 factory CallSiteEntry.fromMap(Map entryMap) { 2843 factory CallSiteEntry.fromMap(Map entryMap) {
2860 return new CallSiteEntry(entryMap['receiverContainer'], 2844 return new CallSiteEntry(entryMap['receiver'],
2861 entryMap['count'], 2845 entryMap['count'],
2862 entryMap['target']); 2846 entryMap['target']);
2863 } 2847 }
2864 2848
2865 String toString() => "CallSiteEntry(${receiverContainer.name}, $count)"; 2849 String toString() => "CallSiteEntry(${receiver.name}, $count)";
2866 } 2850 }
2867 2851
2868 /// The location of a local variable reference in a script. 2852 /// The location of a local variable reference in a script.
2869 class LocalVarLocation { 2853 class LocalVarLocation {
2870 final int line; 2854 final int line;
2871 final int column; 2855 final int column;
2872 final int endColumn; 2856 final int endColumn;
2873 LocalVarLocation(this.line, this.column, this.endColumn); 2857 LocalVarLocation(this.line, this.column, this.endColumn);
2874 } 2858 }
2875 2859
2876 class Script extends HeapObject with Coverage { 2860 class Script extends HeapObject {
2877 Set<CallSite> callSites = new Set<CallSite>();
2878 final lines = new ObservableList<ScriptLine>(); 2861 final lines = new ObservableList<ScriptLine>();
2879 final _hits = new Map<int, int>();
2880 @observable String uri; 2862 @observable String uri;
2881 @observable String kind; 2863 @observable String kind;
2882 @observable int firstTokenPos; 2864 @observable int firstTokenPos;
2883 @observable int lastTokenPos; 2865 @observable int lastTokenPos;
2884 @observable int lineOffset; 2866 @observable int lineOffset;
2885 @observable int columnOffset; 2867 @observable int columnOffset;
2886 @observable Library library; 2868 @observable Library library;
2887 2869
2888 bool get immutable => true; 2870 bool get immutable => true;
2889 2871
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
3023 } 3005 }
3024 3006
3025 for (var line in lines) { 3007 for (var line in lines) {
3026 // Remove possible breakpoints on lines with no tokens. 3008 // Remove possible breakpoints on lines with no tokens.
3027 if (!lineSet.contains(line.line)) { 3009 if (!lineSet.contains(line.line)) {
3028 line.possibleBpt = false; 3010 line.possibleBpt = false;
3029 } 3011 }
3030 } 3012 }
3031 } 3013 }
3032 3014
3033 void _processCallSites(List newCallSiteMaps) {
3034 var mergedCallSites = new Set<CallSite>();
3035 for (var callSiteMap in newCallSiteMaps) {
3036 var newSite = new CallSite.fromMap(callSiteMap, this);
3037 mergedCallSites.add(newSite);
3038
3039 var line = newSite.line;
3040 var hit = newSite.aggregateCount;
3041 assert(line >= 1); // Lines start at 1.
3042 var oldHits = _hits[line];
3043 if (oldHits != null) {
3044 hit += oldHits;
3045 }
3046 _hits[line] = hit;
3047 }
3048
3049 mergedCallSites.addAll(callSites);
3050 callSites = mergedCallSites;
3051 _applyHitsToLines();
3052 // Notify any Observers that this Script's state has changed.
3053 notifyChange(null);
3054 }
3055
3056 void _processSource(String source) { 3015 void _processSource(String source) {
3057 if (source == null) { 3016 if (source == null) {
3058 return; 3017 return;
3059 } 3018 }
3060 var sourceLines = source.split('\n'); 3019 var sourceLines = source.split('\n');
3061 if (sourceLines.length == 0) { 3020 if (sourceLines.length == 0) {
3062 return; 3021 return;
3063 } 3022 }
3064 lines.clear(); 3023 lines.clear();
3065 Logger.root.info('Adding ${sourceLines.length} source lines for ${uri}'); 3024 Logger.root.info('Adding ${sourceLines.length} source lines for ${uri}');
3066 for (var i = 0; i < sourceLines.length; i++) { 3025 for (var i = 0; i < sourceLines.length; i++) {
3067 lines.add(new ScriptLine(this, i + lineOffset + 1, sourceLines[i])); 3026 lines.add(new ScriptLine(this, i + lineOffset + 1, sourceLines[i]));
3068 } 3027 }
3069 for (var bpt in isolate.breakpoints.values) { 3028 for (var bpt in isolate.breakpoints.values) {
3070 if (bpt.location.script == this) { 3029 if (bpt.location.script == this) {
3071 _addBreakpoint(bpt); 3030 _addBreakpoint(bpt);
3072 } 3031 }
3073 } 3032 }
3074 3033
3075 _applyHitsToLines();
3076 // Notify any Observers that this Script's state has changed. 3034 // Notify any Observers that this Script's state has changed.
3077 notifyChange(null); 3035 notifyChange(null);
3078 } 3036 }
3079 3037
3080 void _applyHitsToLines() {
3081 for (var line in lines) {
3082 var hits = _hits[line.line];
3083 line.hits = hits;
3084 }
3085 }
3086
3087 void _addBreakpoint(Breakpoint bpt) { 3038 void _addBreakpoint(Breakpoint bpt) {
3088 var line; 3039 var line;
3089 if (bpt.location.tokenPos != null) { 3040 if (bpt.location.tokenPos != null) {
3090 line = tokenToLine(bpt.location.tokenPos); 3041 line = tokenToLine(bpt.location.tokenPos);
3091 } else { 3042 } else {
3092 UnresolvedSourceLocation loc = bpt.location; 3043 UnresolvedSourceLocation loc = bpt.location;
3093 line = loc.line; 3044 line = loc.line;
3094 } 3045 }
3095 getLine(line).addBreakpoint(bpt); 3046 getLine(line).addBreakpoint(bpt);
3096 } 3047 }
(...skipping 968 matching lines...) Expand 10 before | Expand all | Expand 10 after
4065 var v = list[i]; 4016 var v = list[i];
4066 if ((v is ObservableMap) && _isServiceMap(v)) { 4017 if ((v is ObservableMap) && _isServiceMap(v)) {
4067 list[i] = owner.getFromMap(v); 4018 list[i] = owner.getFromMap(v);
4068 } else if (v is ObservableList) { 4019 } else if (v is ObservableList) {
4069 _upgradeObservableList(v, owner); 4020 _upgradeObservableList(v, owner);
4070 } else if (v is ObservableMap) { 4021 } else if (v is ObservableMap) {
4071 _upgradeObservableMap(v, owner); 4022 _upgradeObservableMap(v, owner);
4072 } 4023 }
4073 } 4024 }
4074 } 4025 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698