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