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