Home | History | Annotate | Download | only in src
      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 
     12 namespace v8 {
     13 namespace 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.
     20 class 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.
     75 class 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.
    110 class 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.
    129 class 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.
    148 class 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   base::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