• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2008 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are
4 // met:
5 //
6 //     * Redistributions of source code must retain the above copyright
7 //       notice, this list of conditions and the following disclaimer.
8 //     * Redistributions in binary form must reproduce the above
9 //       copyright notice, this list of conditions and the following
10 //       disclaimer in the documentation and/or other materials provided
11 //       with the distribution.
12 //     * Neither the name of Google Inc. nor the names of its
13 //       contributors may be used to endorse or promote products derived
14 //       from this software without specific prior written permission.
15 //
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 
28 #ifndef V8_COMPILATION_CACHE_H_
29 #define V8_COMPILATION_CACHE_H_
30 
31 namespace v8 {
32 namespace internal {
33 
34 class HashMap;
35 
36 // The compilation cache consists of several generational sub-caches which uses
37 // this class as a base class. A sub-cache contains a compilation cache tables
38 // for each generation of the sub-cache. Since the same source code string has
39 // different compiled code for scripts and evals, we use separate sub-caches
40 // for different compilation modes, to avoid retrieving the wrong result.
41 class CompilationSubCache {
42  public:
CompilationSubCache(Isolate * isolate,int generations)43   CompilationSubCache(Isolate* isolate, int generations)
44       : isolate_(isolate),
45         generations_(generations) {
46     tables_ = NewArray<Object*>(generations);
47   }
48 
~CompilationSubCache()49   ~CompilationSubCache() { DeleteArray(tables_); }
50 
51   // Index for the first generation in the cache.
52   static const int kFirstGeneration = 0;
53 
54   // Get the compilation cache tables for a specific generation.
55   Handle<CompilationCacheTable> GetTable(int generation);
56 
57   // Accessors for first generation.
GetFirstTable()58   Handle<CompilationCacheTable> GetFirstTable() {
59     return GetTable(kFirstGeneration);
60   }
SetFirstTable(Handle<CompilationCacheTable> value)61   void SetFirstTable(Handle<CompilationCacheTable> value) {
62     ASSERT(kFirstGeneration < generations_);
63     tables_[kFirstGeneration] = *value;
64   }
65 
66   // Age the sub-cache by evicting the oldest generation and creating a new
67   // young generation.
68   void Age();
69 
70   // GC support.
71   void Iterate(ObjectVisitor* v);
72   void IterateFunctions(ObjectVisitor* v);
73 
74   // Clear this sub-cache evicting all its content.
75   void Clear();
76 
77   // Remove given shared function info from sub-cache.
78   void Remove(Handle<SharedFunctionInfo> function_info);
79 
80   // Number of generations in this sub-cache.
generations()81   inline int generations() { return generations_; }
82 
83  protected:
isolate()84   Isolate* isolate() { return isolate_; }
85 
86  private:
87   Isolate* isolate_;
88   int generations_;  // Number of generations.
89   Object** tables_;  // Compilation cache tables - one for each generation.
90 
91   DISALLOW_IMPLICIT_CONSTRUCTORS(CompilationSubCache);
92 };
93 
94 
95 // Sub-cache for scripts.
96 class CompilationCacheScript : public CompilationSubCache {
97  public:
98   CompilationCacheScript(Isolate* isolate, int generations);
99 
100   Handle<SharedFunctionInfo> Lookup(Handle<String> source,
101                                     Handle<Object> name,
102                                     int line_offset,
103                                     int column_offset);
104   void Put(Handle<String> source, Handle<SharedFunctionInfo> function_info);
105 
106  private:
107   MUST_USE_RESULT MaybeObject* TryTablePut(
108       Handle<String> source, Handle<SharedFunctionInfo> function_info);
109 
110   // Note: Returns a new hash table if operation results in expansion.
111   Handle<CompilationCacheTable> TablePut(
112       Handle<String> source, Handle<SharedFunctionInfo> function_info);
113 
114   bool HasOrigin(Handle<SharedFunctionInfo> function_info,
115                  Handle<Object> name,
116                  int line_offset,
117                  int column_offset);
118 
119   void* script_histogram_;
120   bool script_histogram_initialized_;
121 
122   DISALLOW_IMPLICIT_CONSTRUCTORS(CompilationCacheScript);
123 };
124 
125 
126 // Sub-cache for eval scripts.
127 class CompilationCacheEval: public CompilationSubCache {
128  public:
CompilationCacheEval(Isolate * isolate,int generations)129   CompilationCacheEval(Isolate* isolate, int generations)
130       : CompilationSubCache(isolate, generations) { }
131 
132   Handle<SharedFunctionInfo> Lookup(Handle<String> source,
133                                     Handle<Context> context,
134                                     StrictModeFlag strict_mode);
135 
136   void Put(Handle<String> source,
137            Handle<Context> context,
138            Handle<SharedFunctionInfo> function_info);
139 
140  private:
141   MUST_USE_RESULT MaybeObject* TryTablePut(
142       Handle<String> source,
143       Handle<Context> context,
144       Handle<SharedFunctionInfo> function_info);
145 
146   // Note: Returns a new hash table if operation results in expansion.
147   Handle<CompilationCacheTable> TablePut(
148       Handle<String> source,
149       Handle<Context> context,
150       Handle<SharedFunctionInfo> function_info);
151 
152   DISALLOW_IMPLICIT_CONSTRUCTORS(CompilationCacheEval);
153 };
154 
155 
156 // Sub-cache for regular expressions.
157 class CompilationCacheRegExp: public CompilationSubCache {
158  public:
CompilationCacheRegExp(Isolate * isolate,int generations)159   CompilationCacheRegExp(Isolate* isolate, int generations)
160       : CompilationSubCache(isolate, generations) { }
161 
162   Handle<FixedArray> Lookup(Handle<String> source, JSRegExp::Flags flags);
163 
164   void Put(Handle<String> source,
165            JSRegExp::Flags flags,
166            Handle<FixedArray> data);
167  private:
168   MUST_USE_RESULT MaybeObject* TryTablePut(Handle<String> source,
169                                       JSRegExp::Flags flags,
170                                       Handle<FixedArray> data);
171 
172   // Note: Returns a new hash table if operation results in expansion.
173   Handle<CompilationCacheTable> TablePut(Handle<String> source,
174                                          JSRegExp::Flags flags,
175                                          Handle<FixedArray> data);
176 
177   DISALLOW_IMPLICIT_CONSTRUCTORS(CompilationCacheRegExp);
178 };
179 
180 
181 // The compilation cache keeps shared function infos for compiled
182 // scripts and evals. The shared function infos are looked up using
183 // the source string as the key. For regular expressions the
184 // compilation data is cached.
185 class CompilationCache {
186  public:
187   // Finds the script shared function info for a source
188   // string. Returns an empty handle if the cache doesn't contain a
189   // script for the given source string with the right origin.
190   Handle<SharedFunctionInfo> LookupScript(Handle<String> source,
191                                           Handle<Object> name,
192                                           int line_offset,
193                                           int column_offset);
194 
195   // Finds the shared function info for a source string for eval in a
196   // given context.  Returns an empty handle if the cache doesn't
197   // contain a script for the given source string.
198   Handle<SharedFunctionInfo> LookupEval(Handle<String> source,
199                                         Handle<Context> context,
200                                         bool is_global,
201                                         StrictModeFlag strict_mode);
202 
203   // Returns the regexp data associated with the given regexp if it
204   // is in cache, otherwise an empty handle.
205   Handle<FixedArray> LookupRegExp(Handle<String> source,
206                                   JSRegExp::Flags flags);
207 
208   // Associate the (source, kind) pair to the shared function
209   // info. This may overwrite an existing mapping.
210   void PutScript(Handle<String> source,
211                  Handle<SharedFunctionInfo> function_info);
212 
213   // Associate the (source, context->closure()->shared(), kind) triple
214   // with the shared function info. This may overwrite an existing mapping.
215   void PutEval(Handle<String> source,
216                Handle<Context> context,
217                bool is_global,
218                Handle<SharedFunctionInfo> function_info);
219 
220   // Associate the (source, flags) pair to the given regexp data.
221   // This may overwrite an existing mapping.
222   void PutRegExp(Handle<String> source,
223                  JSRegExp::Flags flags,
224                  Handle<FixedArray> data);
225 
226   // Support for eager optimization tracking.
227   bool ShouldOptimizeEagerly(Handle<JSFunction> function);
228   void MarkForEagerOptimizing(Handle<JSFunction> function);
229   void MarkForLazyOptimizing(Handle<JSFunction> function);
230 
231   // Reset the eager optimization tracking data.
232   void ResetEagerOptimizingData();
233 
234   // Clear the cache - also used to initialize the cache at startup.
235   void Clear();
236 
237   // Remove given shared function info from all caches.
238   void Remove(Handle<SharedFunctionInfo> function_info);
239 
240   // GC support.
241   void Iterate(ObjectVisitor* v);
242   void IterateFunctions(ObjectVisitor* v);
243 
244   // Notify the cache that a mark-sweep garbage collection is about to
245   // take place. This is used to retire entries from the cache to
246   // avoid keeping them alive too long without using them.
247   void MarkCompactPrologue();
248 
249   // Enable/disable compilation cache. Used by debugger to disable compilation
250   // cache during debugging to make sure new scripts are always compiled.
251   void Enable();
252   void Disable();
253  private:
254   explicit CompilationCache(Isolate* isolate);
255   ~CompilationCache();
256 
257   HashMap* EagerOptimizingSet();
258 
259   // The number of sub caches covering the different types to cache.
260   static const int kSubCacheCount = 4;
261 
IsEnabled()262   bool IsEnabled() { return FLAG_compilation_cache && enabled_; }
263 
isolate()264   Isolate* isolate() { return isolate_; }
265 
266   Isolate* isolate_;
267 
268   CompilationCacheScript script_;
269   CompilationCacheEval eval_global_;
270   CompilationCacheEval eval_contextual_;
271   CompilationCacheRegExp reg_exp_;
272   CompilationSubCache* subcaches_[kSubCacheCount];
273 
274   // Current enable state of the compilation cache.
275   bool enabled_;
276 
277   HashMap* eager_optimizing_set_;
278 
279   friend class Isolate;
280 
281   DISALLOW_COPY_AND_ASSIGN(CompilationCache);
282 };
283 
284 
285 } }  // namespace v8::internal
286 
287 #endif  // V8_COMPILATION_CACHE_H_
288