LCOV - code coverage report
Current view: top level - src/compiler - common-operator.h (source / functions) Hit Total Coverage
Test: app.info Lines: 12 13 92.3 %
Date: 2017-10-20 Functions: 3 3 100.0 %

          Line data    Source code
       1             : // Copyright 2014 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_COMMON_OPERATOR_H_
       6             : #define V8_COMPILER_COMMON_OPERATOR_H_
       7             : 
       8             : #include "src/assembler.h"
       9             : #include "src/base/compiler-specific.h"
      10             : #include "src/compiler/frame-states.h"
      11             : #include "src/deoptimize-reason.h"
      12             : #include "src/globals.h"
      13             : #include "src/machine-type.h"
      14             : #include "src/zone/zone-containers.h"
      15             : #include "src/zone/zone-handle-set.h"
      16             : 
      17             : namespace v8 {
      18             : namespace internal {
      19             : namespace compiler {
      20             : 
      21             : // Forward declarations.
      22             : class CallDescriptor;
      23             : struct CommonOperatorGlobalCache;
      24             : class Operator;
      25             : class Type;
      26             : class Node;
      27             : 
      28             : // Prediction hint for branches.
      29             : enum class BranchHint : uint8_t { kNone, kTrue, kFalse };
      30             : 
      31       13723 : inline BranchHint NegateBranchHint(BranchHint hint) {
      32       13723 :   switch (hint) {
      33             :     case BranchHint::kNone:
      34        9599 :       return hint;
      35             :     case BranchHint::kTrue:
      36             :       return BranchHint::kFalse;
      37             :     case BranchHint::kFalse:
      38        4120 :       return BranchHint::kTrue;
      39             :   }
      40           0 :   UNREACHABLE();
      41             : }
      42             : 
      43       35864 : inline size_t hash_value(BranchHint hint) { return static_cast<size_t>(hint); }
      44             : 
      45             : V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream&, BranchHint);
      46             : 
      47             : V8_EXPORT_PRIVATE BranchHint BranchHintOf(const Operator* const);
      48             : 
      49             : // Helper function for return nodes, because returns have a hidden value input.
      50             : int ValueInputCountOfReturn(Operator const* const op);
      51             : 
      52             : // Parameters for the {Deoptimize} operator.
      53             : class DeoptimizeParameters final {
      54             :  public:
      55             :   DeoptimizeParameters(DeoptimizeKind kind, DeoptimizeReason reason)
      56             :       : kind_(kind), reason_(reason) {}
      57             : 
      58             :   DeoptimizeKind kind() const { return kind_; }
      59             :   DeoptimizeReason reason() const { return reason_; }
      60             : 
      61             :  private:
      62             :   DeoptimizeKind const kind_;
      63             :   DeoptimizeReason const reason_;
      64             : };
      65             : 
      66             : bool operator==(DeoptimizeParameters, DeoptimizeParameters);
      67             : bool operator!=(DeoptimizeParameters, DeoptimizeParameters);
      68             : 
      69             : size_t hast_value(DeoptimizeParameters p);
      70             : 
      71             : std::ostream& operator<<(std::ostream&, DeoptimizeParameters p);
      72             : 
      73             : DeoptimizeParameters const& DeoptimizeParametersOf(Operator const* const);
      74             : 
      75             : 
      76             : class SelectParameters final {
      77             :  public:
      78             :   explicit SelectParameters(MachineRepresentation representation,
      79             :                             BranchHint hint = BranchHint::kNone)
      80             :       : representation_(representation), hint_(hint) {}
      81             : 
      82             :   MachineRepresentation representation() const { return representation_; }
      83             :   BranchHint hint() const { return hint_; }
      84             : 
      85             :  private:
      86             :   const MachineRepresentation representation_;
      87             :   const BranchHint hint_;
      88             : };
      89             : 
      90             : bool operator==(SelectParameters const&, SelectParameters const&);
      91             : bool operator!=(SelectParameters const&, SelectParameters const&);
      92             : 
      93             : size_t hash_value(SelectParameters const& p);
      94             : 
      95             : std::ostream& operator<<(std::ostream&, SelectParameters const& p);
      96             : 
      97             : V8_EXPORT_PRIVATE SelectParameters const& SelectParametersOf(
      98             :     const Operator* const);
      99             : 
     100             : V8_EXPORT_PRIVATE CallDescriptor const* CallDescriptorOf(const Operator* const);
     101             : 
     102             : V8_EXPORT_PRIVATE size_t ProjectionIndexOf(const Operator* const);
     103             : 
     104             : V8_EXPORT_PRIVATE MachineRepresentation
     105             : PhiRepresentationOf(const Operator* const);
     106             : 
     107             : // The {IrOpcode::kParameter} opcode represents an incoming parameter to the
     108             : // function. This class bundles the index and a debug name for such operators.
     109             : class ParameterInfo final {
     110             :  public:
     111             :   ParameterInfo(int index, const char* debug_name)
     112             :       : index_(index), debug_name_(debug_name) {}
     113             : 
     114             :   int index() const { return index_; }
     115             :   const char* debug_name() const { return debug_name_; }
     116             : 
     117             :  private:
     118             :   int index_;
     119             :   const char* debug_name_;
     120             : };
     121             : 
     122             : std::ostream& operator<<(std::ostream&, ParameterInfo const&);
     123             : 
     124             : V8_EXPORT_PRIVATE int ParameterIndexOf(const Operator* const);
     125             : const ParameterInfo& ParameterInfoOf(const Operator* const);
     126             : 
     127             : struct ObjectStateInfo final : std::pair<uint32_t, int> {
     128             :   ObjectStateInfo(uint32_t object_id, int size)
     129             :       : std::pair<uint32_t, int>(object_id, size) {}
     130             :   uint32_t object_id() const { return first; }
     131             :   int size() const { return second; }
     132             : };
     133             : std::ostream& operator<<(std::ostream&, ObjectStateInfo const&);
     134             : size_t hash_value(ObjectStateInfo const& p);
     135             : 
     136             : struct TypedObjectStateInfo final
     137             :     : std::pair<uint32_t, const ZoneVector<MachineType>*> {
     138             :   TypedObjectStateInfo(uint32_t object_id,
     139             :                        const ZoneVector<MachineType>* machine_types)
     140             :       : std::pair<uint32_t, const ZoneVector<MachineType>*>(object_id,
     141             :                                                             machine_types) {}
     142             :   uint32_t object_id() const { return first; }
     143             :   const ZoneVector<MachineType>* machine_types() const { return second; }
     144             : };
     145             : std::ostream& operator<<(std::ostream&, TypedObjectStateInfo const&);
     146             : size_t hash_value(TypedObjectStateInfo const& p);
     147             : 
     148             : class RelocatablePtrConstantInfo final {
     149             :  public:
     150             :   enum Type { kInt32, kInt64 };
     151             : 
     152             :   RelocatablePtrConstantInfo(int32_t value, RelocInfo::Mode rmode)
     153        2334 :       : value_(value), rmode_(rmode), type_(kInt32) {}
     154             :   RelocatablePtrConstantInfo(int64_t value, RelocInfo::Mode rmode)
     155             :       : value_(value), rmode_(rmode), type_(kInt64) {}
     156             : 
     157             :   intptr_t value() const { return value_; }
     158             :   RelocInfo::Mode rmode() const { return rmode_; }
     159             :   Type type() const { return type_; }
     160             : 
     161             :  private:
     162             :   intptr_t value_;
     163             :   RelocInfo::Mode rmode_;
     164             :   Type type_;
     165             : };
     166             : 
     167             : bool operator==(RelocatablePtrConstantInfo const& lhs,
     168             :                 RelocatablePtrConstantInfo const& rhs);
     169             : bool operator!=(RelocatablePtrConstantInfo const& lhs,
     170             :                 RelocatablePtrConstantInfo const& rhs);
     171             : 
     172             : std::ostream& operator<<(std::ostream&, RelocatablePtrConstantInfo const&);
     173             : 
     174             : size_t hash_value(RelocatablePtrConstantInfo const& p);
     175             : 
     176             : // Used to define a sparse set of inputs. This can be used to efficiently encode
     177             : // nodes that can have a lot of inputs, but where many inputs can have the same
     178             : // value.
     179             : class SparseInputMask final {
     180             :  public:
     181             :   typedef uint32_t BitMaskType;
     182             : 
     183             :   // The mask representing a dense input set.
     184             :   static const BitMaskType kDenseBitMask = 0x0;
     185             :   // The bits representing the end of a sparse input set.
     186             :   static const BitMaskType kEndMarker = 0x1;
     187             :   // The mask for accessing a sparse input entry in the bitmask.
     188             :   static const BitMaskType kEntryMask = 0x1;
     189             : 
     190             :   // The number of bits in the mask, minus one for the end marker.
     191             :   static const int kMaxSparseInputs = (sizeof(BitMaskType) * kBitsPerByte - 1);
     192             : 
     193             :   // An iterator over a node's sparse inputs.
     194             :   class InputIterator final {
     195             :    public:
     196             :     InputIterator() {}
     197             :     InputIterator(BitMaskType bit_mask, Node* parent);
     198             : 
     199             :     Node* parent() const { return parent_; }
     200             :     int real_index() const { return real_index_; }
     201             : 
     202             :     // Advance the iterator to the next sparse input. Only valid if the iterator
     203             :     // has not reached the end.
     204             :     void Advance();
     205             : 
     206             :     // Get the current sparse input's real node value. Only valid if the
     207             :     // current sparse input is real.
     208             :     Node* GetReal() const;
     209             : 
     210             :     // Get the current sparse input, returning either a real input node if
     211             :     // the current sparse input is real, or the given {empty_value} if the
     212             :     // current sparse input is empty.
     213    41620391 :     Node* Get(Node* empty_value) const {
     214    41620391 :       return IsReal() ? GetReal() : empty_value;
     215             :     }
     216             : 
     217             :     // True if the current sparse input is a real input node.
     218             :     bool IsReal() const;
     219             : 
     220             :     // True if the current sparse input is an empty value.
     221   136384183 :     bool IsEmpty() const { return !IsReal(); }
     222             : 
     223             :     // True if the iterator has reached the end of the sparse inputs.
     224             :     bool IsEnd() const;
     225             : 
     226             :    private:
     227             :     BitMaskType bit_mask_;
     228             :     Node* parent_;
     229             :     int real_index_;
     230             :   };
     231             : 
     232     9078999 :   explicit SparseInputMask(BitMaskType bit_mask) : bit_mask_(bit_mask) {}
     233             : 
     234             :   // Provides a SparseInputMask representing a dense input set.
     235             :   static SparseInputMask Dense() { return SparseInputMask(kDenseBitMask); }
     236             : 
     237     7255107 :   BitMaskType mask() const { return bit_mask_; }
     238             : 
     239     3674752 :   bool IsDense() const { return bit_mask_ == SparseInputMask::kDenseBitMask; }
     240             : 
     241             :   // Counts how many real values are in the sparse array. Only valid for
     242             :   // non-dense masks.
     243             :   int CountReal() const;
     244             : 
     245             :   // Returns an iterator over the sparse inputs of {node}.
     246             :   InputIterator IterateOverInputs(Node* node);
     247             : 
     248             :  private:
     249             :   //
     250             :   // The sparse input mask has a bitmask specifying if the node's inputs are
     251             :   // represented sparsely. If the bitmask value is 0, then the inputs are dense;
     252             :   // otherwise, they should be interpreted as follows:
     253             :   //
     254             :   //   * The bitmask represents which values are real, with 1 for real values
     255             :   //     and 0 for empty values.
     256             :   //   * The inputs to the node are the real values, in the order of the 1s from
     257             :   //     least- to most-significant.
     258             :   //   * The top bit of the bitmask is a guard indicating the end of the values,
     259             :   //     whether real or empty (and is not representative of a real input
     260             :   //     itself). This is used so that we don't have to additionally store a
     261             :   //     value count.
     262             :   //
     263             :   // So, for N 1s in the bitmask, there are N - 1 inputs into the node.
     264             :   BitMaskType bit_mask_;
     265             : };
     266             : 
     267             : bool operator==(SparseInputMask const& lhs, SparseInputMask const& rhs);
     268             : bool operator!=(SparseInputMask const& lhs, SparseInputMask const& rhs);
     269             : 
     270             : class TypedStateValueInfo final {
     271             :  public:
     272             :   TypedStateValueInfo(ZoneVector<MachineType> const* machine_types,
     273             :                       SparseInputMask sparse_input_mask)
     274             :       : machine_types_(machine_types), sparse_input_mask_(sparse_input_mask) {}
     275             : 
     276             :   ZoneVector<MachineType> const* machine_types() const {
     277             :     return machine_types_;
     278             :   }
     279             :   SparseInputMask sparse_input_mask() const { return sparse_input_mask_; }
     280             : 
     281             :  private:
     282             :   ZoneVector<MachineType> const* machine_types_;
     283             :   SparseInputMask sparse_input_mask_;
     284             : };
     285             : 
     286             : bool operator==(TypedStateValueInfo const& lhs, TypedStateValueInfo const& rhs);
     287             : bool operator!=(TypedStateValueInfo const& lhs, TypedStateValueInfo const& rhs);
     288             : 
     289             : std::ostream& operator<<(std::ostream&, TypedStateValueInfo const&);
     290             : 
     291             : size_t hash_value(TypedStateValueInfo const& p);
     292             : 
     293             : // Used to mark a region (as identified by BeginRegion/FinishRegion) as either
     294             : // JavaScript-observable or not (i.e. allocations are not JavaScript observable
     295             : // themselves, but transitioning stores are).
     296             : enum class RegionObservability : uint8_t { kObservable, kNotObservable };
     297             : 
     298             : size_t hash_value(RegionObservability);
     299             : 
     300             : std::ostream& operator<<(std::ostream&, RegionObservability);
     301             : 
     302             : RegionObservability RegionObservabilityOf(Operator const*) WARN_UNUSED_RESULT;
     303             : 
     304             : std::ostream& operator<<(std::ostream& os,
     305             :                          const ZoneVector<MachineType>* types);
     306             : 
     307             : Type* TypeGuardTypeOf(Operator const*) WARN_UNUSED_RESULT;
     308             : 
     309             : int OsrValueIndexOf(Operator const*);
     310             : 
     311             : SparseInputMask SparseInputMaskOf(Operator const*);
     312             : 
     313             : ZoneVector<MachineType> const* MachineTypesOf(Operator const*)
     314             :     WARN_UNUSED_RESULT;
     315             : 
     316             : // The ArgumentsElementsState and ArgumentsLengthState can describe the layout
     317             : // for backing stores of arguments objects of various types:
     318             : //
     319             : //                        +------------------------------------+
     320             : //  - kUnmappedArguments: | arg0, ... argK-1, argK, ... argN-1 |  {length:N}
     321             : //                        +------------------------------------+
     322             : //                        +------------------------------------+
     323             : //  - kMappedArguments:   | hole, ...   hole, argK, ... argN-1 |  {length:N}
     324             : //                        +------------------------------------+
     325             : //                                          +------------------+
     326             : //  - kRestParameter:                       | argK, ... argN-1 |  {length:N-K}
     327             : //                                          +------------------+
     328             : //
     329             : // Here {K} represents the number for formal parameters of the active function,
     330             : // whereas {N} represents the actual number of arguments passed at runtime.
     331             : // Note that {N < K} can happen and causes {K} to be capped accordingly.
     332             : //
     333             : // Also note that it is possible for an arguments object of {kMappedArguments}
     334             : // type to carry a backing store of {kUnappedArguments} type when {K == 0}.
     335             : typedef CreateArgumentsType ArgumentsStateType;
     336             : 
     337             : ArgumentsStateType ArgumentsStateTypeOf(Operator const*) WARN_UNUSED_RESULT;
     338             : 
     339             : uint32_t ObjectIdOf(Operator const*);
     340             : 
     341             : // Interface for building common operators that can be used at any level of IR,
     342             : // including JavaScript, mid-level, and low-level.
     343             : class V8_EXPORT_PRIVATE CommonOperatorBuilder final
     344             :     : public NON_EXPORTED_BASE(ZoneObject) {
     345             :  public:
     346             :   explicit CommonOperatorBuilder(Zone* zone);
     347             : 
     348             :   const Operator* Dead();
     349             :   const Operator* End(size_t control_input_count);
     350             :   const Operator* Branch(BranchHint = BranchHint::kNone);
     351             :   const Operator* IfTrue();
     352             :   const Operator* IfFalse();
     353             :   const Operator* IfSuccess();
     354             :   const Operator* IfException();
     355             :   const Operator* Switch(size_t control_output_count);
     356             :   const Operator* IfValue(int32_t value);
     357             :   const Operator* IfDefault();
     358             :   const Operator* Throw();
     359             :   const Operator* Deoptimize(DeoptimizeKind kind, DeoptimizeReason reason);
     360             :   const Operator* DeoptimizeIf(DeoptimizeKind kind, DeoptimizeReason reason);
     361             :   const Operator* DeoptimizeUnless(DeoptimizeKind kind,
     362             :                                    DeoptimizeReason reason);
     363             :   const Operator* TrapIf(int32_t trap_id);
     364             :   const Operator* TrapUnless(int32_t trap_id);
     365             :   const Operator* Return(int value_input_count = 1);
     366             :   const Operator* Terminate();
     367             : 
     368             :   const Operator* Start(int value_output_count);
     369             :   const Operator* Loop(int control_input_count);
     370             :   const Operator* Merge(int control_input_count);
     371             :   const Operator* Parameter(int index, const char* debug_name = nullptr);
     372             : 
     373             :   const Operator* OsrNormalEntry();
     374             :   const Operator* OsrLoopEntry();
     375             :   const Operator* OsrValue(int index);
     376             : 
     377             :   const Operator* Int32Constant(int32_t);
     378             :   const Operator* Int64Constant(int64_t);
     379             :   const Operator* Float32Constant(volatile float);
     380             :   const Operator* Float64Constant(volatile double);
     381             :   const Operator* ExternalConstant(const ExternalReference&);
     382             :   const Operator* NumberConstant(volatile double);
     383             :   const Operator* PointerConstant(intptr_t);
     384             :   const Operator* HeapConstant(const Handle<HeapObject>&);
     385             :   const Operator* ObjectId(uint32_t);
     386             : 
     387             :   const Operator* RelocatableInt32Constant(int32_t value,
     388             :                                            RelocInfo::Mode rmode);
     389             :   const Operator* RelocatableInt64Constant(int64_t value,
     390             :                                            RelocInfo::Mode rmode);
     391             : 
     392             :   const Operator* Select(MachineRepresentation, BranchHint = BranchHint::kNone);
     393             :   const Operator* Phi(MachineRepresentation representation,
     394             :                       int value_input_count);
     395             :   const Operator* EffectPhi(int effect_input_count);
     396             :   const Operator* InductionVariablePhi(int value_input_count);
     397             :   const Operator* LoopExit();
     398             :   const Operator* LoopExitValue();
     399             :   const Operator* LoopExitEffect();
     400             :   const Operator* Checkpoint();
     401             :   const Operator* BeginRegion(RegionObservability);
     402             :   const Operator* FinishRegion();
     403             :   const Operator* StateValues(int arguments, SparseInputMask bitmask);
     404             :   const Operator* TypedStateValues(const ZoneVector<MachineType>* types,
     405             :                                    SparseInputMask bitmask);
     406             :   const Operator* ArgumentsElementsState(ArgumentsStateType type);
     407             :   const Operator* ArgumentsLengthState(ArgumentsStateType type);
     408             :   const Operator* ObjectState(uint32_t object_id, int pointer_slots);
     409             :   const Operator* TypedObjectState(uint32_t object_id,
     410             :                                    const ZoneVector<MachineType>* types);
     411             :   const Operator* FrameState(BailoutId bailout_id,
     412             :                              OutputFrameStateCombine state_combine,
     413             :                              const FrameStateFunctionInfo* function_info);
     414             :   const Operator* Call(const CallDescriptor* descriptor);
     415             :   const Operator* CallWithCallerSavedRegisters(
     416             :       const CallDescriptor* descriptor);
     417             :   const Operator* TailCall(const CallDescriptor* descriptor);
     418             :   const Operator* Projection(size_t index);
     419             :   const Operator* Retain();
     420             :   const Operator* TypeGuard(Type* type);
     421             : 
     422             :   // Constructs a new merge or phi operator with the same opcode as {op}, but
     423             :   // with {size} inputs.
     424             :   const Operator* ResizeMergeOrPhi(const Operator* op, int size);
     425             : 
     426             :   // Constructs function info for frame state construction.
     427             :   const FrameStateFunctionInfo* CreateFrameStateFunctionInfo(
     428             :       FrameStateType type, int parameter_count, int local_count,
     429             :       Handle<SharedFunctionInfo> shared_info);
     430             : 
     431             :  private:
     432             :   Zone* zone() const { return zone_; }
     433             : 
     434             :   const CommonOperatorGlobalCache& cache_;
     435             :   Zone* const zone_;
     436             : 
     437             :   DISALLOW_COPY_AND_ASSIGN(CommonOperatorBuilder);
     438             : };
     439             : 
     440             : }  // namespace compiler
     441             : }  // namespace internal
     442             : }  // namespace v8
     443             : 
     444             : #endif  // V8_COMPILER_COMMON_OPERATOR_H_

Generated by: LCOV version 1.10