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 DCHECK(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<SharedFunctionInfo> outer_info,
118 StrictMode strict_mode,
121 void Put(Handle<String> source, Handle<SharedFunctionInfo> outer_info,
122 Handle<SharedFunctionInfo> function_info, int scope_position);
125 DISALLOW_IMPLICIT_CONSTRUCTORS(CompilationCacheEval);
129 // Sub-cache for regular expressions.
130 class CompilationCacheRegExp: public CompilationSubCache {
132 CompilationCacheRegExp(Isolate* isolate, int generations)
133 : CompilationSubCache(isolate, generations) { }
135 MaybeHandle<FixedArray> Lookup(Handle<String> source, JSRegExp::Flags flags);
137 void Put(Handle<String> source,
138 JSRegExp::Flags flags,
139 Handle<FixedArray> data);
141 DISALLOW_IMPLICIT_CONSTRUCTORS(CompilationCacheRegExp);
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 {
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 MaybeHandle<SharedFunctionInfo> LookupScript(
155 Handle<String> source, Handle<Object> name, int line_offset,
156 int column_offset, bool is_shared_cross_origin, Handle<Context> context);
158 // Finds the shared function info for a source string for eval in a
159 // given context. Returns an empty handle if the cache doesn't
160 // contain a script for the given source string.
161 MaybeHandle<SharedFunctionInfo> LookupEval(
162 Handle<String> source, Handle<SharedFunctionInfo> outer_info,
163 Handle<Context> context, StrictMode strict_mode, int scope_position);
165 // Returns the regexp data associated with the given regexp if it
166 // is in cache, otherwise an empty handle.
167 MaybeHandle<FixedArray> LookupRegExp(
168 Handle<String> source, JSRegExp::Flags flags);
170 // Associate the (source, kind) pair to the shared function
171 // info. This may overwrite an existing mapping.
172 void PutScript(Handle<String> source,
173 Handle<Context> context,
174 Handle<SharedFunctionInfo> function_info);
176 // Associate the (source, context->closure()->shared(), kind) triple
177 // with the shared function info. This may overwrite an existing mapping.
178 void PutEval(Handle<String> source, Handle<SharedFunctionInfo> outer_info,
179 Handle<Context> context,
180 Handle<SharedFunctionInfo> function_info, int scope_position);
182 // Associate the (source, flags) pair to the given regexp data.
183 // This may overwrite an existing mapping.
184 void PutRegExp(Handle<String> source,
185 JSRegExp::Flags flags,
186 Handle<FixedArray> data);
188 // Clear the cache - also used to initialize the cache at startup.
191 // Remove given shared function info from all caches.
192 void Remove(Handle<SharedFunctionInfo> function_info);
195 void Iterate(ObjectVisitor* v);
196 void IterateFunctions(ObjectVisitor* v);
198 // Notify the cache that a mark-sweep garbage collection is about to
199 // take place. This is used to retire entries from the cache to
200 // avoid keeping them alive too long without using them.
201 void MarkCompactPrologue();
203 // Enable/disable compilation cache. Used by debugger to disable compilation
204 // cache during debugging to make sure new scripts are always compiled.
209 explicit CompilationCache(Isolate* isolate);
212 HashMap* EagerOptimizingSet();
214 // The number of sub caches covering the different types to cache.
215 static const int kSubCacheCount = 4;
217 bool IsEnabled() { return FLAG_compilation_cache && enabled_; }
219 Isolate* isolate() { return isolate_; }
223 CompilationCacheScript script_;
224 CompilationCacheEval eval_global_;
225 CompilationCacheEval eval_contextual_;
226 CompilationCacheRegExp reg_exp_;
227 CompilationSubCache* subcaches_[kSubCacheCount];
229 // Current enable state of the compilation cache.
232 friend class Isolate;
234 DISALLOW_COPY_AND_ASSIGN(CompilationCache);
238 } } // namespace v8::internal
240 #endif // V8_COMPILATION_CACHE_H_