| OLD | NEW |
| (Empty) |
| 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 | |
| 3 // BSD-style license that can be found in the LICENSE file. | |
| 4 | |
| 5 part of service; | |
| 6 | |
| 7 /// Abstract [ServiceObjectCache]. | |
| 8 abstract class ServiceObjectCache<T extends ServiceObject> { | |
| 9 final Isolate isolate; | |
| 10 final _cache = new ObservableMap<String, T>(); | |
| 11 | |
| 12 ServiceObjectCache(this.isolate) { | |
| 13 assert(isolate != null); | |
| 14 } | |
| 15 | |
| 16 /// Returns true if [this] caches objects with this [id]. | |
| 17 bool cachesId(String id); | |
| 18 | |
| 19 /// Upgrades [obj] into a [T]. | |
| 20 T _upgrade(ObservableMap map); | |
| 21 | |
| 22 /// Returns true if [this] has [id] in its cache. | |
| 23 bool contains(String id) { | |
| 24 assert(cachesId(id)); | |
| 25 return _cache[id] != null; | |
| 26 } | |
| 27 | |
| 28 /// Gets [id] from the cache. Returns null if not contained. | |
| 29 T operator[](String id) { | |
| 30 assert(cachesId(id)); | |
| 31 return _cache[id]; | |
| 32 } | |
| 33 | |
| 34 /// Caches [serviceObject] with [id]. | |
| 35 operator[]=(String id, T serviceObject) { | |
| 36 assert(cachesId(id)); | |
| 37 _cache[id] = serviceObject; | |
| 38 } | |
| 39 | |
| 40 /// Gets [id] from the cache or makes a network request for [id]. | |
| 41 Future<T> get(String id) { | |
| 42 assert(cachesId(id)); | |
| 43 T cached = _cache[id]; | |
| 44 if (cached != null) { | |
| 45 return cached.load(); | |
| 46 } | |
| 47 return isolate.getDirect(id); | |
| 48 } | |
| 49 | |
| 50 /// If [obj] is cached, return the cached object. Otherwise, upgrades [obj] | |
| 51 /// and adds the upgraded value to the cache. | |
| 52 T putIfAbsent(ObservableMap obj) { | |
| 53 assert(ServiceObject.isServiceMap(obj)); | |
| 54 String id = obj['id']; | |
| 55 var type = obj['type']; | |
| 56 if (!cachesId(id)) { | |
| 57 Logger.root.warning('Cache does not cache this id: $id'); | |
| 58 } | |
| 59 assert(cachesId(id)); | |
| 60 if (contains(id)) { | |
| 61 return this[id]; | |
| 62 } | |
| 63 return _addToCache(_upgrade(obj)); | |
| 64 } | |
| 65 | |
| 66 T _addToCache(T so) { | |
| 67 this[so.id] = so; | |
| 68 return so; | |
| 69 } | |
| 70 } | |
| 71 | |
| 72 class ScriptCache extends ServiceObjectCache<Script> { | |
| 73 ScriptCache(Isolate isolate) : super(isolate); | |
| 74 | |
| 75 bool cachesId(String id) => _matcher.hasMatch(id); | |
| 76 Script _upgrade(ObservableMap obj) => new Script.fromMap(isolate, obj); | |
| 77 static final RegExp _matcher = new RegExp(r'^scripts/.+'); | |
| 78 | |
| 79 void _processCoverage(ServiceMap coverage) { | |
| 80 assert(coverage.serviceType == 'CodeCoverage'); | |
| 81 var coverageList = coverage['coverage']; | |
| 82 assert(coverageList != null); | |
| 83 coverageList.forEach((scriptCoverage) { | |
| 84 _processScriptCoverage(scriptCoverage); | |
| 85 }); | |
| 86 } | |
| 87 | |
| 88 void _processScriptCoverage(ObservableMap scriptCoverage) { | |
| 89 // Because the coverage data was upgraded into a ServiceObject, | |
| 90 // the script can be directly accessed. | |
| 91 Script script = scriptCoverage['script']; | |
| 92 script._processHits(scriptCoverage['hits']); | |
| 93 } | |
| 94 } | |
| 95 | |
| 96 class CodeCache extends ServiceObjectCache<Code> { | |
| 97 CodeCache(Isolate isolate) : super(isolate); | |
| 98 | |
| 99 bool cachesId(String id) => _matcher.hasMatch(id); | |
| 100 Code _upgrade(ObservableMap obj) => new Code.fromMap(isolate, obj); | |
| 101 | |
| 102 static final RegExp _matcher = new RegExp(r'^code/.+'); | |
| 103 | |
| 104 List<Code> topExclusive(int count) { | |
| 105 var codeList = _cache.values.toList(); | |
| 106 codeList.sort((Code a, Code b) { | |
| 107 return b.exclusiveTicks - a.exclusiveTicks; | |
| 108 }); | |
| 109 if (codeList.length < count) { | |
| 110 return codeList; | |
| 111 } | |
| 112 codeList.length = count; | |
| 113 return codeList; | |
| 114 } | |
| 115 | |
| 116 static const TAG_ROOT_ID = 'code/tag-0'; | |
| 117 | |
| 118 /// Returns the Code object for the root tag. | |
| 119 Code tagRoot() { | |
| 120 return _cache[TAG_ROOT_ID]; | |
| 121 } | |
| 122 | |
| 123 void _resetProfileData() { | |
| 124 _cache.forEach((k, Code code) { | |
| 125 code.resetProfileData(); | |
| 126 }); | |
| 127 } | |
| 128 | |
| 129 void _updateProfileData(ServiceMap profile, List<Code> codeTable) { | |
| 130 var codeRegions = profile['codes']; | |
| 131 var sampleCount = profile['samples']; | |
| 132 for (var codeRegion in codeRegions) { | |
| 133 Code code = codeRegion['code']; | |
| 134 code.updateProfileData(codeRegion, codeTable, sampleCount); | |
| 135 } | |
| 136 } | |
| 137 } | |
| 138 | |
| 139 class ClassCache extends ServiceObjectCache<ServiceMap> { | |
| 140 ClassCache(Isolate isolate) : super(isolate); | |
| 141 | |
| 142 bool cachesId(String id) => _matcher.hasMatch(id); | |
| 143 bool cachesType(String type) => ServiceObject.stripRef(type) == 'Class'; | |
| 144 ServiceMap _upgrade(ObservableMap obj) => | |
| 145 new ServiceMap.fromMap(isolate, obj); | |
| 146 | |
| 147 static final RegExp _matcher = new RegExp(r'^classes/\d+$'); | |
| 148 } | |
| 149 | |
| 150 class FunctionCache extends ServiceObjectCache<ServiceMap> { | |
| 151 FunctionCache(Isolate isolate) : super(isolate); | |
| 152 | |
| 153 bool cachesId(String id) => _matcher.hasMatch(id); | |
| 154 | |
| 155 bool cachesType(String type) => ServiceObject.stripRef(type) == 'Function'; | |
| 156 ServiceMap _upgrade(ObservableMap obj) => | |
| 157 new ServiceMap.fromMap(isolate, obj); | |
| 158 | |
| 159 static final RegExp _matcher = | |
| 160 new RegExp(r'^functions/native-.+|' | |
| 161 r'^functions/collected-.+|' | |
| 162 r'^functions/reused-.+|' | |
| 163 r'^functions/stub-.+|' | |
| 164 r'^functions/tag-.+|' | |
| 165 r'^classes/\d+/functions/.+|' | |
| 166 r'^classes/\d+/closures/.+|' | |
| 167 r'^classes/\d+/implicit_closures/.+|' | |
| 168 r'^classes/\d+/dispatchers/.+'); | |
| 169 } | |
| OLD | NEW |