Line data Source code
1 : // Copyright 2015 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_COMPILER_JS_NATIVE_CONTEXT_SPECIALIZATION_H_
6 : #define V8_COMPILER_JS_NATIVE_CONTEXT_SPECIALIZATION_H_
7 :
8 : #include "src/base/flags.h"
9 : #include "src/compiler/graph-reducer.h"
10 : #include "src/deoptimize-reason.h"
11 : #include "src/feedback-vector.h"
12 :
13 : namespace v8 {
14 : namespace internal {
15 :
16 : // Forward declarations.
17 : class CompilationDependencies;
18 : class Factory;
19 :
20 : namespace compiler {
21 :
22 : // Forward declarations.
23 : enum class AccessMode;
24 : class CommonOperatorBuilder;
25 : class ElementAccessInfo;
26 : class JSGraph;
27 : class JSOperatorBuilder;
28 : class MachineOperatorBuilder;
29 : class PropertyAccessInfo;
30 : class SimplifiedOperatorBuilder;
31 : class TypeCache;
32 :
33 : // Specializes a given JSGraph to a given native context, potentially constant
34 : // folding some {LoadGlobal} nodes or strength reducing some {StoreGlobal}
35 : // nodes. And also specializes {LoadNamed} and {StoreNamed} nodes according
36 : // to type feedback (if available).
37 395343 : class JSNativeContextSpecialization final : public AdvancedReducer {
38 : public:
39 : // Flags that control the mode of operation.
40 : enum Flag {
41 : kNoFlags = 0u,
42 : kAccessorInliningEnabled = 1u << 0,
43 : kBailoutOnUninitialized = 1u << 1
44 : };
45 : typedef base::Flags<Flag> Flags;
46 :
47 : JSNativeContextSpecialization(Editor* editor, JSGraph* jsgraph, Flags flags,
48 : Handle<Context> native_context,
49 : CompilationDependencies* dependencies,
50 : Zone* zone);
51 :
52 : Reduction Reduce(Node* node) final;
53 :
54 : private:
55 : Reduction ReduceJSAdd(Node* node);
56 : Reduction ReduceJSGetSuperConstructor(Node* node);
57 : Reduction ReduceJSInstanceOf(Node* node);
58 : Reduction ReduceJSOrdinaryHasInstance(Node* node);
59 : Reduction ReduceJSLoadContext(Node* node);
60 : Reduction ReduceJSLoadGlobal(Node* node);
61 : Reduction ReduceJSStoreGlobal(Node* node);
62 : Reduction ReduceJSLoadNamed(Node* node);
63 : Reduction ReduceJSStoreNamed(Node* node);
64 : Reduction ReduceJSLoadProperty(Node* node);
65 : Reduction ReduceJSStoreProperty(Node* node);
66 : Reduction ReduceJSStoreNamedOwn(Node* node);
67 : Reduction ReduceJSStoreDataPropertyInLiteral(Node* node);
68 :
69 : Reduction ReduceElementAccess(Node* node, Node* index, Node* value,
70 : MapHandleList const& receiver_maps,
71 : AccessMode access_mode,
72 : LanguageMode language_mode,
73 : KeyedAccessStoreMode store_mode);
74 : template <typename KeyedICNexus>
75 : Reduction ReduceKeyedAccess(Node* node, Node* index, Node* value,
76 : KeyedICNexus const& nexus, AccessMode access_mode,
77 : LanguageMode language_mode,
78 : KeyedAccessStoreMode store_mode);
79 : Reduction ReduceNamedAccessFromNexus(Node* node, Node* value,
80 : FeedbackNexus const& nexus,
81 : Handle<Name> name,
82 : AccessMode access_mode,
83 : LanguageMode language_mode);
84 : Reduction ReduceNamedAccess(Node* node, Node* value,
85 : MapHandleList const& receiver_maps,
86 : Handle<Name> name, AccessMode access_mode,
87 : LanguageMode language_mode,
88 : Node* index = nullptr);
89 : Reduction ReduceGlobalAccess(Node* node, Node* receiver, Node* value,
90 : Handle<Name> name, AccessMode access_mode,
91 : Node* index = nullptr);
92 :
93 : Reduction ReduceSoftDeoptimize(Node* node, DeoptimizeReason reason);
94 :
95 : // A triple of nodes that represents a continuation.
96 : class ValueEffectControl final {
97 : public:
98 : ValueEffectControl(Node* value, Node* effect, Node* control)
99 116189 : : value_(value), effect_(effect), control_(control) {}
100 :
101 : Node* value() const { return value_; }
102 : Node* effect() const { return effect_; }
103 : Node* control() const { return control_; }
104 :
105 : private:
106 : Node* const value_;
107 : Node* const effect_;
108 : Node* const control_;
109 : };
110 :
111 : // Construct the appropriate subgraph for property access.
112 : ValueEffectControl BuildPropertyAccess(Node* receiver, Node* value,
113 : Node* context, Node* frame_state,
114 : Node* effect, Node* control,
115 : Handle<Name> name,
116 : PropertyAccessInfo const& access_info,
117 : AccessMode access_mode,
118 : LanguageMode language_mode);
119 :
120 : // Construct the appropriate subgraph for element access.
121 : ValueEffectControl BuildElementAccess(Node* receiver, Node* index,
122 : Node* value, Node* effect,
123 : Node* control,
124 : ElementAccessInfo const& access_info,
125 : AccessMode access_mode,
126 : KeyedAccessStoreMode store_mode);
127 :
128 : // Construct an appropriate heap object check.
129 : Node* BuildCheckHeapObject(Node* receiver, Node** effect, Node* control);
130 :
131 : // Construct an appropriate map check.
132 : Node* BuildCheckMaps(Node* receiver, Node* effect, Node* control,
133 : std::vector<Handle<Map>> const& maps);
134 :
135 : // Construct appropriate subgraph to extend properties backing store.
136 : Node* BuildExtendPropertiesBackingStore(Handle<Map> map, Node* properties,
137 : Node* effect, Node* control);
138 :
139 : // Adds stability dependencies on all prototypes of every class in
140 : // {receiver_type} up to (and including) the {holder}.
141 : void AssumePrototypesStable(std::vector<Handle<Map>> const& receiver_maps,
142 : Handle<JSObject> holder);
143 :
144 : // Checks if we can turn the hole into undefined when loading an element
145 : // from an object with one of the {receiver_maps}; sets up appropriate
146 : // code dependencies and might use the array protector cell.
147 : bool CanTreatHoleAsUndefined(std::vector<Handle<Map>> const& receiver_maps);
148 :
149 : // Checks if we know at compile time that the {receiver} either definitely
150 : // has the {prototype} in it's prototype chain, or the {receiver} definitely
151 : // doesn't have the {prototype} in it's prototype chain.
152 : enum InferHasInPrototypeChainResult {
153 : kIsInPrototypeChain,
154 : kIsNotInPrototypeChain,
155 : kMayBeInPrototypeChain
156 : };
157 : InferHasInPrototypeChainResult InferHasInPrototypeChain(
158 : Node* receiver, Node* effect, Handle<JSReceiver> prototype);
159 :
160 : // Extract receiver maps from {nexus} and filter based on {receiver} if
161 : // possible.
162 : bool ExtractReceiverMaps(Node* receiver, Node* effect,
163 : FeedbackNexus const& nexus,
164 : MapHandleList* receiver_maps);
165 :
166 : // Try to infer maps for the given {receiver} at the current {effect}.
167 : // If maps are returned then you can be sure that the {receiver} definitely
168 : // has one of the returned maps at this point in the program (identified
169 : // by {effect}).
170 : bool InferReceiverMaps(Node* receiver, Node* effect,
171 : MapHandleList* receiver_maps);
172 : // Try to infer a root map for the {receiver} independent of the current
173 : // program location.
174 : MaybeHandle<Map> InferReceiverRootMap(Node* receiver);
175 :
176 : ValueEffectControl InlineApiCall(
177 : Node* receiver, Node* context, Node* target, Node* frame_state,
178 : Node* parameter, Node* effect, Node* control,
179 : Handle<SharedFunctionInfo> shared_info,
180 : Handle<FunctionTemplateInfo> function_template_info);
181 :
182 : // Script context lookup logic.
183 : struct ScriptContextTableLookupResult;
184 : bool LookupInScriptContextTable(Handle<Name> name,
185 : ScriptContextTableLookupResult* result);
186 :
187 : Graph* graph() const;
188 : JSGraph* jsgraph() const { return jsgraph_; }
189 : Isolate* isolate() const;
190 : Factory* factory() const;
191 : CommonOperatorBuilder* common() const;
192 : JSOperatorBuilder* javascript() const;
193 : SimplifiedOperatorBuilder* simplified() const;
194 : MachineOperatorBuilder* machine() const;
195 : Flags flags() const { return flags_; }
196 : Handle<JSGlobalObject> global_object() const { return global_object_; }
197 : Handle<JSGlobalProxy> global_proxy() const { return global_proxy_; }
198 : Handle<Context> native_context() const { return native_context_; }
199 : CompilationDependencies* dependencies() const { return dependencies_; }
200 : Zone* zone() const { return zone_; }
201 :
202 : JSGraph* const jsgraph_;
203 : Flags const flags_;
204 : Handle<JSGlobalObject> global_object_;
205 : Handle<JSGlobalProxy> global_proxy_;
206 : Handle<Context> native_context_;
207 : CompilationDependencies* const dependencies_;
208 : Zone* const zone_;
209 : TypeCache const& type_cache_;
210 :
211 : DISALLOW_COPY_AND_ASSIGN(JSNativeContextSpecialization);
212 : };
213 :
214 : DEFINE_OPERATORS_FOR_FLAGS(JSNativeContextSpecialization::Flags)
215 :
216 : } // namespace compiler
217 : } // namespace internal
218 : } // namespace v8
219 :
220 : #endif // V8_COMPILER_JS_NATIVE_CONTEXT_SPECIALIZATION_H_
|