1 // Copyright 2012 the V8 project authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef V8_COMPILATION_CACHE_H_ 6 #define V8_COMPILATION_CACHE_H_ 7 8 #include "src/allocation.h" 9 #include "src/objects.h" 10 11 namespace v8 { 12 namespace internal { 13 14 template <typename T> 15 class Handle; 16 17 // The compilation cache consists of several generational sub-caches which uses 18 // this class as a base class. A sub-cache contains a compilation cache tables 19 // for each generation of the sub-cache. Since the same source code string has 20 // different compiled code for scripts and evals, we use separate sub-caches 21 // for different compilation modes, to avoid retrieving the wrong result. 22 class CompilationSubCache { 23 public: CompilationSubCache(Isolate * isolate,int generations)24 CompilationSubCache(Isolate* isolate, int generations) 25 : isolate_(isolate), 26 generations_(generations) { 27 tables_ = NewArray<Object*>(generations); 28 } 29 ~CompilationSubCache()30 ~CompilationSubCache() { DeleteArray(tables_); } 31 32 // Index for the first generation in the cache. 33 static const int kFirstGeneration = 0; 34 35 // Get the compilation cache tables for a specific generation. 36 Handle<CompilationCacheTable> GetTable(int generation); 37 38 // Accessors for first generation. GetFirstTable()39 Handle<CompilationCacheTable> GetFirstTable() { 40 return GetTable(kFirstGeneration); 41 } SetFirstTable(Handle<CompilationCacheTable> value)42 void SetFirstTable(Handle<CompilationCacheTable> value) { 43 DCHECK(kFirstGeneration < generations_); 44 tables_[kFirstGeneration] = *value; 45 } 46 47 // Age the sub-cache by evicting the oldest generation and creating a new 48 // young generation. 49 void Age(); 50 51 // GC support. 52 void Iterate(ObjectVisitor* v); 53 void IterateFunctions(ObjectVisitor* v); 54 55 // Clear this sub-cache evicting all its content. 56 void Clear(); 57 58 // Remove given shared function info from sub-cache. 59 void Remove(Handle<SharedFunctionInfo> function_info); 60 61 // Number of generations in this sub-cache. generations()62 inline int generations() { return generations_; } 63 64 protected: isolate()65 Isolate* isolate() { return isolate_; } 66 67 private: 68 Isolate* isolate_; 69 int generations_; // Number of generations. 70 Object** tables_; // Compilation cache tables - one for each generation. 71 72 DISALLOW_IMPLICIT_CONSTRUCTORS(CompilationSubCache); 73 }; 74 75 76 // Sub-cache for scripts. 77 class CompilationCacheScript : public CompilationSubCache { 78 public: 79 explicit CompilationCacheScript(Isolate* isolate); 80 81 InfoVectorPair Lookup(Handle<String> source, Handle<Object> name, 82 int line_offset, int column_offset, 83 ScriptOriginOptions resource_options, 84 Handle<Context> context, LanguageMode language_mode); 85 86 void Put(Handle<String> source, Handle<Context> context, 87 LanguageMode language_mode, Handle<SharedFunctionInfo> function_info, 88 Handle<Cell> literals); 89 90 private: 91 bool HasOrigin(Handle<SharedFunctionInfo> function_info, Handle<Object> name, 92 int line_offset, int column_offset, 93 ScriptOriginOptions resource_options); 94 95 DISALLOW_IMPLICIT_CONSTRUCTORS(CompilationCacheScript); 96 }; 97 98 99 // Sub-cache for eval scripts. Two caches for eval are used. One for eval calls 100 // in native contexts and one for eval calls in other contexts. The cache 101 // considers the following pieces of information when checking for matching 102 // entries: 103 // 1. The source string. 104 // 2. The shared function info of the calling function. 105 // 3. Whether the source should be compiled as strict code or as sloppy code. 106 // Note: Currently there are clients of CompileEval that always compile 107 // sloppy code even if the calling function is a strict mode function. 108 // More specifically these are the CompileString, DebugEvaluate and 109 // DebugEvaluateGlobal runtime functions. 110 // 4. The start position of the calling scope. 111 class CompilationCacheEval: public CompilationSubCache { 112 public: CompilationCacheEval(Isolate * isolate)113 explicit CompilationCacheEval(Isolate* isolate) 114 : CompilationSubCache(isolate, 1) {} 115 116 InfoVectorPair Lookup(Handle<String> source, 117 Handle<SharedFunctionInfo> outer_info, 118 Handle<Context> native_context, 119 LanguageMode language_mode, int position); 120 121 void Put(Handle<String> source, Handle<SharedFunctionInfo> outer_info, 122 Handle<SharedFunctionInfo> function_info, 123 Handle<Context> native_context, Handle<Cell> literals, int position); 124 125 private: 126 DISALLOW_IMPLICIT_CONSTRUCTORS(CompilationCacheEval); 127 }; 128 129 130 // Sub-cache for regular expressions. 131 class CompilationCacheRegExp: public CompilationSubCache { 132 public: CompilationCacheRegExp(Isolate * isolate,int generations)133 CompilationCacheRegExp(Isolate* isolate, int generations) 134 : CompilationSubCache(isolate, generations) { } 135 136 MaybeHandle<FixedArray> Lookup(Handle<String> source, JSRegExp::Flags flags); 137 138 void Put(Handle<String> source, 139 JSRegExp::Flags flags, 140 Handle<FixedArray> data); 141 private: 142 DISALLOW_IMPLICIT_CONSTRUCTORS(CompilationCacheRegExp); 143 }; 144 145 // The compilation cache keeps shared function infos for compiled 146 // scripts and evals. The shared function infos are looked up using 147 // the source string as the key. For regular expressions the 148 // compilation data is cached. 149 class CompilationCache { 150 public: 151 // Finds the script shared function info for a source 152 // string. Returns an empty handle if the cache doesn't contain a 153 // script for the given source string with the right origin. 154 InfoVectorPair LookupScript(Handle<String> source, Handle<Object> name, 155 int line_offset, int column_offset, 156 ScriptOriginOptions resource_options, 157 Handle<Context> context, 158 LanguageMode language_mode); 159 160 // Finds the shared function info for a source string for eval in a 161 // given context. Returns an empty handle if the cache doesn't 162 // contain a script for the given source string. 163 InfoVectorPair LookupEval(Handle<String> source, 164 Handle<SharedFunctionInfo> outer_info, 165 Handle<Context> context, LanguageMode language_mode, 166 int position); 167 168 // Returns the regexp data associated with the given regexp if it 169 // is in cache, otherwise an empty handle. 170 MaybeHandle<FixedArray> LookupRegExp( 171 Handle<String> source, JSRegExp::Flags flags); 172 173 // Associate the (source, kind) pair to the shared function 174 // info. This may overwrite an existing mapping. 175 void PutScript(Handle<String> source, Handle<Context> context, 176 LanguageMode language_mode, 177 Handle<SharedFunctionInfo> function_info, 178 Handle<Cell> literals); 179 180 // Associate the (source, context->closure()->shared(), kind) triple 181 // with the shared function info. This may overwrite an existing mapping. 182 void PutEval(Handle<String> source, Handle<SharedFunctionInfo> outer_info, 183 Handle<Context> context, 184 Handle<SharedFunctionInfo> function_info, Handle<Cell> literals, 185 int position); 186 187 // Associate the (source, flags) pair to the given regexp data. 188 // This may overwrite an existing mapping. 189 void PutRegExp(Handle<String> source, 190 JSRegExp::Flags flags, 191 Handle<FixedArray> data); 192 193 // Clear the cache - also used to initialize the cache at startup. 194 void Clear(); 195 196 // Remove given shared function info from all caches. 197 void Remove(Handle<SharedFunctionInfo> function_info); 198 199 // GC support. 200 void Iterate(ObjectVisitor* v); 201 void IterateFunctions(ObjectVisitor* v); 202 203 // Notify the cache that a mark-sweep garbage collection is about to 204 // take place. This is used to retire entries from the cache to 205 // avoid keeping them alive too long without using them. 206 void MarkCompactPrologue(); 207 208 // Enable/disable compilation cache. Used by debugger to disable compilation 209 // cache during debugging to make sure new scripts are always compiled. 210 void Enable(); 211 void Disable(); 212 213 private: 214 explicit CompilationCache(Isolate* isolate); 215 ~CompilationCache(); 216 217 base::HashMap* EagerOptimizingSet(); 218 219 // The number of sub caches covering the different types to cache. 220 static const int kSubCacheCount = 4; 221 IsEnabled()222 bool IsEnabled() { return FLAG_compilation_cache && enabled_; } 223 isolate()224 Isolate* isolate() { return isolate_; } 225 226 Isolate* isolate_; 227 228 CompilationCacheScript script_; 229 CompilationCacheEval eval_global_; 230 CompilationCacheEval eval_contextual_; 231 CompilationCacheRegExp reg_exp_; 232 CompilationSubCache* subcaches_[kSubCacheCount]; 233 234 // Current enable state of the compilation cache. 235 bool enabled_; 236 237 friend class Isolate; 238 239 DISALLOW_COPY_AND_ASSIGN(CompilationCache); 240 }; 241 242 243 } // namespace internal 244 } // namespace v8 245 246 #endif // V8_COMPILATION_CACHE_H_ 247