| // Copyright 2017 the V8 project authors. All rights reserved. | 
 | // Use of this source code is governed by a BSD-style license that can be | 
 | // found in the LICENSE file. | 
 |  | 
 | #ifndef V8_OBJECTS_COMPILATION_CACHE_TABLE_H_ | 
 | #define V8_OBJECTS_COMPILATION_CACHE_TABLE_H_ | 
 |  | 
 | #include "src/objects/feedback-cell.h" | 
 | #include "src/objects/hash-table.h" | 
 | #include "src/objects/js-regexp.h" | 
 | #include "src/objects/shared-function-info.h" | 
 | #include "src/roots/roots.h" | 
 |  | 
 | // Has to be the last include (doesn't have include guards): | 
 | #include "src/objects/object-macros.h" | 
 |  | 
 | namespace v8 { | 
 | namespace internal { | 
 |  | 
 | class CompilationCacheShape : public BaseShape<HashTableKey*> { | 
 |  public: | 
 |   static inline bool IsMatch(HashTableKey* key, Object value) { | 
 |     return key->IsMatch(value); | 
 |   } | 
 |  | 
 |   static inline uint32_t Hash(ReadOnlyRoots roots, HashTableKey* key) { | 
 |     return key->Hash(); | 
 |   } | 
 |  | 
 |   static inline uint32_t RegExpHash(String string, Smi flags); | 
 |  | 
 |   static inline uint32_t StringSharedHash(String source, | 
 |                                           SharedFunctionInfo shared, | 
 |                                           LanguageMode language_mode, | 
 |                                           int position); | 
 |  | 
 |   static inline uint32_t HashForObject(ReadOnlyRoots roots, Object object); | 
 |  | 
 |   static const int kPrefixSize = 0; | 
 |   // An 'entry' is essentially a grouped collection of slots. Entries are used | 
 |   // in various ways by the different caches; most store the actual key in the | 
 |   // first entry slot, but it may also be used differently. | 
 |   // Why 3 slots? Because of the eval cache. | 
 |   static const int kEntrySize = 3; | 
 |   static const bool kMatchNeedsHoleCheck = true; | 
 | }; | 
 |  | 
 | class InfoCellPair { | 
 |  public: | 
 |   InfoCellPair() = default; | 
 |   inline InfoCellPair(Isolate* isolate, SharedFunctionInfo shared, | 
 |                       FeedbackCell feedback_cell); | 
 |  | 
 |   FeedbackCell feedback_cell() const { | 
 |     DCHECK(is_compiled_scope_.is_compiled()); | 
 |     return feedback_cell_; | 
 |   } | 
 |   SharedFunctionInfo shared() const { | 
 |     DCHECK(is_compiled_scope_.is_compiled()); | 
 |     return shared_; | 
 |   } | 
 |  | 
 |   bool has_feedback_cell() const { | 
 |     return !feedback_cell_.is_null() && is_compiled_scope_.is_compiled(); | 
 |   } | 
 |   bool has_shared() const { | 
 |     // Only return true if SFI is compiled - the bytecode could have been | 
 |     // flushed while it's in the compilation cache, and not yet have been | 
 |     // removed form the compilation cache. | 
 |     return !shared_.is_null() && is_compiled_scope_.is_compiled(); | 
 |   } | 
 |  | 
 |  private: | 
 |   IsCompiledScope is_compiled_scope_; | 
 |   SharedFunctionInfo shared_; | 
 |   FeedbackCell feedback_cell_; | 
 | }; | 
 |  | 
 | EXTERN_DECLARE_HASH_TABLE(CompilationCacheTable, CompilationCacheShape) | 
 |  | 
 | class CompilationCacheTable | 
 |     : public HashTable<CompilationCacheTable, CompilationCacheShape> { | 
 |  public: | 
 |   NEVER_READ_ONLY_SPACE | 
 |  | 
 |   // The 'script' cache contains SharedFunctionInfos. | 
 |   static MaybeHandle<SharedFunctionInfo> LookupScript( | 
 |       Handle<CompilationCacheTable> table, Handle<String> src, | 
 |       Handle<Context> native_context, LanguageMode language_mode); | 
 |   static Handle<CompilationCacheTable> PutScript( | 
 |       Handle<CompilationCacheTable> cache, Handle<String> src, | 
 |       Handle<Context> native_context, LanguageMode language_mode, | 
 |       Handle<SharedFunctionInfo> value); | 
 |  | 
 |   // Eval code only gets cached after a second probe for the | 
 |   // code object. To do so, on first "put" only a hash identifying the | 
 |   // source is entered into the cache, mapping it to a lifetime count of | 
 |   // the hash. On each call to Age all such lifetimes get reduced, and | 
 |   // removed once they reach zero. If a second put is called while such | 
 |   // a hash is live in the cache, the hash gets replaced by an actual | 
 |   // cache entry. Age also removes stale live entries from the cache. | 
 |   // Such entries are identified by SharedFunctionInfos pointing to | 
 |   // either the recompilation stub, or to "old" code. This avoids memory | 
 |   // leaks due to premature caching of eval strings that are | 
 |   // never needed later. | 
 |   static InfoCellPair LookupEval(Handle<CompilationCacheTable> table, | 
 |                                  Handle<String> src, | 
 |                                  Handle<SharedFunctionInfo> shared, | 
 |                                  Handle<Context> native_context, | 
 |                                  LanguageMode language_mode, int position); | 
 |   static Handle<CompilationCacheTable> PutEval( | 
 |       Handle<CompilationCacheTable> cache, Handle<String> src, | 
 |       Handle<SharedFunctionInfo> outer_info, Handle<SharedFunctionInfo> value, | 
 |       Handle<Context> native_context, Handle<FeedbackCell> feedback_cell, | 
 |       int position); | 
 |  | 
 |   // The RegExp cache contains JSRegExp::data fixed arrays. | 
 |   Handle<Object> LookupRegExp(Handle<String> source, JSRegExp::Flags flags); | 
 |   static Handle<CompilationCacheTable> PutRegExp( | 
 |       Isolate* isolate, Handle<CompilationCacheTable> cache, Handle<String> src, | 
 |       JSRegExp::Flags flags, Handle<FixedArray> value); | 
 |  | 
 |   // The Code cache shares native-context-independent (NCI) code between | 
 |   // contexts. | 
 |   MaybeHandle<Code> LookupCode(Handle<SharedFunctionInfo> key); | 
 |   static Handle<CompilationCacheTable> PutCode( | 
 |       Isolate* isolate, Handle<CompilationCacheTable> cache, | 
 |       Handle<SharedFunctionInfo> key, Handle<Code> value); | 
 |  | 
 |   void Remove(Object value); | 
 |   void Age(); | 
 |  | 
 |   DECL_CAST(CompilationCacheTable) | 
 |  | 
 |  private: | 
 |   void RemoveEntry(int entry_index); | 
 |  | 
 |   OBJECT_CONSTRUCTORS(CompilationCacheTable, | 
 |                       HashTable<CompilationCacheTable, CompilationCacheShape>); | 
 | }; | 
 |  | 
 | }  // namespace internal | 
 | }  // namespace v8 | 
 |  | 
 | #include "src/objects/object-macros-undef.h" | 
 |  | 
 | #endif  // V8_OBJECTS_COMPILATION_CACHE_TABLE_H_ |