v8
V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++.
Loading...
Searching...
No Matches
js-call-reducer.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_CALL_REDUCER_H_
6#define V8_COMPILER_JS_CALL_REDUCER_H_
7
8#include <optional>
9
10#include "src/base/flags.h"
15
16namespace v8 {
17namespace internal {
18
19// Forward declarations.
20class Factory;
21class JSGlobalProxy;
22
23namespace compiler {
24
25// Forward declarations.
26class CallFrequency;
27class CommonOperatorBuilder;
28class CompilationDependencies;
29struct FeedbackSource;
30struct FieldAccess;
31class JSCallReducerAssembler;
32class JSGraph;
33class JSHeapBroker;
34class JSOperatorBuilder;
35class MapInference;
36class NodeProperties;
37class SimplifiedOperatorBuilder;
38
39// Performs strength reduction on {JSConstruct} and {JSCall} nodes,
40// which might allow inlining or other optimizations to be performed afterwards.
42 public:
43 // Flags that control the mode of operation.
44 enum Flag {
47 kInlineJSToWasmCalls = 1u << 1,
48 };
50
52 Zone* temp_zone, Flags flags)
53 : AdvancedReducer(editor),
54 jsgraph_(jsgraph),
56 temp_zone_(temp_zone),
57 flags_(flags) {}
58
59 // Max string length for inlining entire match sequence for
60 // String.prototype.startsWith in JSCallReducer.
61 static constexpr int kMaxInlineMatchSequence = 3;
62
63 const char* reducer_name() const override { return "JSCallReducer"; }
64
65 Reduction Reduce(Node* node) final;
66
67 // Processes the waitlist gathered while the reducer was running,
68 // and does a final attempt to reduce the nodes in the waitlist.
69 void Finalize() final;
70
71 // JSCallReducer outsources much work to a graph assembler.
72 void RevisitForGraphAssembler(Node* node) { Revisit(node); }
73 Zone* ZoneForGraphAssembler() const { return temp_zone(); }
75
76#if V8_ENABLE_WEBASSEMBLY
77 bool has_js_wasm_calls() const {
78 return wasm_module_for_inlining_ != nullptr;
79 }
80 const wasm::WasmModule* wasm_module_for_inlining() const {
81 return wasm_module_for_inlining_;
82 }
83#endif // V8_ENABLE_WEBASSEMBLY
84
85 CompilationDependencies* dependencies() const;
86 JSHeapBroker* broker() const { return broker_; }
87
88 private:
89 Reduction ReduceBooleanConstructor(Node* node);
90 Reduction ReduceCallApiFunction(Node* node, SharedFunctionInfoRef shared);
92 Reduction ReduceFunctionPrototypeApply(Node* node);
93 Reduction ReduceFunctionPrototypeBind(Node* node);
94 Reduction ReduceFunctionPrototypeCall(Node* node);
95 Reduction ReduceFunctionPrototypeHasInstance(Node* node);
96 Reduction ReduceObjectConstructor(Node* node);
97 Reduction ReduceObjectGetPrototype(Node* node, Node* object);
98 Reduction ReduceObjectGetPrototypeOf(Node* node);
99 Reduction ReduceObjectIs(Node* node);
100 Reduction ReduceObjectPrototypeGetProto(Node* node);
101 Reduction ReduceObjectPrototypeHasOwnProperty(Node* node);
102 Reduction ReduceObjectPrototypeIsPrototypeOf(Node* node);
103 Reduction ReduceObjectCreate(Node* node);
104 Reduction ReduceReflectApply(Node* node);
105 Reduction ReduceReflectConstruct(Node* node);
106 Reduction ReduceReflectGet(Node* node);
107 Reduction ReduceReflectGetPrototypeOf(Node* node);
108 Reduction ReduceReflectHas(Node* node);
109
110 Reduction ReduceArrayConstructor(Node* node);
111 Reduction ReduceArrayEvery(Node* node, SharedFunctionInfoRef shared);
112 Reduction ReduceArrayFilter(Node* node, SharedFunctionInfoRef shared);
113 Reduction ReduceArrayFindIndex(Node* node, SharedFunctionInfoRef shared);
114 Reduction ReduceArrayFind(Node* node, SharedFunctionInfoRef shared);
115 Reduction ReduceArrayForEach(Node* node, SharedFunctionInfoRef shared);
116 Reduction ReduceArrayIncludes(Node* node);
117 Reduction ReduceArrayIndexOf(Node* node);
118 Reduction ReduceArrayIsArray(Node* node);
119 Reduction ReduceArrayMap(Node* node, SharedFunctionInfoRef shared);
120 Reduction ReduceArrayPrototypeAt(Node* node);
121 Reduction ReduceArrayPrototypePop(Node* node);
122 Reduction ReduceArrayPrototypePush(Node* node);
123 Reduction ReduceArrayPrototypeShift(Node* node);
124 Reduction ReduceArrayPrototypeSlice(Node* node);
125 Reduction ReduceArrayReduce(Node* node, SharedFunctionInfoRef shared);
126 Reduction ReduceArrayReduceRight(Node* node, SharedFunctionInfoRef shared);
127 Reduction ReduceArraySome(Node* node, SharedFunctionInfoRef shared);
128
129 enum class ArrayIteratorKind { kArrayLike, kTypedArray };
130 Reduction ReduceArrayIterator(Node* node, ArrayIteratorKind array_kind,
131 IterationKind iteration_kind);
132 Reduction ReduceArrayIteratorPrototypeNext(Node* node);
135
136 Reduction ReduceCallOrConstructWithArrayLikeOrSpreadOfCreateArguments(
137 Node* node, Node* arguments_list, int arraylike_or_spread_index,
138 CallFrequency const& frequency, FeedbackSource const& feedback,
139 SpeculationMode speculation_mode, CallFeedbackRelation feedback_relation);
140 Reduction ReduceCallOrConstructWithArrayLikeOrSpread(
141 Node* node, int argument_count, int arraylike_or_spread_index,
142 CallFrequency const& frequency, FeedbackSource const& feedback_source,
143 SpeculationMode speculation_mode, CallFeedbackRelation feedback_relation,
144 Node* target, Effect effect, Control control);
145 Reduction ReduceJSConstruct(Node* node);
146 Reduction ReduceJSConstructWithArrayLike(Node* node);
147 Reduction ReduceJSConstructWithSpread(Node* node);
148 Reduction ReduceJSConstructForwardAllArgs(Node* node);
149 Reduction ReduceJSCall(Node* node);
150 Reduction ReduceJSCall(Node* node, SharedFunctionInfoRef shared);
151 Reduction ReduceJSCallWithArrayLike(Node* node);
152 Reduction ReduceJSCallWithSpread(Node* node);
153 Reduction ReduceRegExpPrototypeTest(Node* node);
154 Reduction ReduceReturnReceiver(Node* node);
155
156 Reduction ReduceStringConstructor(Node* node, JSFunctionRef constructor);
158 Reduction ReduceStringPrototypeIndexOfIncludes(
159 Node* node, StringIndexOfIncludesVariant variant);
160 Reduction ReduceStringPrototypeSubstring(Node* node);
161 Reduction ReduceStringPrototypeSlice(Node* node);
162 Reduction ReduceStringPrototypeSubstr(Node* node);
163 Reduction ReduceStringPrototypeStringAt(
164 const Operator* string_access_operator, Node* node);
165 Reduction ReduceStringPrototypeCharAt(Node* node);
166 Reduction ReduceStringPrototypeStartsWith(Node* node);
167 Reduction ReduceStringPrototypeEndsWith(Node* node);
168
169#ifdef V8_INTL_SUPPORT
170 Reduction ReduceStringPrototypeLocaleCompareIntl(Node* node);
171 Reduction ReduceStringPrototypeToLowerCaseIntl(Node* node);
172 Reduction ReduceStringPrototypeToUpperCaseIntl(Node* node);
173#endif // V8_INTL_SUPPORT
174
175 Reduction ReduceStringFromCharCode(Node* node);
176 Reduction ReduceStringFromCodePoint(Node* node);
177 Reduction ReduceStringPrototypeIterator(Node* node);
178 Reduction ReduceStringIteratorPrototypeNext(Node* node);
179 Reduction ReduceStringPrototypeConcat(Node* node);
180
181 Reduction ReducePromiseConstructor(Node* node);
185 Reduction ReducePromisePrototypeCatch(Node* node);
186 Reduction ReducePromisePrototypeFinally(Node* node);
187 Reduction ReducePromisePrototypeThen(Node* node);
188 Reduction ReducePromiseResolveTrampoline(Node* node);
189
190 Reduction ReduceTypedArrayConstructor(Node* node,
191 SharedFunctionInfoRef shared);
192 Reduction ReduceTypedArrayPrototypeToStringTag(Node* node);
193 Reduction ReduceArrayBufferViewByteLengthAccessor(Node* node,
194 InstanceType instance_type,
195 Builtin builtin);
196 Reduction ReduceArrayBufferViewByteOffsetAccessor(Node* node,
197 InstanceType instance_type,
198 Builtin builtin);
199 Reduction ReduceTypedArrayPrototypeLength(Node* node);
200
201 Reduction ReduceForInsufficientFeedback(Node* node, DeoptimizeReason reason);
202
203 Reduction ReduceMathUnary(Node* node, const Operator* op);
204 Reduction ReduceMathBinary(Node* node, const Operator* op);
205 Reduction ReduceMathImul(Node* node);
206 Reduction ReduceMathClz32(Node* node);
207 Reduction ReduceMathMinMax(Node* node, const Operator* op, Node* empty_value);
208
209 Reduction ReduceNumberIsFinite(Node* node);
210 Reduction ReduceNumberIsInteger(Node* node);
211 Reduction ReduceNumberIsSafeInteger(Node* node);
212 Reduction ReduceNumberIsNaN(Node* node);
213
214 Reduction ReduceGlobalIsFinite(Node* node);
215 Reduction ReduceGlobalIsNaN(Node* node);
216
217 Reduction ReduceMapPrototypeHas(Node* node);
218 Reduction ReduceMapPrototypeGet(Node* node);
219 Reduction ReduceSetPrototypeHas(Node* node);
220 Reduction ReduceCollectionPrototypeHas(Node* node,
221 CollectionKind collection_kind);
222 Reduction ReduceCollectionIteration(Node* node,
223 CollectionKind collection_kind,
224 IterationKind iteration_kind);
225 Reduction ReduceCollectionPrototypeSize(Node* node,
226 CollectionKind collection_kind);
227 Reduction ReduceCollectionIteratorPrototypeNext(
228 Node* node, int entry_size, Handle<HeapObject> empty_collection,
229 InstanceType collection_iterator_instance_type_first,
230 InstanceType collection_iterator_instance_type_last);
231
232 Reduction ReduceArrayBufferIsView(Node* node);
233 Reduction ReduceArrayBufferViewAccessor(Node* node,
234 InstanceType instance_type,
235 FieldAccess const& access,
236 Builtin builtin);
237
238 enum class DataViewAccess { kGet, kSet };
239 Reduction ReduceDataViewAccess(Node* node, DataViewAccess access,
240 ExternalArrayType element_type);
241
242 Reduction ReduceDatePrototypeGetTime(Node* node);
243 Reduction ReduceDateNow(Node* node);
244 Reduction ReduceNumberParseInt(Node* node);
245
246 Reduction ReduceNumberConstructor(Node* node);
247 Reduction ReduceBigIntConstructor(Node* node);
248 Reduction ReduceBigIntAsN(Node* node, Builtin builtin);
249
250 std::optional<Reduction> TryReduceJSCallMathMinMaxWithArrayLike(Node* node);
251 Reduction ReduceJSCallMathMinMaxWithArrayLike(Node* node, Builtin builtin);
252
253#ifdef V8_ENABLE_CONTINUATION_PRESERVED_EMBEDDER_DATA
254 Reduction ReduceGetContinuationPreservedEmbedderData(Node* node);
255 Reduction ReduceSetContinuationPreservedEmbedderData(Node* node);
256#endif // V8_ENABLE_CONTINUATION_PRESERVED_EMBEDDER_DATA
257
258 // The pendant to ReplaceWithValue when using GraphAssembler-based reductions.
259 Reduction ReplaceWithSubgraph(JSCallReducerAssembler* gasm, Node* subgraph);
260 std::pair<Node*, Node*> ReleaseEffectAndControlFromAssembler(
262
263 // Helper to verify promise receiver maps are as expected.
264 // On bailout from a reduction, be sure to return inference.NoChange().
265 bool DoPromiseChecks(MapInference* inference);
266
267 Node* CreateClosureFromBuiltinSharedFunctionInfo(SharedFunctionInfoRef shared,
268 Node* context, Node* effect,
269 Node* control);
270
271 void CheckIfElementsKind(Node* receiver_elements_kind, ElementsKind kind,
272 Node* control, Node** if_true, Node** if_false);
273 Node* LoadReceiverElementsKind(Node* receiver, Effect* effect,
274 Control control);
275
276 bool IsBuiltinOrApiFunction(JSFunctionRef target_ref) const;
277
278 // Check whether an array has the expected length. Returns the new effect.
279 Node* CheckArrayLength(Node* array, ElementsKind elements_kind,
280 uint32_t array_length,
281 const FeedbackSource& feedback_source, Effect effect,
282 Control control);
283
284 // Check whether the given new target value is a constructor function.
285 void CheckIfConstructor(Node* call);
286
287 Node* ConvertHoleToUndefined(Node* value, ElementsKind elements_kind);
288
289 TFGraph* graph() const;
290 JSGraph* jsgraph() const { return jsgraph_; }
291 Zone* temp_zone() const { return temp_zone_; }
292 Isolate* isolate() const;
293 Factory* factory() const;
295 CommonOperatorBuilder* common() const;
296 JSOperatorBuilder* javascript() const;
298 Flags flags() const { return flags_; }
299
304 std::set<Node*> waitlist_;
305
306 // For preventing infinite recursion via ReduceJSCallWithArrayLikeOrSpread.
308
309#if V8_ENABLE_WEBASSEMBLY
310 const wasm::WasmModule* wasm_module_for_inlining_ = nullptr;
311#endif // V8_ENABLE_WEBASSEMBLY
312};
313
314} // namespace compiler
315} // namespace internal
316} // namespace v8
317
318#endif // V8_COMPILER_JS_CALL_REDUCER_H_
TFGraph * graph
JSGraph * jsgraph
SimplifiedOperatorBuilder * simplified
Builtins::Kind kind
Definition builtins.cc:40
JSCallReducer(Editor *editor, JSGraph *jsgraph, JSHeapBroker *broker, Zone *temp_zone, Flags flags)
Reduction ReducePromiseInternalResolve(Node *node)
Reduction ReduceFastArrayIteratorNext(InstanceType type, Node *node, IterationKind kind)
Reduction ReducePromiseInternalReject(Node *node)
Reduction ReduceCallWasmFunction(Node *node, SharedFunctionInfoRef shared)
const char * reducer_name() const override
Reduction ReducePromiseInternalConstructor(Node *node)
std::unordered_set< Node * > generated_calls_with_array_like_or_spread_
JSRegExp::Flags flags_
JSHeapBroker *const broker_
Isolate * isolate
JSHeapBroker * broker
TNode< Object > receiver
!IsContextMap !IsContextMap native_context
Definition map-inl.h:877
#define V8_EXPORT_PRIVATE
Definition macros.h:460