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_CALL_REDUCER_H_
6 : #define V8_COMPILER_JS_CALL_REDUCER_H_
7 :
8 : #include "src/base/flags.h"
9 : #include "src/compiler/frame-states.h"
10 : #include "src/compiler/graph-reducer.h"
11 : #include "src/compiler/node-properties.h"
12 : #include "src/deoptimize-reason.h"
13 :
14 : namespace v8 {
15 : namespace internal {
16 :
17 : // Forward declarations.
18 : class Factory;
19 : class JSGlobalProxy;
20 : class VectorSlotPair;
21 :
22 : namespace compiler {
23 :
24 : // Forward declarations.
25 : class CallFrequency;
26 : class CommonOperatorBuilder;
27 : class CompilationDependencies;
28 : struct FieldAccess;
29 : class JSGraph;
30 : class JSHeapBroker;
31 : class JSOperatorBuilder;
32 : class NodeProperties;
33 : class SimplifiedOperatorBuilder;
34 :
35 : // Performs strength reduction on {JSConstruct} and {JSCall} nodes,
36 : // which might allow inlining or other optimizations to be performed afterwards.
37 928504 : class V8_EXPORT_PRIVATE JSCallReducer final : public AdvancedReducer {
38 : public:
39 : // Flags that control the mode of operation.
40 : enum Flag { kNoFlags = 0u, kBailoutOnUninitialized = 1u << 0 };
41 : using Flags = base::Flags<Flag>;
42 :
43 : JSCallReducer(Editor* editor, JSGraph* jsgraph, JSHeapBroker* broker,
44 : Flags flags, CompilationDependencies* dependencies)
45 : : AdvancedReducer(editor),
46 : jsgraph_(jsgraph),
47 : broker_(broker),
48 : flags_(flags),
49 464253 : dependencies_(dependencies) {}
50 :
51 18 : const char* reducer_name() const override { return "JSCallReducer"; }
52 :
53 : Reduction Reduce(Node* node) final;
54 :
55 : // Processes the waitlist gathered while the reducer was running,
56 : // and does a final attempt to reduce the nodes in the waitlist.
57 : void Finalize() final;
58 :
59 : private:
60 : Reduction ReduceArrayConstructor(Node* node);
61 : Reduction ReduceBooleanConstructor(Node* node);
62 : Reduction ReduceCallApiFunction(Node* node,
63 : const SharedFunctionInfoRef& shared);
64 : Reduction ReduceFunctionPrototypeApply(Node* node);
65 : Reduction ReduceFunctionPrototypeBind(Node* node);
66 : Reduction ReduceFunctionPrototypeCall(Node* node);
67 : Reduction ReduceFunctionPrototypeHasInstance(Node* node);
68 : Reduction ReduceObjectConstructor(Node* node);
69 : Reduction ReduceObjectGetPrototype(Node* node, Node* object);
70 : Reduction ReduceObjectGetPrototypeOf(Node* node);
71 : Reduction ReduceObjectIs(Node* node);
72 : Reduction ReduceObjectPrototypeGetProto(Node* node);
73 : Reduction ReduceObjectPrototypeHasOwnProperty(Node* node);
74 : Reduction ReduceObjectPrototypeIsPrototypeOf(Node* node);
75 : Reduction ReduceObjectCreate(Node* node);
76 : Reduction ReduceReflectApply(Node* node);
77 : Reduction ReduceReflectConstruct(Node* node);
78 : Reduction ReduceReflectGet(Node* node);
79 : Reduction ReduceReflectGetPrototypeOf(Node* node);
80 : Reduction ReduceReflectHas(Node* node);
81 : Reduction ReduceArrayForEach(Node* node, const SharedFunctionInfoRef& shared);
82 : enum class ArrayReduceDirection { kLeft, kRight };
83 : Reduction ReduceArrayReduce(Node* node, ArrayReduceDirection direction,
84 : const SharedFunctionInfoRef& shared);
85 : Reduction ReduceArrayMap(Node* node, const SharedFunctionInfoRef& shared);
86 : Reduction ReduceArrayFilter(Node* node, const SharedFunctionInfoRef& shared);
87 : enum class ArrayFindVariant { kFind, kFindIndex };
88 : Reduction ReduceArrayFind(Node* node, ArrayFindVariant variant,
89 : const SharedFunctionInfoRef& shared);
90 : Reduction ReduceArrayEvery(Node* node, const SharedFunctionInfoRef& shared);
91 : enum class SearchVariant { kIncludes, kIndexOf };
92 : Reduction ReduceArrayIndexOfIncludes(SearchVariant search_variant,
93 : Node* node);
94 : Reduction ReduceArraySome(Node* node, const SharedFunctionInfoRef& shared);
95 : Reduction ReduceArrayPrototypePush(Node* node);
96 : Reduction ReduceArrayPrototypePop(Node* node);
97 : Reduction ReduceArrayPrototypeShift(Node* node);
98 : Reduction ReduceArrayPrototypeSlice(Node* node);
99 : Reduction ReduceArrayIsArray(Node* node);
100 : enum class ArrayIteratorKind { kArray, kTypedArray };
101 : Reduction ReduceArrayIterator(Node* node, IterationKind kind);
102 : Reduction ReduceArrayIteratorPrototypeNext(Node* node);
103 : Reduction ReduceFastArrayIteratorNext(InstanceType type, Node* node,
104 : IterationKind kind);
105 :
106 : Reduction ReduceCallOrConstructWithArrayLikeOrSpread(
107 : Node* node, int arity, CallFrequency const& frequency,
108 : VectorSlotPair const& feedback);
109 : Reduction ReduceJSConstruct(Node* node);
110 : Reduction ReduceJSConstructWithArrayLike(Node* node);
111 : Reduction ReduceJSConstructWithSpread(Node* node);
112 : Reduction ReduceJSCall(Node* node);
113 : Reduction ReduceJSCall(Node* node, const SharedFunctionInfoRef& shared);
114 : Reduction ReduceJSCallWithArrayLike(Node* node);
115 : Reduction ReduceJSCallWithSpread(Node* node);
116 : Reduction ReduceRegExpPrototypeTest(Node* node);
117 : Reduction ReduceReturnReceiver(Node* node);
118 : Reduction ReduceStringPrototypeIndexOf(Node* node);
119 : Reduction ReduceStringPrototypeSubstring(Node* node);
120 : Reduction ReduceStringPrototypeSlice(Node* node);
121 : Reduction ReduceStringPrototypeSubstr(Node* node);
122 : Reduction ReduceStringPrototypeStringAt(
123 : const Operator* string_access_operator, Node* node);
124 : Reduction ReduceStringPrototypeCharAt(Node* node);
125 :
126 : #ifdef V8_INTL_SUPPORT
127 : Reduction ReduceStringPrototypeToLowerCaseIntl(Node* node);
128 : Reduction ReduceStringPrototypeToUpperCaseIntl(Node* node);
129 : #endif // V8_INTL_SUPPORT
130 :
131 : Reduction ReduceStringFromCharCode(Node* node);
132 : Reduction ReduceStringFromCodePoint(Node* node);
133 : Reduction ReduceStringPrototypeIterator(Node* node);
134 : Reduction ReduceStringIteratorPrototypeNext(Node* node);
135 : Reduction ReduceStringPrototypeConcat(Node* node);
136 :
137 : Reduction ReducePromiseConstructor(Node* node);
138 : Reduction ReducePromiseInternalConstructor(Node* node);
139 : Reduction ReducePromiseInternalReject(Node* node);
140 : Reduction ReducePromiseInternalResolve(Node* node);
141 : Reduction ReducePromisePrototypeCatch(Node* node);
142 : Reduction ReducePromisePrototypeFinally(Node* node);
143 : Reduction ReducePromisePrototypeThen(Node* node);
144 : Reduction ReducePromiseResolveTrampoline(Node* node);
145 :
146 : Reduction ReduceTypedArrayConstructor(Node* node,
147 : const SharedFunctionInfoRef& shared);
148 : Reduction ReduceTypedArrayPrototypeToStringTag(Node* node);
149 :
150 : Reduction ReduceSoftDeoptimize(Node* node, DeoptimizeReason reason);
151 :
152 : Reduction ReduceMathUnary(Node* node, const Operator* op);
153 : Reduction ReduceMathBinary(Node* node, const Operator* op);
154 : Reduction ReduceMathImul(Node* node);
155 : Reduction ReduceMathClz32(Node* node);
156 : Reduction ReduceMathMinMax(Node* node, const Operator* op, Node* empty_value);
157 :
158 : Reduction ReduceNumberIsFinite(Node* node);
159 : Reduction ReduceNumberIsInteger(Node* node);
160 : Reduction ReduceNumberIsSafeInteger(Node* node);
161 : Reduction ReduceNumberIsNaN(Node* node);
162 :
163 : Reduction ReduceGlobalIsFinite(Node* node);
164 : Reduction ReduceGlobalIsNaN(Node* node);
165 :
166 : Reduction ReduceMapPrototypeHas(Node* node);
167 : Reduction ReduceMapPrototypeGet(Node* node);
168 : Reduction ReduceCollectionIteration(Node* node,
169 : CollectionKind collection_kind,
170 : IterationKind iteration_kind);
171 : Reduction ReduceCollectionPrototypeSize(Node* node,
172 : CollectionKind collection_kind);
173 : Reduction ReduceCollectionIteratorPrototypeNext(
174 : Node* node, int entry_size, Handle<HeapObject> empty_collection,
175 : InstanceType collection_iterator_instance_type_first,
176 : InstanceType collection_iterator_instance_type_last);
177 :
178 : Reduction ReduceArrayBufferIsView(Node* node);
179 : Reduction ReduceArrayBufferViewAccessor(Node* node,
180 : InstanceType instance_type,
181 : FieldAccess const& access);
182 :
183 : enum class DataViewAccess { kGet, kSet };
184 : Reduction ReduceDataViewAccess(Node* node, DataViewAccess access,
185 : ExternalArrayType element_type);
186 :
187 : Reduction ReduceDatePrototypeGetTime(Node* node);
188 : Reduction ReduceDateNow(Node* node);
189 : Reduction ReduceNumberParseInt(Node* node);
190 :
191 : Reduction ReduceNumberConstructor(Node* node);
192 :
193 : Node* InsertMapChecksIfUnreliableReceiverMaps(
194 : NodeProperties::InferReceiverMapsResult result,
195 : ZoneHandleSet<Map> const& receiver_maps, VectorSlotPair const& feedback,
196 : Node* receiver, Node* effect, Node* control);
197 :
198 : // Returns the updated {to} node, and updates control and effect along the
199 : // way.
200 : Node* DoFilterPostCallbackWork(ElementsKind kind, Node** control,
201 : Node** effect, Node* a, Node* to,
202 : Node* element, Node* callback_value);
203 :
204 : // If {fncallback} is not callable, throw a TypeError.
205 : // {control} is altered, and new nodes {check_fail} and {check_throw} are
206 : // returned. {check_fail} is the control branch where IsCallable failed,
207 : // and {check_throw} is the call to throw a TypeError in that
208 : // branch.
209 : void WireInCallbackIsCallableCheck(Node* fncallback, Node* context,
210 : Node* check_frame_state, Node* effect,
211 : Node** control, Node** check_fail,
212 : Node** check_throw);
213 : void RewirePostCallbackExceptionEdges(Node* check_throw, Node* on_exception,
214 : Node* effect, Node** check_fail,
215 : Node** control);
216 :
217 : // Begin the central loop of a higher-order array builtin. A Loop is wired
218 : // into {control}, an EffectPhi into {effect}, and the array index {k} is
219 : // threaded into a Phi, which is returned. It's helpful to save the
220 : // value of {control} as the loop node, and of {effect} as the corresponding
221 : // EffectPhi after function return.
222 : Node* WireInLoopStart(Node* k, Node** control, Node** effect);
223 : void WireInLoopEnd(Node* loop, Node* eloop, Node* vloop, Node* k,
224 : Node* control, Node* effect);
225 :
226 : // Load receiver[k], first bounding k by receiver array length.
227 : // k is thusly changed, and the effect is changed as well.
228 : Node* SafeLoadElement(ElementsKind kind, Node* receiver, Node* control,
229 : Node** effect, Node** k,
230 : const VectorSlotPair& feedback);
231 :
232 : Node* CreateArtificialFrameState(Node* node, Node* outer_frame_state,
233 : int parameter_count, BailoutId bailout_id,
234 : FrameStateType frame_state_type,
235 : const SharedFunctionInfoRef& shared,
236 : Node* context = nullptr);
237 :
238 : Graph* graph() const;
239 : JSGraph* jsgraph() const { return jsgraph_; }
240 : JSHeapBroker* broker() const { return broker_; }
241 : Isolate* isolate() const;
242 : Factory* factory() const;
243 304795 : NativeContextRef native_context() const { return broker()->native_context(); }
244 : CommonOperatorBuilder* common() const;
245 : JSOperatorBuilder* javascript() const;
246 : SimplifiedOperatorBuilder* simplified() const;
247 : Flags flags() const { return flags_; }
248 : CompilationDependencies* dependencies() const { return dependencies_; }
249 :
250 : JSGraph* const jsgraph_;
251 : JSHeapBroker* const broker_;
252 : Flags const flags_;
253 : CompilationDependencies* const dependencies_;
254 : std::set<Node*> waitlist_;
255 : };
256 :
257 : } // namespace compiler
258 : } // namespace internal
259 : } // namespace v8
260 :
261 : #endif // V8_COMPILER_JS_CALL_REDUCER_H_
|