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.
5 #ifndef V8_COMPILATION_CACHE_H_
6 #define V8_COMPILATION_CACHE_H_
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 {
18 CompilationSubCache(Isolate* isolate, int generations)
20 generations_(generations) {
21 tables_ = NewArray<Object*>(generations);
24 ~CompilationSubCache() { DeleteArray(tables_); }
26 // Index for the first generation in the cache.
27 static const int kFirstGeneration = 0;
29 // Get the compilation cache tables for a specific generation.
30 Handle<CompilationCacheTable> GetTable(int generation);
32 // Accessors for first generation.
33 Handle<CompilationCacheTable> GetFirstTable() {
34 return GetTable(kFirstGeneration);
36 void SetFirstTable(Handle<CompilationCacheTable> value) {
37 ASSERT(kFirstGeneration < generations_);
38 tables_[kFirstGeneration] = *value;
41 // Age the sub-cache by evicting the oldest generation and creating a new
46 void Iterate(ObjectVisitor* v);
47 void IterateFunctions(ObjectVisitor* v);
49 // Clear this sub-cache evicting all its content.
52 // Remove given shared function info from sub-cache.
53 void Remove(Handle<SharedFunctionInfo> function_info);
55 // Number of generations in this sub-cache.
56 inline int generations() { return generations_; }
59 Isolate* isolate() { return isolate_; }
63 int generations_; // Number of generations.
64 Object** tables_; // Compilation cache tables - one for each generation.
66 DISALLOW_IMPLICIT_CONSTRUCTORS(CompilationSubCache);
70 // Sub-cache for scripts.
71 class CompilationCacheScript : public CompilationSubCache {
73 CompilationCacheScript(Isolate* isolate, int generations);
75 Handle<SharedFunctionInfo> Lookup(Handle<String> source,
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);
86 bool HasOrigin(Handle<SharedFunctionInfo> function_info,
90 bool is_shared_cross_origin);
92 void* script_histogram_;
93 bool script_histogram_initialized_;
95 DISALLOW_IMPLICIT_CONSTRUCTORS(CompilationCacheScript);
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
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 {
113 CompilationCacheEval(Isolate* isolate, int generations)
114 : CompilationSubCache(isolate, generations) { }
116 MaybeHandle<SharedFunctionInfo> Lookup(Handle<String> source,
117 Handle<Context> context,
118 StrictMode strict_mode,
121 void Put(Handle<String> source,
122 Handle<Context> context,
123 Handle<SharedFunctionInfo> function_info,
127 DISALLOW_IMPLICIT_CONSTRUCTORS(CompilationCacheEval);
131 // Sub-cache for regular expressions.
132 class CompilationCacheRegExp: public CompilationSubCache {
134 CompilationCacheRegExp(Isolate* isolate, int generations)
135 : CompilationSubCache(isolate, generations) { }
137 MaybeHandle<FixedArray> Lookup(Handle<String> source, JSRegExp::Flags flags);
139 void Put(Handle<String> source,
140 JSRegExp::Flags flags,
141 Handle<FixedArray> data);
143 DISALLOW_IMPLICIT_CONSTRUCTORS(CompilationCacheRegExp);
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 {
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);
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,
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);
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);
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,
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);
191 // Clear the cache - also used to initialize the cache at startup.
194 // Remove given shared function info from all caches.
195 void Remove(Handle<SharedFunctionInfo> function_info);
198 void Iterate(ObjectVisitor* v);
199 void IterateFunctions(ObjectVisitor* v);
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();
206 // Enable/disable compilation cache. Used by debugger to disable compilation
207 // cache during debugging to make sure new scripts are always compiled.
212 explicit CompilationCache(Isolate* isolate);
215 HashMap* EagerOptimizingSet();
217 // The number of sub caches covering the different types to cache.
218 static const int kSubCacheCount = 4;
220 bool IsEnabled() { return FLAG_compilation_cache && enabled_; }
222 Isolate* isolate() { return isolate_; }
226 CompilationCacheScript script_;
227 CompilationCacheEval eval_global_;
228 CompilationCacheEval eval_contextual_;
229 CompilationCacheRegExp reg_exp_;
230 CompilationSubCache* subcaches_[kSubCacheCount];
232 // Current enable state of the compilation cache.
235 friend class Isolate;
237 DISALLOW_COPY_AND_ASSIGN(CompilationCache);
241 } } // namespace v8::internal
243 #endif // V8_COMPILATION_CACHE_H_