Line data Source code
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_H_
6 : #define V8_OBJECTS_COMPILATION_CACHE_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 :
13 : // Has to be the last include (doesn't have include guards):
14 : #include "src/objects/object-macros.h"
15 :
16 : namespace v8 {
17 : namespace internal {
18 :
19 : class CompilationCacheShape : public BaseShape<HashTableKey*> {
20 : public:
21 : static inline bool IsMatch(HashTableKey* key, Object value) {
22 6837956 : return key->IsMatch(value);
23 : }
24 :
25 5733597 : static inline uint32_t Hash(Isolate* isolate, HashTableKey* key) {
26 : return key->Hash();
27 : }
28 :
29 : static inline uint32_t RegExpHash(String string, Smi flags);
30 :
31 : static inline uint32_t StringSharedHash(String source,
32 : SharedFunctionInfo shared,
33 : LanguageMode language_mode,
34 : int position);
35 :
36 : static inline uint32_t HashForObject(Isolate* isolate, Object object);
37 :
38 : static const int kPrefixSize = 0;
39 : static const int kEntrySize = 3;
40 : };
41 :
42 : class InfoCellPair {
43 : public:
44 7072118 : InfoCellPair() {}
45 : inline InfoCellPair(SharedFunctionInfo shared, FeedbackCell feedback_cell);
46 :
47 : FeedbackCell feedback_cell() const {
48 : DCHECK(is_compiled_scope_.is_compiled());
49 : return feedback_cell_;
50 : }
51 : SharedFunctionInfo shared() const {
52 : DCHECK(is_compiled_scope_.is_compiled());
53 : return shared_;
54 : }
55 :
56 : bool has_feedback_cell() const {
57 6147695 : return !feedback_cell_.is_null() && is_compiled_scope_.is_compiled();
58 : }
59 : bool has_shared() const {
60 : // Only return true if SFI is compiled - the bytecode could have been
61 : // flushed while it's in the compilation cache, and not yet have been
62 : // removed form the compilation cache.
63 14040411 : return !shared_.is_null() && is_compiled_scope_.is_compiled();
64 : }
65 :
66 : private:
67 : IsCompiledScope is_compiled_scope_;
68 : SharedFunctionInfo shared_;
69 : FeedbackCell feedback_cell_;
70 : };
71 :
72 : // This cache is used in two different variants. For regexp caching, it simply
73 : // maps identifying info of the regexp to the cached regexp object. Scripts and
74 : // eval code only gets cached after a second probe for the code object. To do
75 : // so, on first "put" only a hash identifying the source is entered into the
76 : // cache, mapping it to a lifetime count of the hash. On each call to Age all
77 : // such lifetimes get reduced, and removed once they reach zero. If a second put
78 : // is called while such a hash is live in the cache, the hash gets replaced by
79 : // an actual cache entry. Age also removes stale live entries from the cache.
80 : // Such entries are identified by SharedFunctionInfos pointing to either the
81 : // recompilation stub, or to "old" code. This avoids memory leaks due to
82 : // premature caching of scripts and eval strings that are never needed later.
83 : class CompilationCacheTable
84 : : public HashTable<CompilationCacheTable, CompilationCacheShape> {
85 : public:
86 : NEVER_READ_ONLY_SPACE
87 : static MaybeHandle<SharedFunctionInfo> LookupScript(
88 : Handle<CompilationCacheTable> table, Handle<String> src,
89 : Handle<Context> native_context, LanguageMode language_mode);
90 : static InfoCellPair LookupEval(Handle<CompilationCacheTable> table,
91 : Handle<String> src,
92 : Handle<SharedFunctionInfo> shared,
93 : Handle<Context> native_context,
94 : LanguageMode language_mode, int position);
95 : Handle<Object> LookupRegExp(Handle<String> source, JSRegExp::Flags flags);
96 : static Handle<CompilationCacheTable> PutScript(
97 : Handle<CompilationCacheTable> cache, Handle<String> src,
98 : Handle<Context> native_context, LanguageMode language_mode,
99 : Handle<SharedFunctionInfo> value);
100 : static Handle<CompilationCacheTable> PutEval(
101 : Handle<CompilationCacheTable> cache, Handle<String> src,
102 : Handle<SharedFunctionInfo> outer_info, Handle<SharedFunctionInfo> value,
103 : Handle<Context> native_context, Handle<FeedbackCell> feedback_cell,
104 : int position);
105 : static Handle<CompilationCacheTable> PutRegExp(
106 : Isolate* isolate, Handle<CompilationCacheTable> cache, Handle<String> src,
107 : JSRegExp::Flags flags, Handle<FixedArray> value);
108 : void Remove(Object value);
109 : void Age();
110 : static const int kHashGenerations = 10;
111 :
112 : DECL_CAST(CompilationCacheTable)
113 :
114 : private:
115 : OBJECT_CONSTRUCTORS(CompilationCacheTable,
116 : HashTable<CompilationCacheTable, CompilationCacheShape>);
117 : };
118 :
119 : } // namespace internal
120 : } // namespace v8
121 :
122 : #include "src/objects/object-macros-undef.h"
123 :
124 : #endif // V8_OBJECTS_COMPILATION_CACHE_H_
|