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 Factory;
18 : class FeedbackNexus;
19 : class JSGlobalObject;
20 : class JSGlobalProxy;
21 : class StringConstantBase;
22 :
23 : namespace compiler {
24 :
25 : // Forward declarations.
26 : enum class AccessMode;
27 : class CommonOperatorBuilder;
28 : class CompilationDependencies;
29 : class ElementAccessInfo;
30 : class JSGraph;
31 : class JSHeapBroker;
32 : class JSOperatorBuilder;
33 : class MachineOperatorBuilder;
34 : class PropertyAccessInfo;
35 : class SimplifiedOperatorBuilder;
36 : class TypeCache;
37 :
38 : // Specializes a given JSGraph to a given native context, potentially constant
39 : // folding some {LoadGlobal} nodes or strength reducing some {StoreGlobal}
40 : // nodes. And also specializes {LoadNamed} and {StoreNamed} nodes according
41 : // to type feedback (if available).
42 928404 : class V8_EXPORT_PRIVATE JSNativeContextSpecialization final
43 : : public AdvancedReducer {
44 : public:
45 : // Flags that control the mode of operation.
46 : enum Flag {
47 : kNoFlags = 0u,
48 : kAccessorInliningEnabled = 1u << 0,
49 : kBailoutOnUninitialized = 1u << 1
50 : };
51 : using Flags = base::Flags<Flag>;
52 :
53 : JSNativeContextSpecialization(Editor* editor, JSGraph* jsgraph,
54 : JSHeapBroker* broker, Flags flags,
55 : Handle<Context> native_context,
56 : CompilationDependencies* dependencies,
57 : Zone* zone, Zone* shared_zone);
58 :
59 19 : const char* reducer_name() const override {
60 19 : return "JSNativeContextSpecialization";
61 : }
62 :
63 : Reduction Reduce(Node* node) final;
64 :
65 : // Utility for folding string constant concatenation.
66 : // Supports JSAdd nodes and nodes typed as string or number.
67 : // Public for the sake of unit testing.
68 : static base::Optional<size_t> GetMaxStringLength(JSHeapBroker* broker,
69 : Node* node);
70 :
71 : private:
72 : Reduction ReduceJSAdd(Node* node);
73 : Reduction ReduceJSAsyncFunctionEnter(Node* node);
74 : Reduction ReduceJSAsyncFunctionReject(Node* node);
75 : Reduction ReduceJSAsyncFunctionResolve(Node* node);
76 : Reduction ReduceJSGetSuperConstructor(Node* node);
77 : Reduction ReduceJSInstanceOf(Node* node);
78 : Reduction ReduceJSHasInPrototypeChain(Node* node);
79 : Reduction ReduceJSOrdinaryHasInstance(Node* node);
80 : Reduction ReduceJSPromiseResolve(Node* node);
81 : Reduction ReduceJSResolvePromise(Node* node);
82 : Reduction ReduceJSLoadContext(Node* node);
83 : Reduction ReduceJSLoadGlobal(Node* node);
84 : Reduction ReduceJSStoreGlobal(Node* node);
85 : Reduction ReduceJSLoadNamed(Node* node);
86 : Reduction ReduceJSStoreNamed(Node* node);
87 : Reduction ReduceJSHasProperty(Node* node);
88 : Reduction ReduceJSLoadProperty(Node* node);
89 : Reduction ReduceJSStoreProperty(Node* node);
90 : Reduction ReduceJSStoreNamedOwn(Node* node);
91 : Reduction ReduceJSStoreDataPropertyInLiteral(Node* node);
92 : Reduction ReduceJSStoreInArrayLiteral(Node* node);
93 : Reduction ReduceJSToObject(Node* node);
94 :
95 : Reduction ReduceElementAccess(Node* node, Node* index, Node* value,
96 : FeedbackNexus const& nexus,
97 : MapHandles const& receiver_maps,
98 : AccessMode access_mode,
99 : KeyedAccessLoadMode load_mode,
100 : KeyedAccessStoreMode store_mode);
101 : Reduction ReduceKeyedAccess(Node* node, Node* key, Node* value,
102 : FeedbackNexus const& nexus,
103 : AccessMode access_mode,
104 : KeyedAccessLoadMode load_mode,
105 : KeyedAccessStoreMode store_mode);
106 : Reduction ReduceNamedAccessFromNexus(Node* node, Node* value,
107 : FeedbackNexus const& nexus,
108 : NameRef const& name,
109 : AccessMode access_mode);
110 : Reduction ReduceNamedAccess(Node* node, Node* value,
111 : MapHandles const& receiver_maps,
112 : NameRef const& name, AccessMode access_mode,
113 : Node* key = nullptr);
114 : Reduction ReduceGlobalAccess(Node* node, Node* receiver, Node* value,
115 : NameRef const& name, AccessMode access_mode,
116 : Node* key = nullptr);
117 : Reduction ReduceGlobalAccess(Node* node, Node* receiver, Node* value,
118 : NameRef const& name, AccessMode access_mode,
119 : Node* key, PropertyCellRef const& property_cell);
120 : Reduction ReduceKeyedLoadFromHeapConstant(Node* node, Node* key,
121 : FeedbackNexus const& nexus,
122 : AccessMode access_mode,
123 : KeyedAccessLoadMode load_mode);
124 : Reduction ReduceElementAccessOnString(Node* node, Node* index, Node* value,
125 : AccessMode access_mode,
126 : KeyedAccessLoadMode load_mode);
127 :
128 : Reduction ReduceSoftDeoptimize(Node* node, DeoptimizeReason reason);
129 : Reduction ReduceJSToString(Node* node);
130 :
131 : Reduction ReduceJSLoadPropertyWithEnumeratedKey(Node* node);
132 :
133 : const StringConstantBase* CreateDelayedStringConstant(Node* node);
134 :
135 : // A triple of nodes that represents a continuation.
136 : class ValueEffectControl final {
137 : public:
138 : ValueEffectControl()
139 : : value_(nullptr), effect_(nullptr), control_(nullptr) {}
140 : ValueEffectControl(Node* value, Node* effect, Node* control)
141 156429 : : value_(value), effect_(effect), control_(control) {}
142 :
143 : Node* value() const { return value_; }
144 : Node* effect() const { return effect_; }
145 : Node* control() const { return control_; }
146 :
147 : private:
148 : Node* value_;
149 : Node* effect_;
150 : Node* control_;
151 : };
152 :
153 : // Construct the appropriate subgraph for property access.
154 : ValueEffectControl BuildPropertyAccess(Node* receiver, Node* value,
155 : Node* context, Node* frame_state,
156 : Node* effect, Node* control,
157 : NameRef const& name,
158 : ZoneVector<Node*>* if_exceptions,
159 : PropertyAccessInfo const& access_info,
160 : AccessMode access_mode);
161 : ValueEffectControl BuildPropertyLoad(Node* receiver, Node* context,
162 : Node* frame_state, Node* effect,
163 : Node* control, NameRef const& name,
164 : ZoneVector<Node*>* if_exceptions,
165 : PropertyAccessInfo const& access_info);
166 :
167 : ValueEffectControl BuildPropertyStore(Node* receiver, Node* value,
168 : Node* context, Node* frame_state,
169 : Node* effect, Node* control,
170 : NameRef const& name,
171 : ZoneVector<Node*>* if_exceptions,
172 : PropertyAccessInfo const& access_info,
173 : AccessMode access_mode);
174 :
175 : ValueEffectControl BuildPropertyTest(Node* effect, Node* control,
176 : PropertyAccessInfo const& access_info);
177 :
178 : // Helpers for accessor inlining.
179 : Node* InlinePropertyGetterCall(Node* receiver, Node* context,
180 : Node* frame_state, Node** effect,
181 : Node** control,
182 : ZoneVector<Node*>* if_exceptions,
183 : PropertyAccessInfo const& access_info);
184 : void InlinePropertySetterCall(Node* receiver, Node* value, Node* context,
185 : Node* frame_state, Node** effect,
186 : Node** control,
187 : ZoneVector<Node*>* if_exceptions,
188 : PropertyAccessInfo const& access_info);
189 : Node* InlineApiCall(Node* receiver, Node* holder, Node* frame_state,
190 : Node* value, Node** effect, Node** control,
191 : SharedFunctionInfoRef const& shared_info,
192 : FunctionTemplateInfoRef const& function_template_info);
193 :
194 : // Construct the appropriate subgraph for element access.
195 : ValueEffectControl BuildElementAccess(
196 : Node* receiver, Node* index, Node* value, Node* effect, Node* control,
197 : ElementAccessInfo const& access_info, AccessMode access_mode,
198 : KeyedAccessLoadMode load_mode, KeyedAccessStoreMode store_mode);
199 :
200 : // Construct appropriate subgraph to load from a String.
201 : Node* BuildIndexedStringLoad(Node* receiver, Node* index, Node* length,
202 : Node** effect, Node** control,
203 : KeyedAccessLoadMode load_mode);
204 :
205 : // Construct appropriate subgraph to extend properties backing store.
206 : Node* BuildExtendPropertiesBackingStore(const MapRef& map, Node* properties,
207 : Node* effect, Node* control);
208 :
209 : // Construct appropriate subgraph to check that the {value} matches
210 : // the previously recorded {name} feedback.
211 : Node* BuildCheckEqualsName(NameRef const& name, Node* value, Node* effect,
212 : Node* control);
213 :
214 : // Checks if we can turn the hole into undefined when loading an element
215 : // from an object with one of the {receiver_maps}; sets up appropriate
216 : // code dependencies and might use the array protector cell.
217 : bool CanTreatHoleAsUndefined(MapHandles const& receiver_maps);
218 :
219 : // Extract receiver maps from {nexus} and filter based on {receiver} if
220 : // possible.
221 : bool ExtractReceiverMaps(Node* receiver, Node* effect,
222 : FeedbackNexus const& nexus,
223 : MapHandles* receiver_maps);
224 :
225 : // Try to infer maps for the given {receiver} at the current {effect}.
226 : bool InferReceiverMaps(Node* receiver, Node* effect,
227 : MapHandles* receiver_maps);
228 : // Try to infer a root map for the {receiver} independent of the current
229 : // program location.
230 : MaybeHandle<Map> InferReceiverRootMap(Node* receiver);
231 :
232 : // Checks if we know at compile time that the {receiver} either definitely
233 : // has the {prototype} in it's prototype chain, or the {receiver} definitely
234 : // doesn't have the {prototype} in it's prototype chain.
235 : enum InferHasInPrototypeChainResult {
236 : kIsInPrototypeChain,
237 : kIsNotInPrototypeChain,
238 : kMayBeInPrototypeChain
239 : };
240 : InferHasInPrototypeChainResult InferHasInPrototypeChain(
241 : Node* receiver, Node* effect, Handle<HeapObject> prototype);
242 :
243 : Graph* graph() const;
244 : JSGraph* jsgraph() const { return jsgraph_; }
245 :
246 : JSHeapBroker* broker() const { return broker_; }
247 : Isolate* isolate() const;
248 : Factory* factory() const;
249 : CommonOperatorBuilder* common() const;
250 : JSOperatorBuilder* javascript() const;
251 : SimplifiedOperatorBuilder* simplified() const;
252 : Flags flags() const { return flags_; }
253 : Handle<JSGlobalObject> global_object() const { return global_object_; }
254 : Handle<JSGlobalProxy> global_proxy() const { return global_proxy_; }
255 66020 : NativeContextRef native_context() const { return broker()->native_context(); }
256 : CompilationDependencies* dependencies() const { return dependencies_; }
257 : Zone* zone() const { return zone_; }
258 : Zone* shared_zone() const { return shared_zone_; }
259 :
260 : JSGraph* const jsgraph_;
261 : JSHeapBroker* const broker_;
262 : Flags const flags_;
263 : Handle<JSGlobalObject> global_object_;
264 : Handle<JSGlobalProxy> global_proxy_;
265 : CompilationDependencies* const dependencies_;
266 : Zone* const zone_;
267 : Zone* const shared_zone_;
268 : TypeCache const* type_cache_;
269 :
270 : DISALLOW_COPY_AND_ASSIGN(JSNativeContextSpecialization);
271 : };
272 :
273 : DEFINE_OPERATORS_FOR_FLAGS(JSNativeContextSpecialization::Flags)
274 :
275 : } // namespace compiler
276 : } // namespace internal
277 : } // namespace v8
278 :
279 : #endif // V8_COMPILER_JS_NATIVE_CONTEXT_SPECIALIZATION_H_
|