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 namespace v8 { 9 namespace internal { 10 11 // The compilation cache consists of several generational sub-caches which uses 12 // this class as a base class. A sub-cache contains a compilation cache tables 13 // for each generation of the sub-cache. Since the same source code string has 14 // different compiled code for scripts and evals, we use separate sub-caches 15 // for different compilation modes, to avoid retrieving the wrong result. 16 class CompilationSubCache { 17 public: 18 CompilationSubCache(Isolate* isolate, int generations) 19 : isolate_(isolate), 20 generations_(generations) { 21 tables_ = NewArray<Object*>(generations); 22 } 23 24 ~CompilationSubCache() { DeleteArray(tables_); } 25 26 // Index for the first generation in the cache. 27 static const int kFirstGeneration = 0; 28 29 // Get the compilation cache tables for a specific generation. 30 Handle<CompilationCacheTable> GetTable(int generation); 31 32 // Accessors for first generation. 33 Handle<CompilationCacheTable> GetFirstTable() { 34 return GetTable(kFirstGeneration); 35 } 36 void SetFirstTable(Handle<CompilationCacheTable> value) { 37 ASSERT(kFirstGeneration < generations_); 38 tables_[kFirstGeneration] = *value; 39 } 40 41 // Age the sub-cache by evicting the oldest generation and creating a new 42 // young generation. 43 void Age(); 44 45 // GC support. 46 void Iterate(ObjectVisitor* v); 47 void IterateFunctions(ObjectVisitor* v); 48 49 // Clear this sub-cache evicting all its content. 50 void Clear(); 51 52 // Remove given shared function info from sub-cache. 53 void Remove(Handle<SharedFunctionInfo> function_info); 54 55 // Number of generations in this sub-cache. 56 inline int generations() { return generations_; } 57 58 protected: 59 Isolate* isolate() { return isolate_; } 60 61 private: 62 Isolate* isolate_; 63 int generations_; // Number of generations. 64 Object** tables_; // Compilation cache tables - one for each generation. 65 66 DISALLOW_IMPLICIT_CONSTRUCTORS(CompilationSubCache); 67 }; 68 69 70 // Sub-cache for scripts. 71 class CompilationCacheScript : public CompilationSubCache { 72 public: 73 CompilationCacheScript(Isolate* isolate, int generations); 74 75 Handle<SharedFunctionInfo> Lookup(Handle<String> source, 76 Handle<Object> name, 77 int line_offset, 78 int column_offset, 79 bool is_shared_cross_origin, 80 Handle<Context> context); 81 void Put(Handle<String> source, 82 Handle<Context> context, 83 Handle<SharedFunctionInfo> function_info); 84 85 private: 86 bool HasOrigin(Handle<SharedFunctionInfo> function_info, 87 Handle<Object> name, 88 int line_offset, 89 int column_offset, 90 bool is_shared_cross_origin); 91 92 void* script_histogram_; 93 bool script_histogram_initialized_; 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: 113 CompilationCacheEval(Isolate* isolate, int generations) 114 : CompilationSubCache(isolate, generations) { } 115 116 MaybeHandle<SharedFunctionInfo> Lookup(Handle<String> source, 117 Handle<Context> context, 118 StrictMode strict_mode, 119 int scope_position); 120 121 void Put(Handle<String> source, 122 Handle<Context> context, 123 Handle<SharedFunctionInfo> function_info, 124 int scope_position); 125 126 private: 127 DISALLOW_IMPLICIT_CONSTRUCTORS(CompilationCacheEval); 128 }; 129 130 131 // Sub-cache for regular expressions. 132 class CompilationCacheRegExp: public CompilationSubCache { 133 public: 134 CompilationCacheRegExp(Isolate* isolate, int generations) 135 : CompilationSubCache(isolate, generations) { } 136 137 MaybeHandle<FixedArray> Lookup(Handle<String> source, JSRegExp::Flags flags); 138 139 void Put(Handle<String> source, 140 JSRegExp::Flags flags, 141 Handle<FixedArray> data); 142 private: 143 DISALLOW_IMPLICIT_CONSTRUCTORS(CompilationCacheRegExp); 144 }; 145 146 147 // The compilation cache keeps shared function infos for compiled 148 // scripts and evals. The shared function infos are looked up using 149 // the source string as the key. For regular expressions the 150 // compilation data is cached. 151 class CompilationCache { 152 public: 153 // Finds the script shared function info for a source 154 // string. Returns an empty handle if the cache doesn't contain a 155 // script for the given source string with the right origin. 156 MaybeHandle<SharedFunctionInfo> LookupScript( 157 Handle<String> source, Handle<Object> name, int line_offset, 158 int column_offset, bool is_shared_cross_origin, Handle<Context> context); 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 MaybeHandle<SharedFunctionInfo> LookupEval( 164 Handle<String> source, Handle<Context> context, StrictMode strict_mode, 165 int scope_position); 166 167 // Returns the regexp data associated with the given regexp if it 168 // is in cache, otherwise an empty handle. 169 MaybeHandle<FixedArray> LookupRegExp( 170 Handle<String> source, JSRegExp::Flags flags); 171 172 // Associate the (source, kind) pair to the shared function 173 // info. This may overwrite an existing mapping. 174 void PutScript(Handle<String> source, 175 Handle<Context> context, 176 Handle<SharedFunctionInfo> function_info); 177 178 // Associate the (source, context->closure()->shared(), kind) triple 179 // with the shared function info. This may overwrite an existing mapping. 180 void PutEval(Handle<String> source, 181 Handle<Context> context, 182 Handle<SharedFunctionInfo> function_info, 183 int scope_position); 184 185 // Associate the (source, flags) pair to the given regexp data. 186 // This may overwrite an existing mapping. 187 void PutRegExp(Handle<String> source, 188 JSRegExp::Flags flags, 189 Handle<FixedArray> data); 190 191 // Clear the cache - also used to initialize the cache at startup. 192 void Clear(); 193 194 // Remove given shared function info from all caches. 195 void Remove(Handle<SharedFunctionInfo> function_info); 196 197 // GC support. 198 void Iterate(ObjectVisitor* v); 199 void IterateFunctions(ObjectVisitor* v); 200 201 // Notify the cache that a mark-sweep garbage collection is about to 202 // take place. This is used to retire entries from the cache to 203 // avoid keeping them alive too long without using them. 204 void MarkCompactPrologue(); 205 206 // Enable/disable compilation cache. Used by debugger to disable compilation 207 // cache during debugging to make sure new scripts are always compiled. 208 void Enable(); 209 void Disable(); 210 211 private: 212 explicit CompilationCache(Isolate* isolate); 213 ~CompilationCache(); 214 215 HashMap* EagerOptimizingSet(); 216 217 // The number of sub caches covering the different types to cache. 218 static const int kSubCacheCount = 4; 219 220 bool IsEnabled() { return FLAG_compilation_cache && enabled_; } 221 222 Isolate* isolate() { return isolate_; } 223 224 Isolate* isolate_; 225 226 CompilationCacheScript script_; 227 CompilationCacheEval eval_global_; 228 CompilationCacheEval eval_contextual_; 229 CompilationCacheRegExp reg_exp_; 230 CompilationSubCache* subcaches_[kSubCacheCount]; 231 232 // Current enable state of the compilation cache. 233 bool enabled_; 234 235 friend class Isolate; 236 237 DISALLOW_COPY_AND_ASSIGN(CompilationCache); 238 }; 239 240 241 } } // namespace v8::internal 242 243 #endif // V8_COMPILATION_CACHE_H_ 244