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