v8
V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++.
Loading...
Searching...
No Matches
js-native-context-specialization.h
Go to the documentation of this file.
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 <optional>
9
10#include "src/base/flags.h"
16
17namespace v8 {
18namespace internal {
19
20// Forward declarations.
21class Factory;
22class JSGlobalObject;
23class JSGlobalProxy;
24
25namespace compiler {
26
27// Forward declarations.
28enum class AccessMode;
29class CommonOperatorBuilder;
30class CompilationDependencies;
31class ElementAccessInfo;
32class JSGraph;
33class JSHeapBroker;
34class JSOperatorBuilder;
35class MachineOperatorBuilder;
36class PropertyAccessInfo;
37class SimplifiedOperatorBuilder;
38class TypeCache;
39
40// Specializes a given JSGraph to a given native context, potentially constant
41// folding some {LoadGlobal} nodes or strength reducing some {StoreGlobal}
42// nodes. And also specializes {LoadNamed} and {SetNamedProperty} nodes
43// according to type feedback (if available).
45 : public AdvancedReducer {
46 public:
47 // Flags that control the mode of operation.
48 enum Flag {
51 };
53
55 JSHeapBroker* broker, Flags flags, Zone* zone,
56 Zone* shared_zone);
59 const JSNativeContextSpecialization&) = delete;
60
61 const char* reducer_name() const override {
62 return "JSNativeContextSpecialization";
63 }
64
65 Reduction Reduce(Node* node) final;
66
67 // Utility for folding string constant concatenation.
68 // Supports JSAdd nodes and nodes typed as string or number.
69 // Public for the sake of unit testing.
70 static std::optional<size_t> GetMaxStringLength(JSHeapBroker* broker,
71 Node* node);
72
73 private:
74 Reduction ReduceJSAdd(Node* node);
75 Reduction ReduceJSAsyncFunctionEnter(Node* node);
76 Reduction ReduceJSAsyncFunctionReject(Node* node);
77 Reduction ReduceJSAsyncFunctionResolve(Node* node);
78 Reduction ReduceJSGetSuperConstructor(Node* node);
79 Reduction ReduceJSFindNonDefaultConstructorOrConstruct(Node* node);
80 Reduction ReduceJSInstanceOf(Node* node);
81 Reduction ReduceJSHasInPrototypeChain(Node* node);
82 Reduction ReduceJSOrdinaryHasInstance(Node* node);
83 Reduction ReduceJSPromiseResolve(Node* node);
84 Reduction ReduceJSResolvePromise(Node* node);
85 Reduction ReduceJSLoadGlobal(Node* node);
86 Reduction ReduceJSStoreGlobal(Node* node);
87 Reduction ReduceJSLoadNamed(Node* node);
88 Reduction ReduceJSLoadNamedFromSuper(Node* node);
89 Reduction ReduceJSGetIterator(Node* node);
90 Reduction ReduceJSSetNamedProperty(Node* node);
91 Reduction ReduceJSHasProperty(Node* node);
92 Reduction ReduceJSLoadProperty(Node* node);
93 Reduction ReduceJSSetKeyedProperty(Node* node);
94 Reduction ReduceJSDefineKeyedOwnProperty(Node* node);
95 Reduction ReduceJSDefineNamedOwnProperty(Node* node);
96 Reduction ReduceJSDefineKeyedOwnPropertyInLiteral(Node* node);
97 Reduction ReduceJSStoreInArrayLiteral(Node* node);
98 Reduction ReduceJSToObject(Node* node);
99
100 Reduction ReduceElementAccess(Node* node, Node* index, Node* value,
101 ElementAccessFeedback const& feedback);
102 // In the case of non-keyed (named) accesses, pass the name as {static_name}
103 // and use {nullptr} for {key} (load/store modes are irrelevant).
104 Reduction ReducePropertyAccess(Node* node, Node* key,
105 OptionalNameRef static_name, Node* value,
106 FeedbackSource const& source,
107 AccessMode access_mode);
108 Reduction ReduceNamedAccess(Node* node, Node* value,
109 NamedAccessFeedback const& feedback,
110 AccessMode access_mode, Node* key = nullptr);
111 Reduction ReduceMegaDOMPropertyAccess(
112 Node* node, Node* value, MegaDOMPropertyAccessFeedback const& feedback,
113 FeedbackSource const& source);
114 Reduction ReduceGlobalAccess(Node* node, Node* lookup_start_object,
115 Node* receiver, Node* value, NameRef name,
116 AccessMode access_mode, Node* key,
117 PropertyCellRef property_cell,
118 Node* effect = nullptr);
119 Reduction ReduceElementLoadFromHeapConstant(Node* node, Node* key,
120 AccessMode access_mode,
121 KeyedAccessLoadMode load_mode);
122 Reduction ReduceElementAccessOnString(Node* node, Node* index, Node* value,
123 KeyedAccessMode const& keyed_mode);
124
125 Reduction ReduceEagerDeoptimize(Node* node, DeoptimizeReason reason);
126 Reduction ReduceJSToString(Node* node);
127
128 Reduction ReduceJSLoadPropertyWithEnumeratedKey(Node* node);
129
130 Handle<String> CreateStringConstant(Node* node);
131
132 // A triple of nodes that represents a continuation.
133 class ValueEffectControl final {
134 public:
136 : value_(nullptr), effect_(nullptr), control_(nullptr) {}
137 ValueEffectControl(Node* value, Node* effect, Node* control)
138 : value_(value), effect_(effect), control_(control) {}
139
140 Node* value() const { return value_; }
141 Node* effect() const { return effect_; }
142 Node* control() const { return control_; }
143
144 private:
148 };
149
150 // Construct the appropriate subgraph for property access. Return {} if the
151 // property access couldn't be built.
152 std::optional<ValueEffectControl> BuildPropertyAccess(
153 Node* lookup_start_object, Node* receiver, Node* value, Node* context,
154 Node* frame_state, Node* effect, Node* control, NameRef name,
155 ZoneVector<Node*>* if_exceptions, PropertyAccessInfo const& access_info,
156 AccessMode access_mode);
157 std::optional<ValueEffectControl> BuildPropertyLoad(
158 Node* lookup_start_object, Node* receiver, Node* context,
159 Node* frame_state, Node* effect, Node* control, NameRef name,
160 ZoneVector<Node*>* if_exceptions, PropertyAccessInfo const& access_info);
161
162 ValueEffectControl BuildPropertyStore(Node* receiver, Node* value,
163 Node* context, Node* frame_state,
164 Node* effect, Node* control,
165 NameRef name,
166 ZoneVector<Node*>* if_exceptions,
167 PropertyAccessInfo const& access_info,
168 AccessMode access_mode);
169
170 ValueEffectControl BuildPropertyTest(Node* effect, Node* control,
171 PropertyAccessInfo const& access_info);
172
173 // Helpers for accessor inlining.
174 Node* InlinePropertyGetterCall(Node* receiver,
175 ConvertReceiverMode receiver_mode,
176 Node* lookup_start_object, Node* context,
177 Node* frame_state, Node** effect,
178 Node** control,
179 ZoneVector<Node*>* if_exceptions,
180 PropertyAccessInfo const& access_info);
181 void InlinePropertySetterCall(Node* receiver, Node* value, Node* context,
182 Node* frame_state, Node** effect,
183 Node** control,
184 ZoneVector<Node*>* if_exceptions,
185 PropertyAccessInfo const& access_info);
186 Node* InlineApiCall(Node* receiver, Node* frame_state, Node* value,
187 Node** effect, Node** control,
188 FunctionTemplateInfoRef function_template_info,
189 const FeedbackSource& feedback);
190
191 // Construct the appropriate subgraph for element access.
192 ValueEffectControl BuildElementAccess(Node* receiver, Node* index,
193 Node* value, Node* effect,
194 Node* control, Node* context,
195 ElementAccessInfo const& access_info,
196 KeyedAccessMode const& keyed_mode);
197 ValueEffectControl BuildElementAccessForTypedArrayOrRabGsabTypedArray(
198 Node* receiver, Node* index, Node* value, Node* effect, Node* control,
199 Node* context, ElementsKind elements_kind,
200 KeyedAccessMode const& keyed_mode);
201
202 // Construct appropriate subgraph to load from a String.
203 Node* BuildIndexedStringLoad(Node* receiver, Node* index, Node* length,
204 Node** effect, Node** control,
205 KeyedAccessLoadMode load_mode);
206
207 // Construct appropriate subgraph to extend properties backing store.
208 Node* BuildExtendPropertiesBackingStore(MapRef map, Node* properties,
209 Node* effect, Node* control);
210
211 // Construct appropriate subgraph to check that the {value} matches
212 // the previously recorded {name} feedback.
213 Node* BuildCheckEqualsName(NameRef name, Node* value, Node* effect,
214 Node* control);
215
216 // Concatenates {left} and {right}.
217 Handle<String> Concatenate(Handle<String> left, Handle<String> right);
218
219 // Returns true if {str} can safely be read:
220 // - if we are on the main thread, then any string can safely be read
221 // - in the background, we can only read some string shapes, except if we
222 // created the string ourselves.
223 // {node} is the node from which we got {str}, but which is still taken as
224 // parameter to simplify the checks.
225 bool StringCanSafelyBeRead(Node* const node, Handle<String> str);
226
227 // Checks if we can turn the hole into undefined when loading an element
228 // from an object with one of the {receiver_maps}; sets up appropriate
229 // code dependencies and might use the array protector cell.
230 bool CanTreatHoleAsUndefined(ZoneVector<MapRef> const& receiver_maps);
231
232 void RemoveImpossibleMaps(Node* object, ZoneVector<MapRef>* maps) const;
233
234 ElementAccessFeedback const& TryRefineElementAccessFeedback(
235 ElementAccessFeedback const& feedback, Node* receiver,
236 Effect effect) const;
237
238 // Try to infer maps for the given {object} at the current {effect}.
239 bool InferMaps(Node* object, Effect effect, ZoneVector<MapRef>* maps) const;
240
241 // Try to infer a root map for the {object} independent of the current program
242 // location.
243 OptionalMapRef InferRootMap(Node* object) const;
244
245 // Checks if we know at compile time that the {receiver} either definitely
246 // has the {prototype} in it's prototype chain, or the {receiver} definitely
247 // doesn't have the {prototype} in it's prototype chain.
253 InferHasInPrototypeChainResult InferHasInPrototypeChain(
254 Node* receiver, Effect effect, HeapObjectRef prototype);
255
256 Node* BuildLoadPrototypeFromObject(Node* object, Node* effect, Node* control);
257
258 std::pair<Node*, Node*> ReleaseEffectAndControlFromAssembler(
259 JSGraphAssembler* assembler);
260
261 TFGraph* graph() const;
262 JSGraph* jsgraph() const { return jsgraph_; }
263
264 JSHeapBroker* broker() const { return broker_; }
265 Isolate* isolate() const;
266 Factory* factory() const;
267 CommonOperatorBuilder* common() const;
268 JSOperatorBuilder* javascript() const;
270 Flags flags() const { return flags_; }
271 DirectHandle<JSGlobalObject> global_object() const { return global_object_; }
272 DirectHandle<JSGlobalProxy> global_proxy() const { return global_proxy_; }
274 return broker()->target_native_context();
275 }
277 return broker()->dependencies();
278 }
279 Zone* zone() const { return zone_; }
280 Zone* shared_zone() const { return shared_zone_; }
281
287 Zone* const zone_;
293};
294
296
297} // namespace compiler
298} // namespace internal
299} // namespace v8
300
301#endif // V8_COMPILER_JS_NATIVE_CONTEXT_SPECIALIZATION_H_
TFGraph * graph
JSGraph * jsgraph
SimplifiedOperatorBuilder * simplified
#define DEFINE_OPERATORS_FOR_FLAGS(Type)
Definition flags.h:100
JSNativeContextSpecialization(const JSNativeContextSpecialization &)=delete
ZoneUnorderedSet< IndirectHandle< String >, IndirectHandle< String >::hash, IndirectHandle< String >::equal_to > created_strings_
JSNativeContextSpecialization & operator=(const JSNativeContextSpecialization &)=delete
Zone * zone_
Register const value_
JSRegExp::Flags flags_
JSHeapBroker *const broker_
Isolate * isolate
JSHeapBroker * broker
Control control_
TNode< Object > receiver
Effect effect_
#define V8_EXPORT_PRIVATE
Definition macros.h:460
std::unique_ptr< ValueMirror > key