compilation-cache.h revision 014dc512cdd3e367bee49a713fdc5ed92584a3e5
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/handles.h"
10#include "src/objects.h"
11
12namespace v8 {
13namespace internal {
14
15// 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) {
41    DCHECK(kFirstGeneration < generations_);
42    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
79  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);
84  void Put(Handle<String> source,
85           Handle<Context> context,
86           LanguageMode language_mode,
87           Handle<SharedFunctionInfo> function_info);
88
89 private:
90  bool HasOrigin(Handle<SharedFunctionInfo> function_info, Handle<Object> name,
91                 int line_offset, int column_offset,
92                 ScriptOriginOptions resource_options);
93
94  DISALLOW_IMPLICIT_CONSTRUCTORS(CompilationCacheScript);
95};
96
97
98// Sub-cache for eval scripts. Two caches for eval are used. One for eval calls
99// in native contexts and one for eval calls in other contexts. The cache
100// 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.
104// 3. Whether the source should be compiled as strict code or as sloppy code.
105//    Note: Currently there are clients of CompileEval that always compile
106//    sloppy code even if the calling function is a strict mode function.
107//    More specifically these are the CompileString, DebugEvaluate and
108//    DebugEvaluateGlobal runtime functions.
109// 4. The start position of the calling scope.
110class CompilationCacheEval: public CompilationSubCache {
111 public:
112  CompilationCacheEval(Isolate* isolate, int generations)
113      : CompilationSubCache(isolate, generations) { }
114
115  MaybeHandle<SharedFunctionInfo> Lookup(Handle<String> source,
116                                         Handle<SharedFunctionInfo> outer_info,
117                                         LanguageMode language_mode,
118                                         int scope_position);
119
120  void Put(Handle<String> source, Handle<SharedFunctionInfo> outer_info,
121           Handle<SharedFunctionInfo> function_info, int scope_position);
122
123 private:
124  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
134  MaybeHandle<FixedArray> Lookup(Handle<String> source, JSRegExp::Flags flags);
135
136  void Put(Handle<String> source,
137           JSRegExp::Flags flags,
138           Handle<FixedArray> data);
139 private:
140  DISALLOW_IMPLICIT_CONSTRUCTORS(CompilationCacheRegExp);
141};
142
143
144// 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.
148class CompilationCache {
149 public:
150  // Finds the script shared function info for a source
151  // string. Returns an empty handle if the cache doesn't contain a
152  // script for the given source string with the right origin.
153  MaybeHandle<SharedFunctionInfo> LookupScript(
154      Handle<String> source, Handle<Object> name, int line_offset,
155      int column_offset, ScriptOriginOptions resource_options,
156      Handle<Context> context, LanguageMode language_mode);
157
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, LanguageMode language_mode, int scope_position);
164
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);
169
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                 LanguageMode language_mode,
175                 Handle<SharedFunctionInfo> function_info);
176
177  // Associate the (source, context->closure()->shared(), kind) triple
178  // with the shared function info. This may overwrite an existing mapping.
179  void PutEval(Handle<String> source, Handle<SharedFunctionInfo> outer_info,
180               Handle<Context> context,
181               Handle<SharedFunctionInfo> function_info, int scope_position);
182
183  // Associate the (source, flags) pair to the given regexp data.
184  // This may overwrite an existing mapping.
185  void PutRegExp(Handle<String> source,
186                 JSRegExp::Flags flags,
187                 Handle<FixedArray> data);
188
189  // Clear the cache - also used to initialize the cache at startup.
190  void Clear();
191
192  // Remove given shared function info from all caches.
193  void Remove(Handle<SharedFunctionInfo> function_info);
194
195  // GC support.
196  void Iterate(ObjectVisitor* v);
197  void IterateFunctions(ObjectVisitor* v);
198
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.
202  void MarkCompactPrologue();
203
204  // Enable/disable compilation cache. Used by debugger to disable compilation
205  // cache during debugging to make sure new scripts are always compiled.
206  void Enable();
207  void Disable();
208
209 private:
210  explicit CompilationCache(Isolate* isolate);
211  ~CompilationCache();
212
213  HashMap* EagerOptimizingSet();
214
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
233  friend class Isolate;
234
235  DISALLOW_COPY_AND_ASSIGN(CompilationCache);
236};
237
238
239}  // namespace internal
240}  // namespace v8
241
242#endif  // V8_COMPILATION_CACHE_H_
243