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 namespace v8 {
      9 namespace internal {
     10 
     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 {
     17  public:
     18   CompilationSubCache(Isolate* isolate, int generations)
     19       : isolate_(isolate),
     20         generations_(generations) {
     21     tables_ = NewArray<Object*>(generations);
     22   }
     23 
     24   ~CompilationSubCache() { DeleteArray(tables_); }
     25 
     26   // Index for the first generation in the cache.
     27   static const int kFirstGeneration = 0;
     28 
     29   // Get the compilation cache tables for a specific generation.
     30   Handle<CompilationCacheTable> GetTable(int generation);
     31 
     32   // Accessors for first generation.
     33   Handle<CompilationCacheTable> GetFirstTable() {
     34     return GetTable(kFirstGeneration);
     35   }
     36   void SetFirstTable(Handle<CompilationCacheTable> value) {
     37     ASSERT(kFirstGeneration < generations_);
     38     tables_[kFirstGeneration] = *value;
     39   }
     40 
     41   // Age the sub-cache by evicting the oldest generation and creating a new
     42   // young generation.
     43   void Age();
     44 
     45   // GC support.
     46   void Iterate(ObjectVisitor* v);
     47   void IterateFunctions(ObjectVisitor* v);
     48 
     49   // Clear this sub-cache evicting all its content.
     50   void Clear();
     51 
     52   // Remove given shared function info from sub-cache.
     53   void Remove(Handle<SharedFunctionInfo> function_info);
     54 
     55   // Number of generations in this sub-cache.
     56   inline int generations() { return generations_; }
     57 
     58  protected:
     59   Isolate* isolate() { return isolate_; }
     60 
     61  private:
     62   Isolate* isolate_;
     63   int generations_;  // Number of generations.
     64   Object** tables_;  // Compilation cache tables - one for each generation.
     65 
     66   DISALLOW_IMPLICIT_CONSTRUCTORS(CompilationSubCache);
     67 };
     68 
     69 
     70 // Sub-cache for scripts.
     71 class CompilationCacheScript : public CompilationSubCache {
     72  public:
     73   CompilationCacheScript(Isolate* isolate, int generations);
     74 
     75   Handle<SharedFunctionInfo> Lookup(Handle<String> source,
     76                                     Handle<Object> name,
     77                                     int line_offset,
     78                                     int column_offset,
     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);
     84 
     85  private:
     86   bool HasOrigin(Handle<SharedFunctionInfo> function_info,
     87                  Handle<Object> name,
     88                  int line_offset,
     89                  int column_offset,
     90                  bool is_shared_cross_origin);
     91 
     92   void* script_histogram_;
     93   bool script_histogram_initialized_;
     94 
     95   DISALLOW_IMPLICIT_CONSTRUCTORS(CompilationCacheScript);
     96 };
     97 
     98 
     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
    102 // entries:
    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 {
    112  public:
    113   CompilationCacheEval(Isolate* isolate, int generations)
    114       : CompilationSubCache(isolate, generations) { }
    115 
    116   MaybeHandle<SharedFunctionInfo> Lookup(Handle<String> source,
    117                                          Handle<Context> context,
    118                                          StrictMode strict_mode,
    119                                          int scope_position);
    120 
    121   void Put(Handle<String> source,
    122            Handle<Context> context,
    123            Handle<SharedFunctionInfo> function_info,
    124            int scope_position);
    125 
    126  private:
    127   DISALLOW_IMPLICIT_CONSTRUCTORS(CompilationCacheEval);
    128 };
    129 
    130 
    131 // Sub-cache for regular expressions.
    132 class CompilationCacheRegExp: public CompilationSubCache {
    133  public:
    134   CompilationCacheRegExp(Isolate* isolate, int generations)
    135       : CompilationSubCache(isolate, generations) { }
    136 
    137   MaybeHandle<FixedArray> Lookup(Handle<String> source, JSRegExp::Flags flags);
    138 
    139   void Put(Handle<String> source,
    140            JSRegExp::Flags flags,
    141            Handle<FixedArray> data);
    142  private:
    143   DISALLOW_IMPLICIT_CONSTRUCTORS(CompilationCacheRegExp);
    144 };
    145 
    146 
    147 // The compilation cache keeps shared function infos for compiled
    148 // scripts and evals. The shared function infos are looked up using
    149 // the source string as the key. For regular expressions the
    150 // compilation data is cached.
    151 class CompilationCache {
    152  public:
    153   // Finds the script shared function info for a source
    154   // string. Returns an empty handle if the cache doesn't contain a
    155   // script for the given source string with the right origin.
    156   MaybeHandle<SharedFunctionInfo> LookupScript(
    157       Handle<String> source, Handle<Object> name, int line_offset,
    158       int column_offset, bool is_shared_cross_origin, Handle<Context> context);
    159 
    160   // Finds the shared function info for a source string for eval in a
    161   // given context.  Returns an empty handle if the cache doesn't
    162   // contain a script for the given source string.
    163   MaybeHandle<SharedFunctionInfo> LookupEval(
    164       Handle<String> source, Handle<Context> context, StrictMode strict_mode,
    165       int scope_position);
    166 
    167   // Returns the regexp data associated with the given regexp if it
    168   // is in cache, otherwise an empty handle.
    169   MaybeHandle<FixedArray> LookupRegExp(
    170       Handle<String> source, JSRegExp::Flags flags);
    171 
    172   // Associate the (source, kind) pair to the shared function
    173   // info. This may overwrite an existing mapping.
    174   void PutScript(Handle<String> source,
    175                  Handle<Context> context,
    176                  Handle<SharedFunctionInfo> function_info);
    177 
    178   // Associate the (source, context->closure()->shared(), kind) triple
    179   // with the shared function info. This may overwrite an existing mapping.
    180   void PutEval(Handle<String> source,
    181                Handle<Context> context,
    182                Handle<SharedFunctionInfo> function_info,
    183                int scope_position);
    184 
    185   // Associate the (source, flags) pair to the given regexp data.
    186   // This may overwrite an existing mapping.
    187   void PutRegExp(Handle<String> source,
    188                  JSRegExp::Flags flags,
    189                  Handle<FixedArray> data);
    190 
    191   // Clear the cache - also used to initialize the cache at startup.
    192   void Clear();
    193 
    194   // Remove given shared function info from all caches.
    195   void Remove(Handle<SharedFunctionInfo> function_info);
    196 
    197   // GC support.
    198   void Iterate(ObjectVisitor* v);
    199   void IterateFunctions(ObjectVisitor* v);
    200 
    201   // Notify the cache that a mark-sweep garbage collection is about to
    202   // take place. This is used to retire entries from the cache to
    203   // avoid keeping them alive too long without using them.
    204   void MarkCompactPrologue();
    205 
    206   // Enable/disable compilation cache. Used by debugger to disable compilation
    207   // cache during debugging to make sure new scripts are always compiled.
    208   void Enable();
    209   void Disable();
    210 
    211  private:
    212   explicit CompilationCache(Isolate* isolate);
    213   ~CompilationCache();
    214 
    215   HashMap* EagerOptimizingSet();
    216 
    217   // The number of sub caches covering the different types to cache.
    218   static const int kSubCacheCount = 4;
    219 
    220   bool IsEnabled() { return FLAG_compilation_cache && enabled_; }
    221 
    222   Isolate* isolate() { return isolate_; }
    223 
    224   Isolate* isolate_;
    225 
    226   CompilationCacheScript script_;
    227   CompilationCacheEval eval_global_;
    228   CompilationCacheEval eval_contextual_;
    229   CompilationCacheRegExp reg_exp_;
    230   CompilationSubCache* subcaches_[kSubCacheCount];
    231 
    232   // Current enable state of the compilation cache.
    233   bool enabled_;
    234 
    235   friend class Isolate;
    236 
    237   DISALLOW_COPY_AND_ASSIGN(CompilationCache);
    238 };
    239 
    240 
    241 } }  // namespace v8::internal
    242 
    243 #endif  // V8_COMPILATION_CACHE_H_
    244