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 927734 : 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 : typedef base::Flags<Flag> Flags;
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* index, 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 : Handle<Name> name,
109 : AccessMode access_mode);
110 : Reduction ReduceNamedAccess(Node* node, Node* value,
111 : MapHandles const& receiver_maps,
112 : Handle<Name> name, AccessMode access_mode,
113 : Node* index = nullptr);
114 : Reduction ReduceGlobalAccess(Node* node, Node* receiver, Node* value,
115 : Handle<Name> name, AccessMode access_mode,
116 : Node* index = nullptr);
117 : Reduction ReduceGlobalAccess(Node* node, Node* receiver, Node* value,
118 : Handle<Name> name, AccessMode access_mode,
119 : Node* index,
120 : PropertyCellRef const& property_cell);
121 : Reduction ReduceKeyedLoadFromHeapConstant(Node* node, Node* index,
122 : FeedbackNexus const& nexus,
123 : AccessMode access_mode,
124 : KeyedAccessLoadMode load_mode);
125 : Reduction ReduceElementAccessOnString(Node* node, Node* index, Node* value,
126 : AccessMode access_mode,
127 : KeyedAccessLoadMode load_mode);
128 :
129 : Reduction ReduceSoftDeoptimize(Node* node, DeoptimizeReason reason);
130 : Reduction ReduceJSToString(Node* node);
131 :
132 : Reduction ReduceJSLoadPropertyWithEnumeratedKey(Node* node);
133 :
134 : const StringConstantBase* CreateDelayedStringConstant(Node* node);
135 :
136 : // A triple of nodes that represents a continuation.
137 : class ValueEffectControl final {
138 : public:
139 : ValueEffectControl()
140 : : value_(nullptr), effect_(nullptr), control_(nullptr) {}
141 : ValueEffectControl(Node* value, Node* effect, Node* control)
142 153286 : : value_(value), effect_(effect), control_(control) {}
143 :
144 : Node* value() const { return value_; }
145 : Node* effect() const { return effect_; }
146 : Node* control() const { return control_; }
147 :
148 : private:
149 : Node* value_;
150 : Node* effect_;
151 : Node* control_;
152 : };
153 :
154 : // Construct the appropriate subgraph for property access.
155 : ValueEffectControl BuildPropertyAccess(Node* receiver, Node* value,
156 : Node* context, Node* frame_state,
157 : Node* effect, Node* control,
158 : Handle<Name> name,
159 : ZoneVector<Node*>* if_exceptions,
160 : PropertyAccessInfo const& access_info,
161 : AccessMode access_mode);
162 : ValueEffectControl BuildPropertyLoad(Node* receiver, Node* context,
163 : Node* frame_state, Node* effect,
164 : Node* control, Handle<Name> name,
165 : ZoneVector<Node*>* if_exceptions,
166 : PropertyAccessInfo const& access_info);
167 :
168 : ValueEffectControl BuildPropertyStore(Node* receiver, Node* value,
169 : Node* context, Node* frame_state,
170 : Node* effect, Node* control,
171 : Handle<Name> name,
172 : ZoneVector<Node*>* if_exceptions,
173 : PropertyAccessInfo const& access_info,
174 : AccessMode access_mode);
175 :
176 : ValueEffectControl BuildPropertyTest(Node* effect, Node* control,
177 : PropertyAccessInfo const& access_info);
178 :
179 : // Helpers for accessor inlining.
180 : Node* InlinePropertyGetterCall(Node* receiver, Node* context,
181 : Node* frame_state, Node** effect,
182 : Node** control,
183 : ZoneVector<Node*>* if_exceptions,
184 : PropertyAccessInfo const& access_info);
185 : void InlinePropertySetterCall(Node* receiver, Node* value, Node* context,
186 : Node* frame_state, Node** effect,
187 : Node** control,
188 : ZoneVector<Node*>* if_exceptions,
189 : PropertyAccessInfo const& access_info);
190 : Node* InlineApiCall(Node* receiver, Node* holder, Node* frame_state,
191 : Node* value, Node** effect, Node** control,
192 : Handle<SharedFunctionInfo> shared_info,
193 : Handle<FunctionTemplateInfo> function_template_info);
194 :
195 : // Construct the appropriate subgraph for element access.
196 : ValueEffectControl BuildElementAccess(
197 : Node* receiver, Node* index, Node* value, Node* effect, Node* control,
198 : ElementAccessInfo const& access_info, AccessMode access_mode,
199 : KeyedAccessLoadMode load_mode, KeyedAccessStoreMode store_mode);
200 :
201 : // Construct appropriate subgraph to load from a String.
202 : Node* BuildIndexedStringLoad(Node* receiver, Node* index, Node* length,
203 : Node** effect, Node** control,
204 : KeyedAccessLoadMode load_mode);
205 :
206 : // Construct appropriate subgraph to extend properties backing store.
207 : Node* BuildExtendPropertiesBackingStore(const MapRef& map, Node* properties,
208 : Node* effect, Node* control);
209 :
210 : // Construct appropriate subgraph to check that the {value} matches
211 : // the previously recorded {name} feedback.
212 : Node* BuildCheckEqualsName(Handle<Name> name, Node* value, Node* effect,
213 : Node* control);
214 :
215 : // Checks if we can turn the hole into undefined when loading an element
216 : // from an object with one of the {receiver_maps}; sets up appropriate
217 : // code dependencies and might use the array protector cell.
218 : bool CanTreatHoleAsUndefined(MapHandles const& receiver_maps);
219 :
220 : // Extract receiver maps from {nexus} and filter based on {receiver} if
221 : // possible.
222 : bool ExtractReceiverMaps(Node* receiver, Node* effect,
223 : FeedbackNexus const& nexus,
224 : MapHandles* receiver_maps);
225 :
226 : // Try to infer maps for the given {receiver} at the current {effect}.
227 : bool InferReceiverMaps(Node* receiver, Node* effect,
228 : MapHandles* receiver_maps);
229 : // Try to infer a root map for the {receiver} independent of the current
230 : // program location.
231 : MaybeHandle<Map> InferReceiverRootMap(Node* receiver);
232 :
233 : // Checks if we know at compile time that the {receiver} either definitely
234 : // has the {prototype} in it's prototype chain, or the {receiver} definitely
235 : // doesn't have the {prototype} in it's prototype chain.
236 : enum InferHasInPrototypeChainResult {
237 : kIsInPrototypeChain,
238 : kIsNotInPrototypeChain,
239 : kMayBeInPrototypeChain
240 : };
241 : InferHasInPrototypeChainResult InferHasInPrototypeChain(
242 : Node* receiver, Node* effect, Handle<HeapObject> prototype);
243 :
244 : Graph* graph() const;
245 : JSGraph* jsgraph() const { return jsgraph_; }
246 :
247 : JSHeapBroker* broker() const { return broker_; }
248 : Isolate* isolate() const;
249 : Factory* factory() const;
250 : CommonOperatorBuilder* common() const;
251 : JSOperatorBuilder* javascript() const;
252 : SimplifiedOperatorBuilder* simplified() const;
253 : Flags flags() const { return flags_; }
254 : Handle<JSGlobalObject> global_object() const { return global_object_; }
255 : Handle<JSGlobalProxy> global_proxy() const { return global_proxy_; }
256 551 : NativeContextRef native_context() const { return broker()->native_context(); }
257 : CompilationDependencies* dependencies() const { return dependencies_; }
258 : Zone* zone() const { return zone_; }
259 : Zone* shared_zone() const { return shared_zone_; }
260 :
261 : JSGraph* const jsgraph_;
262 : JSHeapBroker* const broker_;
263 : Flags const flags_;
264 : Handle<JSGlobalObject> global_object_;
265 : Handle<JSGlobalProxy> global_proxy_;
266 : CompilationDependencies* const dependencies_;
267 : Zone* const zone_;
268 : Zone* const shared_zone_;
269 : TypeCache const* type_cache_;
270 :
271 : DISALLOW_COPY_AND_ASSIGN(JSNativeContextSpecialization);
272 : };
273 :
274 : DEFINE_OPERATORS_FOR_FLAGS(JSNativeContextSpecialization::Flags)
275 :
276 : } // namespace compiler
277 : } // namespace internal
278 : } // namespace v8
279 :
280 : #endif // V8_COMPILER_JS_NATIVE_CONTEXT_SPECIALIZATION_H_
|