blob: 973673c524335a75e0c3d0cff60c3dba8603ebdf [file] [log] [blame]
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001// Copyright 2012 the V8 project authors. All rights reserved.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
Steve Blocka7e24c12009-10-30 11:49:00 +00004
5#ifndef V8_COMPILATION_CACHE_H_
6#define V8_COMPILATION_CACHE_H_
7
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00008#include "src/allocation.h"
9#include "src/handles.h"
10#include "src/objects.h"
11
Steve Blocka7e24c12009-10-30 11:49:00 +000012namespace v8 {
13namespace internal {
14
Steve Block44f0eee2011-05-26 01:26:41 +010015// The compilation cache consists of several generational sub-caches which uses
16// this class as a base class. A sub-cache contains a compilation cache tables
17// for each generation of the sub-cache. Since the same source code string has
18// different compiled code for scripts and evals, we use separate sub-caches
19// for different compilation modes, to avoid retrieving the wrong result.
20class CompilationSubCache {
21 public:
22 CompilationSubCache(Isolate* isolate, int generations)
23 : isolate_(isolate),
24 generations_(generations) {
25 tables_ = NewArray<Object*>(generations);
26 }
27
28 ~CompilationSubCache() { DeleteArray(tables_); }
29
30 // Index for the first generation in the cache.
31 static const int kFirstGeneration = 0;
32
33 // Get the compilation cache tables for a specific generation.
34 Handle<CompilationCacheTable> GetTable(int generation);
35
36 // Accessors for first generation.
37 Handle<CompilationCacheTable> GetFirstTable() {
38 return GetTable(kFirstGeneration);
39 }
40 void SetFirstTable(Handle<CompilationCacheTable> value) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +000041 DCHECK(kFirstGeneration < generations_);
Steve Block44f0eee2011-05-26 01:26:41 +010042 tables_[kFirstGeneration] = *value;
43 }
44
45 // Age the sub-cache by evicting the oldest generation and creating a new
46 // young generation.
47 void Age();
48
49 // GC support.
50 void Iterate(ObjectVisitor* v);
51 void IterateFunctions(ObjectVisitor* v);
52
53 // Clear this sub-cache evicting all its content.
54 void Clear();
55
56 // Remove given shared function info from sub-cache.
57 void Remove(Handle<SharedFunctionInfo> function_info);
58
59 // Number of generations in this sub-cache.
60 inline int generations() { return generations_; }
61
62 protected:
63 Isolate* isolate() { return isolate_; }
64
65 private:
66 Isolate* isolate_;
67 int generations_; // Number of generations.
68 Object** tables_; // Compilation cache tables - one for each generation.
69
70 DISALLOW_IMPLICIT_CONSTRUCTORS(CompilationSubCache);
71};
72
73
74// Sub-cache for scripts.
75class CompilationCacheScript : public CompilationSubCache {
76 public:
77 CompilationCacheScript(Isolate* isolate, int generations);
78
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000079 Handle<SharedFunctionInfo> Lookup(Handle<String> source, Handle<Object> name,
80 int line_offset, int column_offset,
81 ScriptOriginOptions resource_options,
82 Handle<Context> context,
83 LanguageMode language_mode);
Ben Murdochb8a8cc12014-11-26 15:28:44 +000084 void Put(Handle<String> source,
85 Handle<Context> context,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000086 LanguageMode language_mode,
Ben Murdochb8a8cc12014-11-26 15:28:44 +000087 Handle<SharedFunctionInfo> function_info);
Steve Block44f0eee2011-05-26 01:26:41 +010088
89 private:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000090 bool HasOrigin(Handle<SharedFunctionInfo> function_info, Handle<Object> name,
91 int line_offset, int column_offset,
92 ScriptOriginOptions resource_options);
Steve Block44f0eee2011-05-26 01:26:41 +010093
Steve Block44f0eee2011-05-26 01:26:41 +010094 DISALLOW_IMPLICIT_CONSTRUCTORS(CompilationCacheScript);
95};
96
97
Ben Murdoch3ef787d2012-04-12 10:51:47 +010098// Sub-cache for eval scripts. Two caches for eval are used. One for eval calls
Ben Murdochb8a8cc12014-11-26 15:28:44 +000099// in native contexts and one for eval calls in other contexts. The cache
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100100// considers the following pieces of information when checking for matching
101// entries:
102// 1. The source string.
103// 2. The shared function info of the calling function.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000104// 3. Whether the source should be compiled as strict code or as sloppy code.
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100105// Note: Currently there are clients of CompileEval that always compile
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000106// sloppy code even if the calling function is a strict mode function.
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100107// More specifically these are the CompileString, DebugEvaluate and
108// DebugEvaluateGlobal runtime functions.
109// 4. The start position of the calling scope.
Steve Block44f0eee2011-05-26 01:26:41 +0100110class CompilationCacheEval: public CompilationSubCache {
111 public:
112 CompilationCacheEval(Isolate* isolate, int generations)
113 : CompilationSubCache(isolate, generations) { }
114
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000115 MaybeHandle<SharedFunctionInfo> Lookup(Handle<String> source,
116 Handle<SharedFunctionInfo> outer_info,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000117 LanguageMode language_mode,
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000118 int scope_position);
Steve Block44f0eee2011-05-26 01:26:41 +0100119
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000120 void Put(Handle<String> source, Handle<SharedFunctionInfo> outer_info,
121 Handle<SharedFunctionInfo> function_info, int scope_position);
Steve Block44f0eee2011-05-26 01:26:41 +0100122
123 private:
Steve Block44f0eee2011-05-26 01:26:41 +0100124 DISALLOW_IMPLICIT_CONSTRUCTORS(CompilationCacheEval);
125};
126
127
128// Sub-cache for regular expressions.
129class CompilationCacheRegExp: public CompilationSubCache {
130 public:
131 CompilationCacheRegExp(Isolate* isolate, int generations)
132 : CompilationSubCache(isolate, generations) { }
133
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000134 MaybeHandle<FixedArray> Lookup(Handle<String> source, JSRegExp::Flags flags);
Steve Block44f0eee2011-05-26 01:26:41 +0100135
136 void Put(Handle<String> source,
137 JSRegExp::Flags flags,
138 Handle<FixedArray> data);
139 private:
Steve Block44f0eee2011-05-26 01:26:41 +0100140 DISALLOW_IMPLICIT_CONSTRUCTORS(CompilationCacheRegExp);
141};
142
Steve Blocka7e24c12009-10-30 11:49:00 +0000143
Steve Block6ded16b2010-05-10 14:33:55 +0100144// The compilation cache keeps shared function infos for compiled
145// scripts and evals. The shared function infos are looked up using
146// the source string as the key. For regular expressions the
147// compilation data is cached.
Steve Blocka7e24c12009-10-30 11:49:00 +0000148class CompilationCache {
149 public:
Steve Block6ded16b2010-05-10 14:33:55 +0100150 // Finds the script shared function info for a source
Steve Blocka7e24c12009-10-30 11:49:00 +0000151 // string. Returns an empty handle if the cache doesn't contain a
152 // script for the given source string with the right origin.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000153 MaybeHandle<SharedFunctionInfo> LookupScript(
154 Handle<String> source, Handle<Object> name, int line_offset,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000155 int column_offset, ScriptOriginOptions resource_options,
156 Handle<Context> context, LanguageMode language_mode);
Steve Blocka7e24c12009-10-30 11:49:00 +0000157
Steve Block6ded16b2010-05-10 14:33:55 +0100158 // Finds the shared function info for a source string for eval in a
Steve Blocka7e24c12009-10-30 11:49:00 +0000159 // given context. Returns an empty handle if the cache doesn't
160 // contain a script for the given source string.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000161 MaybeHandle<SharedFunctionInfo> LookupEval(
162 Handle<String> source, Handle<SharedFunctionInfo> outer_info,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000163 Handle<Context> context, LanguageMode language_mode, int scope_position);
Steve Blocka7e24c12009-10-30 11:49:00 +0000164
165 // Returns the regexp data associated with the given regexp if it
166 // is in cache, otherwise an empty handle.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000167 MaybeHandle<FixedArray> LookupRegExp(
168 Handle<String> source, JSRegExp::Flags flags);
Steve Blocka7e24c12009-10-30 11:49:00 +0000169
Steve Block6ded16b2010-05-10 14:33:55 +0100170 // Associate the (source, kind) pair to the shared function
171 // info. This may overwrite an existing mapping.
Steve Block44f0eee2011-05-26 01:26:41 +0100172 void PutScript(Handle<String> source,
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000173 Handle<Context> context,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000174 LanguageMode language_mode,
Steve Block44f0eee2011-05-26 01:26:41 +0100175 Handle<SharedFunctionInfo> function_info);
Steve Blocka7e24c12009-10-30 11:49:00 +0000176
177 // Associate the (source, context->closure()->shared(), kind) triple
Steve Block6ded16b2010-05-10 14:33:55 +0100178 // with the shared function info. This may overwrite an existing mapping.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000179 void PutEval(Handle<String> source, Handle<SharedFunctionInfo> outer_info,
Steve Block44f0eee2011-05-26 01:26:41 +0100180 Handle<Context> context,
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000181 Handle<SharedFunctionInfo> function_info, int scope_position);
Steve Blocka7e24c12009-10-30 11:49:00 +0000182
183 // Associate the (source, flags) pair to the given regexp data.
184 // This may overwrite an existing mapping.
Steve Block44f0eee2011-05-26 01:26:41 +0100185 void PutRegExp(Handle<String> source,
186 JSRegExp::Flags flags,
187 Handle<FixedArray> data);
Steve Blocka7e24c12009-10-30 11:49:00 +0000188
189 // Clear the cache - also used to initialize the cache at startup.
Steve Block44f0eee2011-05-26 01:26:41 +0100190 void Clear();
Steve Blocka7e24c12009-10-30 11:49:00 +0000191
Ben Murdochb0fe1622011-05-05 13:52:32 +0100192 // Remove given shared function info from all caches.
Steve Block44f0eee2011-05-26 01:26:41 +0100193 void Remove(Handle<SharedFunctionInfo> function_info);
Ben Murdochb0fe1622011-05-05 13:52:32 +0100194
Steve Blocka7e24c12009-10-30 11:49:00 +0000195 // GC support.
Steve Block44f0eee2011-05-26 01:26:41 +0100196 void Iterate(ObjectVisitor* v);
197 void IterateFunctions(ObjectVisitor* v);
Steve Blocka7e24c12009-10-30 11:49:00 +0000198
199 // Notify the cache that a mark-sweep garbage collection is about to
200 // take place. This is used to retire entries from the cache to
201 // avoid keeping them alive too long without using them.
Steve Block44f0eee2011-05-26 01:26:41 +0100202 void MarkCompactPrologue();
Steve Blocka7e24c12009-10-30 11:49:00 +0000203
204 // Enable/disable compilation cache. Used by debugger to disable compilation
205 // cache during debugging to make sure new scripts are always compiled.
Steve Block44f0eee2011-05-26 01:26:41 +0100206 void Enable();
207 void Disable();
Ben Murdoch589d6972011-11-30 16:04:58 +0000208
Steve Block44f0eee2011-05-26 01:26:41 +0100209 private:
210 explicit CompilationCache(Isolate* isolate);
211 ~CompilationCache();
212
Ben Murdoch61f157c2016-09-16 13:49:30 +0100213 base::HashMap* EagerOptimizingSet();
Steve Block44f0eee2011-05-26 01:26:41 +0100214
215 // The number of sub caches covering the different types to cache.
216 static const int kSubCacheCount = 4;
217
218 bool IsEnabled() { return FLAG_compilation_cache && enabled_; }
219
220 Isolate* isolate() { return isolate_; }
221
222 Isolate* isolate_;
223
224 CompilationCacheScript script_;
225 CompilationCacheEval eval_global_;
226 CompilationCacheEval eval_contextual_;
227 CompilationCacheRegExp reg_exp_;
228 CompilationSubCache* subcaches_[kSubCacheCount];
229
230 // Current enable state of the compilation cache.
231 bool enabled_;
232
Steve Block44f0eee2011-05-26 01:26:41 +0100233 friend class Isolate;
234
235 DISALLOW_COPY_AND_ASSIGN(CompilationCache);
Steve Blocka7e24c12009-10-30 11:49:00 +0000236};
237
238
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000239} // namespace internal
240} // namespace v8
Steve Blocka7e24c12009-10-30 11:49:00 +0000241
242#endif // V8_COMPILATION_CACHE_H_