Home | History | Annotate | Download | only in compiler
      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_SIMPLIFIED_OPERATOR_H_
      6 #define V8_COMPILER_SIMPLIFIED_OPERATOR_H_
      7 
      8 #include <iosfwd>
      9 
     10 #include "src/compiler/type-hints.h"
     11 #include "src/handles.h"
     12 #include "src/machine-type.h"
     13 #include "src/objects.h"
     14 
     15 namespace v8 {
     16 namespace internal {
     17 
     18 // Forward declarations.
     19 class Type;
     20 class Zone;
     21 
     22 
     23 namespace compiler {
     24 
     25 // Forward declarations.
     26 class Operator;
     27 struct SimplifiedOperatorGlobalCache;
     28 
     29 enum BaseTaggedness : uint8_t { kUntaggedBase, kTaggedBase };
     30 
     31 size_t hash_value(BaseTaggedness);
     32 
     33 std::ostream& operator<<(std::ostream&, BaseTaggedness);
     34 
     35 
     36 // An access descriptor for loads/stores of array buffers.
     37 class BufferAccess final {
     38  public:
     39   explicit BufferAccess(ExternalArrayType external_array_type)
     40       : external_array_type_(external_array_type) {}
     41 
     42   ExternalArrayType external_array_type() const { return external_array_type_; }
     43   MachineType machine_type() const;
     44 
     45  private:
     46   ExternalArrayType const external_array_type_;
     47 };
     48 
     49 bool operator==(BufferAccess, BufferAccess);
     50 bool operator!=(BufferAccess, BufferAccess);
     51 
     52 size_t hash_value(BufferAccess);
     53 
     54 std::ostream& operator<<(std::ostream&, BufferAccess);
     55 
     56 BufferAccess const BufferAccessOf(const Operator* op) WARN_UNUSED_RESULT;
     57 
     58 
     59 // An access descriptor for loads/stores of fixed structures like field
     60 // accesses of heap objects. Accesses from either tagged or untagged base
     61 // pointers are supported; untagging is done automatically during lowering.
     62 struct FieldAccess {
     63   BaseTaggedness base_is_tagged;  // specifies if the base pointer is tagged.
     64   int offset;                     // offset of the field, without tag.
     65   MaybeHandle<Name> name;         // debugging only.
     66   Type* type;                     // type of the field.
     67   MachineType machine_type;       // machine type of the field.
     68   WriteBarrierKind write_barrier_kind;  // write barrier hint.
     69 
     70   int tag() const { return base_is_tagged == kTaggedBase ? kHeapObjectTag : 0; }
     71 };
     72 
     73 bool operator==(FieldAccess const&, FieldAccess const&);
     74 bool operator!=(FieldAccess const&, FieldAccess const&);
     75 
     76 size_t hash_value(FieldAccess const&);
     77 
     78 std::ostream& operator<<(std::ostream&, FieldAccess const&);
     79 
     80 FieldAccess const& FieldAccessOf(const Operator* op) WARN_UNUSED_RESULT;
     81 
     82 
     83 // An access descriptor for loads/stores of indexed structures like characters
     84 // in strings or off-heap backing stores. Accesses from either tagged or
     85 // untagged base pointers are supported; untagging is done automatically during
     86 // lowering.
     87 struct ElementAccess {
     88   BaseTaggedness base_is_tagged;  // specifies if the base pointer is tagged.
     89   int header_size;                // size of the header, without tag.
     90   Type* type;                     // type of the element.
     91   MachineType machine_type;       // machine type of the element.
     92   WriteBarrierKind write_barrier_kind;  // write barrier hint.
     93 
     94   int tag() const { return base_is_tagged == kTaggedBase ? kHeapObjectTag : 0; }
     95 };
     96 
     97 bool operator==(ElementAccess const&, ElementAccess const&);
     98 bool operator!=(ElementAccess const&, ElementAccess const&);
     99 
    100 size_t hash_value(ElementAccess const&);
    101 
    102 std::ostream& operator<<(std::ostream&, ElementAccess const&);
    103 
    104 ElementAccess const& ElementAccessOf(const Operator* op) WARN_UNUSED_RESULT;
    105 
    106 enum class CheckFloat64HoleMode : uint8_t {
    107   kNeverReturnHole,  // Never return the hole (deoptimize instead).
    108   kAllowReturnHole   // Allow to return the hole (signaling NaN).
    109 };
    110 
    111 size_t hash_value(CheckFloat64HoleMode);
    112 
    113 std::ostream& operator<<(std::ostream&, CheckFloat64HoleMode);
    114 
    115 CheckFloat64HoleMode CheckFloat64HoleModeOf(const Operator*) WARN_UNUSED_RESULT;
    116 
    117 enum class CheckTaggedHoleMode : uint8_t {
    118   kNeverReturnHole,        // Never return the hole (deoptimize instead).
    119   kConvertHoleToUndefined  // Convert the hole to undefined.
    120 };
    121 
    122 size_t hash_value(CheckTaggedHoleMode);
    123 
    124 std::ostream& operator<<(std::ostream&, CheckTaggedHoleMode);
    125 
    126 CheckTaggedHoleMode CheckTaggedHoleModeOf(const Operator*) WARN_UNUSED_RESULT;
    127 
    128 Type* TypeOf(const Operator* op) WARN_UNUSED_RESULT;
    129 
    130 BinaryOperationHints::Hint BinaryOperationHintOf(const Operator* op);
    131 
    132 CompareOperationHints::Hint CompareOperationHintOf(const Operator* op);
    133 
    134 // Interface for building simplified operators, which represent the
    135 // medium-level operations of V8, including adding numbers, allocating objects,
    136 // indexing into objects and arrays, etc.
    137 // All operators are typed but many are representation independent.
    138 
    139 // Number values from JS can be in one of these representations:
    140 //   - Tagged: word-sized integer that is either
    141 //     - a signed small integer (31 or 32 bits plus a tag)
    142 //     - a tagged pointer to a HeapNumber object that has a float64 field
    143 //   - Int32: an untagged signed 32-bit integer
    144 //   - Uint32: an untagged unsigned 32-bit integer
    145 //   - Float64: an untagged float64
    146 
    147 // Additional representations for intermediate code or non-JS code:
    148 //   - Int64: an untagged signed 64-bit integer
    149 //   - Uint64: an untagged unsigned 64-bit integer
    150 //   - Float32: an untagged float32
    151 
    152 // Boolean values can be:
    153 //   - Bool: a tagged pointer to either the canonical JS #false or
    154 //           the canonical JS #true object
    155 //   - Bit: an untagged integer 0 or 1, but word-sized
    156 class SimplifiedOperatorBuilder final : public ZoneObject {
    157  public:
    158   explicit SimplifiedOperatorBuilder(Zone* zone);
    159 
    160   const Operator* BooleanNot();
    161   const Operator* BooleanToNumber();
    162 
    163   const Operator* NumberEqual();
    164   const Operator* NumberLessThan();
    165   const Operator* NumberLessThanOrEqual();
    166   const Operator* NumberAdd();
    167   const Operator* NumberSubtract();
    168   const Operator* NumberMultiply();
    169   const Operator* NumberDivide();
    170   const Operator* NumberModulus();
    171   const Operator* NumberBitwiseOr();
    172   const Operator* NumberBitwiseXor();
    173   const Operator* NumberBitwiseAnd();
    174   const Operator* NumberShiftLeft();
    175   const Operator* NumberShiftRight();
    176   const Operator* NumberShiftRightLogical();
    177   const Operator* NumberImul();
    178   const Operator* NumberAbs();
    179   const Operator* NumberClz32();
    180   const Operator* NumberCeil();
    181   const Operator* NumberFloor();
    182   const Operator* NumberFround();
    183   const Operator* NumberAtan();
    184   const Operator* NumberAtan2();
    185   const Operator* NumberAtanh();
    186   const Operator* NumberCbrt();
    187   const Operator* NumberCos();
    188   const Operator* NumberExp();
    189   const Operator* NumberExpm1();
    190   const Operator* NumberLog();
    191   const Operator* NumberLog1p();
    192   const Operator* NumberLog10();
    193   const Operator* NumberLog2();
    194   const Operator* NumberRound();
    195   const Operator* NumberSin();
    196   const Operator* NumberSqrt();
    197   const Operator* NumberTan();
    198   const Operator* NumberTrunc();
    199   const Operator* NumberToInt32();
    200   const Operator* NumberToUint32();
    201 
    202   const Operator* NumberSilenceNaN();
    203 
    204   const Operator* SpeculativeNumberAdd(BinaryOperationHints::Hint hint);
    205   const Operator* SpeculativeNumberSubtract(BinaryOperationHints::Hint hint);
    206   const Operator* SpeculativeNumberMultiply(BinaryOperationHints::Hint hint);
    207   const Operator* SpeculativeNumberDivide(BinaryOperationHints::Hint hint);
    208   const Operator* SpeculativeNumberModulus(BinaryOperationHints::Hint hint);
    209 
    210   const Operator* SpeculativeNumberLessThan(CompareOperationHints::Hint hint);
    211   const Operator* SpeculativeNumberLessThanOrEqual(
    212       CompareOperationHints::Hint hint);
    213   const Operator* SpeculativeNumberEqual(CompareOperationHints::Hint hint);
    214 
    215   const Operator* ReferenceEqual(Type* type);
    216 
    217   const Operator* StringEqual();
    218   const Operator* StringLessThan();
    219   const Operator* StringLessThanOrEqual();
    220   const Operator* StringFromCharCode();
    221   const Operator* StringToNumber();
    222 
    223   const Operator* PlainPrimitiveToNumber();
    224   const Operator* PlainPrimitiveToWord32();
    225   const Operator* PlainPrimitiveToFloat64();
    226 
    227   const Operator* ChangeTaggedSignedToInt32();
    228   const Operator* ChangeTaggedToInt32();
    229   const Operator* ChangeTaggedToUint32();
    230   const Operator* ChangeTaggedToFloat64();
    231   const Operator* ChangeInt31ToTaggedSigned();
    232   const Operator* ChangeInt32ToTagged();
    233   const Operator* ChangeUint32ToTagged();
    234   const Operator* ChangeFloat64ToTagged();
    235   const Operator* ChangeTaggedToBit();
    236   const Operator* ChangeBitToTagged();
    237   const Operator* TruncateTaggedToWord32();
    238   const Operator* TruncateTaggedToFloat64();
    239 
    240   const Operator* CheckBounds();
    241   const Operator* CheckTaggedPointer();
    242   const Operator* CheckTaggedSigned();
    243 
    244   const Operator* CheckedInt32Add();
    245   const Operator* CheckedInt32Sub();
    246   const Operator* CheckedUint32ToInt32();
    247   const Operator* CheckedFloat64ToInt32();
    248   const Operator* CheckedTaggedToInt32();
    249   const Operator* CheckedTaggedToFloat64();
    250 
    251   const Operator* CheckFloat64Hole(CheckFloat64HoleMode);
    252   const Operator* CheckTaggedHole(CheckTaggedHoleMode);
    253 
    254   const Operator* ObjectIsCallable();
    255   const Operator* ObjectIsNumber();
    256   const Operator* ObjectIsReceiver();
    257   const Operator* ObjectIsSmi();
    258   const Operator* ObjectIsString();
    259   const Operator* ObjectIsUndetectable();
    260 
    261   const Operator* TypeGuard(Type* type);
    262 
    263   const Operator* Allocate(PretenureFlag pretenure = NOT_TENURED);
    264 
    265   const Operator* LoadField(FieldAccess const&);
    266   const Operator* StoreField(FieldAccess const&);
    267 
    268   // load-buffer buffer, offset, length
    269   const Operator* LoadBuffer(BufferAccess);
    270 
    271   // store-buffer buffer, offset, length, value
    272   const Operator* StoreBuffer(BufferAccess);
    273 
    274   // load-element [base + index], length
    275   const Operator* LoadElement(ElementAccess const&);
    276 
    277   // store-element [base + index], length, value
    278   const Operator* StoreElement(ElementAccess const&);
    279 
    280  private:
    281   Zone* zone() const { return zone_; }
    282 
    283   const SimplifiedOperatorGlobalCache& cache_;
    284   Zone* const zone_;
    285 
    286   DISALLOW_COPY_AND_ASSIGN(SimplifiedOperatorBuilder);
    287 };
    288 
    289 }  // namespace compiler
    290 }  // namespace internal
    291 }  // namespace v8
    292 
    293 #endif  // V8_COMPILER_SIMPLIFIED_OPERATOR_H_
    294