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