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     DCHECK(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<SharedFunctionInfo> outer_info,
    118                                          StrictMode strict_mode,
    119                                          int scope_position);
    120 
    121   void Put(Handle<String> source, Handle<SharedFunctionInfo> outer_info,
    122            Handle<SharedFunctionInfo> function_info, int scope_position);
    123 
    124  private:
    125   DISALLOW_IMPLICIT_CONSTRUCTORS(CompilationCacheEval);
    126 };
    127 
    128 
    129 // Sub-cache for regular expressions.
    130 class CompilationCacheRegExp: public CompilationSubCache {
    131  public:
    132   CompilationCacheRegExp(Isolate* isolate, int generations)
    133       : CompilationSubCache(isolate, generations) { }
    134 
    135   MaybeHandle<FixedArray> Lookup(Handle<String> source, JSRegExp::Flags flags);
    136 
    137   void Put(Handle<String> source,
    138            JSRegExp::Flags flags,
    139            Handle<FixedArray> data);
    140  private:
    141   DISALLOW_IMPLICIT_CONSTRUCTORS(CompilationCacheRegExp);
    142 };
    143 
    144 
    145 // The compilation cache keeps shared function infos for compiled
    146 // scripts and evals. The shared function infos are looked up using
    147 // the source string as the key. For regular expressions the
    148 // compilation data is cached.
    149 class CompilationCache {
    150  public:
    151   // Finds the script shared function info for a source
    152   // string. Returns an empty handle if the cache doesn't contain a
    153   // script for the given source string with the right origin.
    154   MaybeHandle<SharedFunctionInfo> LookupScript(
    155       Handle<String> source, Handle<Object> name, int line_offset,
    156       int column_offset, bool is_shared_cross_origin, Handle<Context> context);
    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, StrictMode strict_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                  Handle<SharedFunctionInfo> function_info);
    175 
    176   // Associate the (source, context->closure()->shared(), kind) triple
    177   // with the shared function info. This may overwrite an existing mapping.
    178   void PutEval(Handle<String> source, Handle<SharedFunctionInfo> outer_info,
    179                Handle<Context> context,
    180                Handle<SharedFunctionInfo> function_info, int scope_position);
    181 
    182   // Associate the (source, flags) pair to the given regexp data.
    183   // This may overwrite an existing mapping.
    184   void PutRegExp(Handle<String> source,
    185                  JSRegExp::Flags flags,
    186                  Handle<FixedArray> data);
    187 
    188   // Clear the cache - also used to initialize the cache at startup.
    189   void Clear();
    190 
    191   // Remove given shared function info from all caches.
    192   void Remove(Handle<SharedFunctionInfo> function_info);
    193 
    194   // GC support.
    195   void Iterate(ObjectVisitor* v);
    196   void IterateFunctions(ObjectVisitor* v);
    197 
    198   // Notify the cache that a mark-sweep garbage collection is about to
    199   // take place. This is used to retire entries from the cache to
    200   // avoid keeping them alive too long without using them.
    201   void MarkCompactPrologue();
    202 
    203   // Enable/disable compilation cache. Used by debugger to disable compilation
    204   // cache during debugging to make sure new scripts are always compiled.
    205   void Enable();
    206   void Disable();
    207 
    208  private:
    209   explicit CompilationCache(Isolate* isolate);
    210   ~CompilationCache();
    211 
    212   HashMap* EagerOptimizingSet();
    213 
    214   // The number of sub caches covering the different types to cache.
    215   static const int kSubCacheCount = 4;
    216 
    217   bool IsEnabled() { return FLAG_compilation_cache && enabled_; }
    218 
    219   Isolate* isolate() { return isolate_; }
    220 
    221   Isolate* isolate_;
    222 
    223   CompilationCacheScript script_;
    224   CompilationCacheEval eval_global_;
    225   CompilationCacheEval eval_contextual_;
    226   CompilationCacheRegExp reg_exp_;
    227   CompilationSubCache* subcaches_[kSubCacheCount];
    228 
    229   // Current enable state of the compilation cache.
    230   bool enabled_;
    231 
    232   friend class Isolate;
    233 
    234   DISALLOW_COPY_AND_ASSIGN(CompilationCache);
    235 };
    236 
    237 
    238 } }  // namespace v8::internal
    239 
    240 #endif  // V8_COMPILATION_CACHE_H_
    241