// Copyright 2015 the V8 project authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef V8_COMPILER_JS_CALL_REDUCER_H_ #define V8_COMPILER_JS_CALL_REDUCER_H_ #include "src/base/flags.h" #include "src/compiler/frame-states.h" #include "src/compiler/globals.h" #include "src/compiler/graph-reducer.h" #include "src/compiler/node-properties.h" #include "src/deoptimizer/deoptimize-reason.h" namespace v8 { namespace internal { // Forward declarations. class Factory; class JSGlobalProxy; namespace compiler { // Forward declarations. class CallFrequency; class CommonOperatorBuilder; class CompilationDependencies; struct FeedbackSource; struct FieldAccess; class JSCallReducerAssembler; class JSGraph; class JSHeapBroker; class JSOperatorBuilder; class MapInference; class NodeProperties; class SimplifiedOperatorBuilder; // Performs strength reduction on {JSConstruct} and {JSCall} nodes, // which might allow inlining or other optimizations to be performed afterwards. class V8_EXPORT_PRIVATE JSCallReducer final : public AdvancedReducer { public: // Flags that control the mode of operation. enum Flag { kNoFlags = 0u, kBailoutOnUninitialized = 1u << 0, }; using Flags = base::Flags; JSCallReducer(Editor* editor, JSGraph* jsgraph, JSHeapBroker* broker, Zone* temp_zone, Flags flags, CompilationDependencies* dependencies) : AdvancedReducer(editor), jsgraph_(jsgraph), broker_(broker), temp_zone_(temp_zone), flags_(flags), dependencies_(dependencies) {} const char* reducer_name() const override { return "JSCallReducer"; } Reduction Reduce(Node* node) final; // Processes the waitlist gathered while the reducer was running, // and does a final attempt to reduce the nodes in the waitlist. void Finalize() final; private: Reduction ReduceBooleanConstructor(Node* node); Reduction ReduceCallApiFunction(Node* node, const SharedFunctionInfoRef& shared); Reduction ReduceFunctionPrototypeApply(Node* node); Reduction ReduceFunctionPrototypeBind(Node* node); Reduction ReduceFunctionPrototypeCall(Node* node); Reduction ReduceFunctionPrototypeHasInstance(Node* node); Reduction ReduceObjectConstructor(Node* node); Reduction ReduceObjectGetPrototype(Node* node, Node* object); Reduction ReduceObjectGetPrototypeOf(Node* node); Reduction ReduceObjectIs(Node* node); Reduction ReduceObjectPrototypeGetProto(Node* node); Reduction ReduceObjectPrototypeHasOwnProperty(Node* node); Reduction ReduceObjectPrototypeIsPrototypeOf(Node* node); Reduction ReduceObjectCreate(Node* node); Reduction ReduceReflectApply(Node* node); Reduction ReduceReflectConstruct(Node* node); Reduction ReduceReflectGet(Node* node); Reduction ReduceReflectGetPrototypeOf(Node* node); Reduction ReduceReflectHas(Node* node); Reduction ReduceArrayConstructor(Node* node); Reduction ReduceArrayEvery(Node* node, const SharedFunctionInfoRef& shared); Reduction ReduceArrayFilter(Node* node, const SharedFunctionInfoRef& shared); Reduction ReduceArrayFindIndex(Node* node, const SharedFunctionInfoRef& shared); Reduction ReduceArrayFind(Node* node, const SharedFunctionInfoRef& shared); Reduction ReduceArrayForEach(Node* node, const SharedFunctionInfoRef& shared); Reduction ReduceArrayIncludes(Node* node); Reduction ReduceArrayIndexOf(Node* node); Reduction ReduceArrayIsArray(Node* node); Reduction ReduceArrayMap(Node* node, const SharedFunctionInfoRef& shared); Reduction ReduceArrayPrototypePop(Node* node); Reduction ReduceArrayPrototypePush(Node* node); Reduction ReduceArrayPrototypeShift(Node* node); Reduction ReduceArrayPrototypeSlice(Node* node); Reduction ReduceArrayReduce(Node* node, const SharedFunctionInfoRef& shared); Reduction ReduceArrayReduceRight(Node* node, const SharedFunctionInfoRef& shared); Reduction ReduceArraySome(Node* node, const SharedFunctionInfoRef& shared); enum class ArrayIteratorKind { kArray, kTypedArray }; Reduction ReduceArrayIterator(Node* node, IterationKind kind); Reduction ReduceArrayIteratorPrototypeNext(Node* node); Reduction ReduceFastArrayIteratorNext(InstanceType type, Node* node, IterationKind kind); Reduction ReduceCallOrConstructWithArrayLikeOrSpread( Node* node, int arity, CallFrequency const& frequency, FeedbackSource const& feedback, SpeculationMode speculation_mode, CallFeedbackRelation feedback_relation); Reduction ReduceJSConstruct(Node* node); Reduction ReduceJSConstructWithArrayLike(Node* node); Reduction ReduceJSConstructWithSpread(Node* node); Reduction ReduceJSCall(Node* node); Reduction ReduceJSCall(Node* node, const SharedFunctionInfoRef& shared); Reduction ReduceJSCallWithArrayLike(Node* node); Reduction ReduceJSCallWithSpread(Node* node); Reduction ReduceRegExpPrototypeTest(Node* node); Reduction ReduceReturnReceiver(Node* node); Reduction ReduceStringPrototypeIndexOf(Node* node); Reduction ReduceStringPrototypeSubstring(Node* node); Reduction ReduceStringPrototypeSlice(Node* node); Reduction ReduceStringPrototypeSubstr(Node* node); Reduction ReduceStringPrototypeStringAt( const Operator* string_access_operator, Node* node); Reduction ReduceStringPrototypeCharAt(Node* node); Reduction ReduceStringPrototypeStartsWith(Node* node); #ifdef V8_INTL_SUPPORT Reduction ReduceStringPrototypeToLowerCaseIntl(Node* node); Reduction ReduceStringPrototypeToUpperCaseIntl(Node* node); #endif // V8_INTL_SUPPORT Reduction ReduceStringFromCharCode(Node* node); Reduction ReduceStringFromCodePoint(Node* node); Reduction ReduceStringPrototypeIterator(Node* node); Reduction ReduceStringIteratorPrototypeNext(Node* node); Reduction ReduceStringPrototypeConcat(Node* node); Reduction ReducePromiseConstructor(Node* node); Reduction ReducePromiseInternalConstructor(Node* node); Reduction ReducePromiseInternalReject(Node* node); Reduction ReducePromiseInternalResolve(Node* node); Reduction ReducePromisePrototypeCatch(Node* node); Reduction ReducePromisePrototypeFinally(Node* node); Reduction ReducePromisePrototypeThen(Node* node); Reduction ReducePromiseResolveTrampoline(Node* node); Reduction ReduceTypedArrayConstructor(Node* node, const SharedFunctionInfoRef& shared); Reduction ReduceTypedArrayPrototypeToStringTag(Node* node); Reduction ReduceSoftDeoptimize(Node* node, DeoptimizeReason reason); Reduction ReduceMathUnary(Node* node, const Operator* op); Reduction ReduceMathBinary(Node* node, const Operator* op); Reduction ReduceMathImul(Node* node); Reduction ReduceMathClz32(Node* node); Reduction ReduceMathMinMax(Node* node, const Operator* op, Node* empty_value); Reduction ReduceNumberIsFinite(Node* node); Reduction ReduceNumberIsInteger(Node* node); Reduction ReduceNumberIsSafeInteger(Node* node); Reduction ReduceNumberIsNaN(Node* node); Reduction ReduceGlobalIsFinite(Node* node); Reduction ReduceGlobalIsNaN(Node* node); Reduction ReduceMapPrototypeHas(Node* node); Reduction ReduceMapPrototypeGet(Node* node); Reduction ReduceCollectionIteration(Node* node, CollectionKind collection_kind, IterationKind iteration_kind); Reduction ReduceCollectionPrototypeSize(Node* node, CollectionKind collection_kind); Reduction ReduceCollectionIteratorPrototypeNext( Node* node, int entry_size, Handle empty_collection, InstanceType collection_iterator_instance_type_first, InstanceType collection_iterator_instance_type_last); Reduction ReduceArrayBufferIsView(Node* node); Reduction ReduceArrayBufferViewAccessor(Node* node, InstanceType instance_type, FieldAccess const& access); enum class DataViewAccess { kGet, kSet }; Reduction ReduceDataViewAccess(Node* node, DataViewAccess access, ExternalArrayType element_type); Reduction ReduceDatePrototypeGetTime(Node* node); Reduction ReduceDateNow(Node* node); Reduction ReduceNumberParseInt(Node* node); Reduction ReduceNumberConstructor(Node* node); Reduction ReduceBigIntAsUintN(Node* node); // The pendant to ReplaceWithValue when using GraphAssembler-based reductions. Reduction ReplaceWithSubgraph(JSCallReducerAssembler* gasm, Node* subgraph); // Helper to verify promise receiver maps are as expected. // On bailout from a reduction, be sure to return inference.NoChange(). bool DoPromiseChecks(MapInference* inference); Node* CreateClosureFromBuiltinSharedFunctionInfo(SharedFunctionInfoRef shared, Node* context, Node* effect, Node* control); void CheckIfElementsKind(Node* receiver_elements_kind, ElementsKind kind, Node* control, Node** if_true, Node** if_false); Node* LoadReceiverElementsKind(Node* receiver, Node** effect, Node** control); Graph* graph() const; JSGraph* jsgraph() const { return jsgraph_; } JSHeapBroker* broker() const { return broker_; } Zone* temp_zone() const { return temp_zone_; } Isolate* isolate() const; Factory* factory() const; NativeContextRef native_context() const; CommonOperatorBuilder* common() const; JSOperatorBuilder* javascript() const; SimplifiedOperatorBuilder* simplified() const; Flags flags() const { return flags_; } CompilationDependencies* dependencies() const { return dependencies_; } bool should_disallow_heap_access() const; JSGraph* const jsgraph_; JSHeapBroker* const broker_; Zone* const temp_zone_; Flags const flags_; CompilationDependencies* const dependencies_; std::set waitlist_; }; } // namespace compiler } // namespace internal } // namespace v8 #endif // V8_COMPILER_JS_CALL_REDUCER_H_