Home | History | Annotate | Download | only in compiler
      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 
     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 
     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;
    236   JSGraph* jsgraph() const { return jsgraph_; }
    237   JSHeapBroker* js_heap_broker() const { return js_heap_broker_; }
    238   Isolate* isolate() const;
    239   Factory* factory() const;
    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;
    245   Flags flags() const { return flags_; }
    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