• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2017 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_OBJECTS_COMPILATION_CACHE_TABLE_H_
6 #define V8_OBJECTS_COMPILATION_CACHE_TABLE_H_
7 
8 #include "src/objects/feedback-cell.h"
9 #include "src/objects/hash-table.h"
10 #include "src/objects/js-regexp.h"
11 #include "src/objects/shared-function-info.h"
12 #include "src/roots/roots.h"
13 
14 // Has to be the last include (doesn't have include guards):
15 #include "src/objects/object-macros.h"
16 
17 namespace v8 {
18 namespace internal {
19 
20 class CompilationCacheShape : public BaseShape<HashTableKey*> {
21  public:
IsMatch(HashTableKey * key,Object value)22   static inline bool IsMatch(HashTableKey* key, Object value) {
23     return key->IsMatch(value);
24   }
25 
Hash(ReadOnlyRoots roots,HashTableKey * key)26   static inline uint32_t Hash(ReadOnlyRoots roots, HashTableKey* key) {
27     return key->Hash();
28   }
29 
30   static inline uint32_t RegExpHash(String string, Smi flags);
31 
32   static inline uint32_t StringSharedHash(String source,
33                                           SharedFunctionInfo shared,
34                                           LanguageMode language_mode,
35                                           int position);
36 
37   static inline uint32_t HashForObject(ReadOnlyRoots roots, Object object);
38 
39   static const int kPrefixSize = 0;
40   // An 'entry' is essentially a grouped collection of slots. Entries are used
41   // in various ways by the different caches; most store the actual key in the
42   // first entry slot, but it may also be used differently.
43   // Why 3 slots? Because of the eval cache.
44   static const int kEntrySize = 3;
45   static const bool kMatchNeedsHoleCheck = true;
46 };
47 
48 class InfoCellPair {
49  public:
50   InfoCellPair() = default;
51   inline InfoCellPair(Isolate* isolate, SharedFunctionInfo shared,
52                       FeedbackCell feedback_cell);
53 
feedback_cell()54   FeedbackCell feedback_cell() const {
55     DCHECK(is_compiled_scope_.is_compiled());
56     return feedback_cell_;
57   }
shared()58   SharedFunctionInfo shared() const {
59     DCHECK(is_compiled_scope_.is_compiled());
60     return shared_;
61   }
62 
has_feedback_cell()63   bool has_feedback_cell() const {
64     return !feedback_cell_.is_null() && is_compiled_scope_.is_compiled();
65   }
has_shared()66   bool has_shared() const {
67     // Only return true if SFI is compiled - the bytecode could have been
68     // flushed while it's in the compilation cache, and not yet have been
69     // removed form the compilation cache.
70     return !shared_.is_null() && is_compiled_scope_.is_compiled();
71   }
72 
73  private:
74   IsCompiledScope is_compiled_scope_;
75   SharedFunctionInfo shared_;
76   FeedbackCell feedback_cell_;
77 };
78 
EXTERN_DECLARE_HASH_TABLE(CompilationCacheTable,CompilationCacheShape)79 EXTERN_DECLARE_HASH_TABLE(CompilationCacheTable, CompilationCacheShape)
80 
81 class CompilationCacheTable
82     : public HashTable<CompilationCacheTable, CompilationCacheShape> {
83  public:
84   NEVER_READ_ONLY_SPACE
85 
86   // The 'script' cache contains SharedFunctionInfos.
87   static MaybeHandle<SharedFunctionInfo> LookupScript(
88       Handle<CompilationCacheTable> table, Handle<String> src,
89       Handle<Context> native_context, LanguageMode language_mode);
90   static Handle<CompilationCacheTable> PutScript(
91       Handle<CompilationCacheTable> cache, Handle<String> src,
92       Handle<Context> native_context, LanguageMode language_mode,
93       Handle<SharedFunctionInfo> value);
94 
95   // Eval code only gets cached after a second probe for the
96   // code object. To do so, on first "put" only a hash identifying the
97   // source is entered into the cache, mapping it to a lifetime count of
98   // the hash. On each call to Age all such lifetimes get reduced, and
99   // removed once they reach zero. If a second put is called while such
100   // a hash is live in the cache, the hash gets replaced by an actual
101   // cache entry. Age also removes stale live entries from the cache.
102   // Such entries are identified by SharedFunctionInfos pointing to
103   // either the recompilation stub, or to "old" code. This avoids memory
104   // leaks due to premature caching of eval strings that are
105   // never needed later.
106   static InfoCellPair LookupEval(Handle<CompilationCacheTable> table,
107                                  Handle<String> src,
108                                  Handle<SharedFunctionInfo> shared,
109                                  Handle<Context> native_context,
110                                  LanguageMode language_mode, int position);
111   static Handle<CompilationCacheTable> PutEval(
112       Handle<CompilationCacheTable> cache, Handle<String> src,
113       Handle<SharedFunctionInfo> outer_info, Handle<SharedFunctionInfo> value,
114       Handle<Context> native_context, Handle<FeedbackCell> feedback_cell,
115       int position);
116 
117   // The RegExp cache contains JSRegExp::data fixed arrays.
118   Handle<Object> LookupRegExp(Handle<String> source, JSRegExp::Flags flags);
119   static Handle<CompilationCacheTable> PutRegExp(
120       Isolate* isolate, Handle<CompilationCacheTable> cache, Handle<String> src,
121       JSRegExp::Flags flags, Handle<FixedArray> value);
122 
123   // The Code cache shares native-context-independent (NCI) code between
124   // contexts.
125   MaybeHandle<Code> LookupCode(Handle<SharedFunctionInfo> key);
126   static Handle<CompilationCacheTable> PutCode(
127       Isolate* isolate, Handle<CompilationCacheTable> cache,
128       Handle<SharedFunctionInfo> key, Handle<Code> value);
129 
130   void Remove(Object value);
131   void Age();
132 
133   DECL_CAST(CompilationCacheTable)
134 
135  private:
136   void RemoveEntry(int entry_index);
137 
138   OBJECT_CONSTRUCTORS(CompilationCacheTable,
139                       HashTable<CompilationCacheTable, CompilationCacheShape>);
140 };
141 
142 }  // namespace internal
143 }  // namespace v8
144 
145 #include "src/objects/object-macros-undef.h"
146 
147 #endif  // V8_OBJECTS_COMPILATION_CACHE_TABLE_H_
148