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/base/compiler-specific.h"
     11 #include "src/compiler/operator.h"
     12 #include "src/compiler/types.h"
     13 #include "src/globals.h"
     14 #include "src/handles.h"
     15 #include "src/machine-type.h"
     16 #include "src/objects.h"
     17 #include "src/zone/zone-handle-set.h"
     18 
     19 namespace v8 {
     20 namespace internal {
     21 
     22 // Forward declarations.
     23 class Zone;
     24 
     25 namespace compiler {
     26 
     27 // Forward declarations.
     28 class Operator;
     29 struct SimplifiedOperatorGlobalCache;
     30 
     31 enum BaseTaggedness : uint8_t { kUntaggedBase, kTaggedBase };
     32 
     33 size_t hash_value(BaseTaggedness);
     34 
     35 std::ostream& operator<<(std::ostream&, BaseTaggedness);
     36 
     37 
     38 // An access descriptor for loads/stores of array buffers.
     39 class BufferAccess final {
     40  public:
     41   explicit BufferAccess(ExternalArrayType external_array_type)
     42       : external_array_type_(external_array_type) {}
     43 
     44   ExternalArrayType external_array_type() const { return external_array_type_; }
     45   MachineType machine_type() const;
     46 
     47  private:
     48   ExternalArrayType const external_array_type_;
     49 };
     50 
     51 V8_EXPORT_PRIVATE bool operator==(BufferAccess, BufferAccess);
     52 bool operator!=(BufferAccess, BufferAccess);
     53 
     54 size_t hash_value(BufferAccess);
     55 
     56 V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream&, BufferAccess);
     57 
     58 V8_EXPORT_PRIVATE BufferAccess const BufferAccessOf(const Operator* op)
     59     WARN_UNUSED_RESULT;
     60 
     61 // An access descriptor for loads/stores of fixed structures like field
     62 // accesses of heap objects. Accesses from either tagged or untagged base
     63 // pointers are supported; untagging is done automatically during lowering.
     64 struct FieldAccess {
     65   BaseTaggedness base_is_tagged;  // specifies if the base pointer is tagged.
     66   int offset;                     // offset of the field, without tag.
     67   MaybeHandle<Name> name;         // debugging only.
     68   MaybeHandle<Map> map;           // map of the field value (if known).
     69   Type* type;                     // type of the field.
     70   MachineType machine_type;       // machine type of the field.
     71   WriteBarrierKind write_barrier_kind;  // write barrier hint.
     72 
     73   int tag() const { return base_is_tagged == kTaggedBase ? kHeapObjectTag : 0; }
     74 };
     75 
     76 V8_EXPORT_PRIVATE bool operator==(FieldAccess const&, FieldAccess const&);
     77 bool operator!=(FieldAccess const&, FieldAccess const&);
     78 
     79 size_t hash_value(FieldAccess const&);
     80 
     81 V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream&, FieldAccess const&);
     82 
     83 FieldAccess const& FieldAccessOf(const Operator* op) WARN_UNUSED_RESULT;
     84 
     85 template <>
     86 void Operator1<FieldAccess>::PrintParameter(std::ostream& os,
     87                                             PrintVerbosity verbose) const;
     88 
     89 // An access descriptor for loads/stores of indexed structures like characters
     90 // in strings or off-heap backing stores. Accesses from either tagged or
     91 // untagged base pointers are supported; untagging is done automatically during
     92 // lowering.
     93 struct ElementAccess {
     94   BaseTaggedness base_is_tagged;  // specifies if the base pointer is tagged.
     95   int header_size;                // size of the header, without tag.
     96   Type* type;                     // type of the element.
     97   MachineType machine_type;       // machine type of the element.
     98   WriteBarrierKind write_barrier_kind;  // write barrier hint.
     99 
    100   int tag() const { return base_is_tagged == kTaggedBase ? kHeapObjectTag : 0; }
    101 };
    102 
    103 V8_EXPORT_PRIVATE bool operator==(ElementAccess const&, ElementAccess const&);
    104 bool operator!=(ElementAccess const&, ElementAccess const&);
    105 
    106 size_t hash_value(ElementAccess const&);
    107 
    108 V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream&, ElementAccess const&);
    109 
    110 V8_EXPORT_PRIVATE ElementAccess const& ElementAccessOf(const Operator* op)
    111     WARN_UNUSED_RESULT;
    112 
    113 ExternalArrayType ExternalArrayTypeOf(const Operator* op) WARN_UNUSED_RESULT;
    114 
    115 enum class CheckFloat64HoleMode : uint8_t {
    116   kNeverReturnHole,  // Never return the hole (deoptimize instead).
    117   kAllowReturnHole   // Allow to return the hole (signaling NaN).
    118 };
    119 
    120 size_t hash_value(CheckFloat64HoleMode);
    121 
    122 std::ostream& operator<<(std::ostream&, CheckFloat64HoleMode);
    123 
    124 CheckFloat64HoleMode CheckFloat64HoleModeOf(const Operator*) WARN_UNUSED_RESULT;
    125 
    126 enum class CheckTaggedInputMode : uint8_t {
    127   kNumber,
    128   kNumberOrOddball,
    129 };
    130 
    131 size_t hash_value(CheckTaggedInputMode);
    132 
    133 std::ostream& operator<<(std::ostream&, CheckTaggedInputMode);
    134 
    135 CheckTaggedInputMode CheckTaggedInputModeOf(const Operator*) WARN_UNUSED_RESULT;
    136 
    137 enum class CheckForMinusZeroMode : uint8_t {
    138   kCheckForMinusZero,
    139   kDontCheckForMinusZero,
    140 };
    141 
    142 size_t hash_value(CheckForMinusZeroMode);
    143 
    144 std::ostream& operator<<(std::ostream&, CheckForMinusZeroMode);
    145 
    146 CheckForMinusZeroMode CheckMinusZeroModeOf(const Operator*) WARN_UNUSED_RESULT;
    147 
    148 // Flags for map checks.
    149 enum class CheckMapsFlag : uint8_t {
    150   kNone = 0u,
    151   kTryMigrateInstance = 1u << 0,  // Try instance migration.
    152 };
    153 typedef base::Flags<CheckMapsFlag> CheckMapsFlags;
    154 
    155 DEFINE_OPERATORS_FOR_FLAGS(CheckMapsFlags)
    156 
    157 std::ostream& operator<<(std::ostream&, CheckMapsFlags);
    158 
    159 // A descriptor for map checks.
    160 class CheckMapsParameters final {
    161  public:
    162   CheckMapsParameters(CheckMapsFlags flags, ZoneHandleSet<Map> const& maps)
    163       : flags_(flags), maps_(maps) {}
    164 
    165   CheckMapsFlags flags() const { return flags_; }
    166   ZoneHandleSet<Map> const& maps() const { return maps_; }
    167 
    168  private:
    169   CheckMapsFlags const flags_;
    170   ZoneHandleSet<Map> const maps_;
    171 };
    172 
    173 bool operator==(CheckMapsParameters const&, CheckMapsParameters const&);
    174 bool operator!=(CheckMapsParameters const&, CheckMapsParameters const&);
    175 
    176 size_t hash_value(CheckMapsParameters const&);
    177 
    178 std::ostream& operator<<(std::ostream&, CheckMapsParameters const&);
    179 
    180 CheckMapsParameters const& CheckMapsParametersOf(Operator const*)
    181     WARN_UNUSED_RESULT;
    182 
    183 // A descriptor for growing elements backing stores.
    184 enum class GrowFastElementsFlag : uint8_t {
    185   kNone = 0u,
    186   kArrayObject = 1u << 0,     // Update JSArray::length field.
    187   kHoleyElements = 1u << 1,   // Backing store is holey.
    188   kDoubleElements = 1u << 2,  // Backing store contains doubles.
    189 };
    190 typedef base::Flags<GrowFastElementsFlag> GrowFastElementsFlags;
    191 
    192 DEFINE_OPERATORS_FOR_FLAGS(GrowFastElementsFlags)
    193 
    194 std::ostream& operator<<(std::ostream&, GrowFastElementsFlags);
    195 
    196 GrowFastElementsFlags GrowFastElementsFlagsOf(const Operator*)
    197     WARN_UNUSED_RESULT;
    198 
    199 // A descriptor for elements kind transitions.
    200 class ElementsTransition final {
    201  public:
    202   enum Mode : uint8_t {
    203     kFastTransition,  // simple transition, just updating the map.
    204     kSlowTransition   // full transition, round-trip to the runtime.
    205   };
    206 
    207   ElementsTransition(Mode mode, Handle<Map> source, Handle<Map> target)
    208       : mode_(mode), source_(source), target_(target) {}
    209 
    210   Mode mode() const { return mode_; }
    211   Handle<Map> source() const { return source_; }
    212   Handle<Map> target() const { return target_; }
    213 
    214  private:
    215   Mode const mode_;
    216   Handle<Map> const source_;
    217   Handle<Map> const target_;
    218 };
    219 
    220 bool operator==(ElementsTransition const&, ElementsTransition const&);
    221 bool operator!=(ElementsTransition const&, ElementsTransition const&);
    222 
    223 size_t hash_value(ElementsTransition);
    224 
    225 std::ostream& operator<<(std::ostream&, ElementsTransition);
    226 
    227 ElementsTransition const& ElementsTransitionOf(const Operator* op)
    228     WARN_UNUSED_RESULT;
    229 
    230 // A hint for speculative number operations.
    231 enum class NumberOperationHint : uint8_t {
    232   kSignedSmall,      // Inputs were always Smi so far, output was in Smi range.
    233   kSigned32,         // Inputs and output were Signed32 so far.
    234   kNumber,           // Inputs were Number, output was Number.
    235   kNumberOrOddball,  // Inputs were Number or Oddball, output was Number.
    236 };
    237 
    238 size_t hash_value(NumberOperationHint);
    239 
    240 V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream&, NumberOperationHint);
    241 
    242 NumberOperationHint NumberOperationHintOf(const Operator* op)
    243     WARN_UNUSED_RESULT;
    244 
    245 int ParameterCountOf(const Operator* op) WARN_UNUSED_RESULT;
    246 
    247 PretenureFlag PretenureFlagOf(const Operator* op) WARN_UNUSED_RESULT;
    248 
    249 UnicodeEncoding UnicodeEncodingOf(const Operator*) WARN_UNUSED_RESULT;
    250 
    251 // Interface for building simplified operators, which represent the
    252 // medium-level operations of V8, including adding numbers, allocating objects,
    253 // indexing into objects and arrays, etc.
    254 // All operators are typed but many are representation independent.
    255 
    256 // Number values from JS can be in one of these representations:
    257 //   - Tagged: word-sized integer that is either
    258 //     - a signed small integer (31 or 32 bits plus a tag)
    259 //     - a tagged pointer to a HeapNumber object that has a float64 field
    260 //   - Int32: an untagged signed 32-bit integer
    261 //   - Uint32: an untagged unsigned 32-bit integer
    262 //   - Float64: an untagged float64
    263 
    264 // Additional representations for intermediate code or non-JS code:
    265 //   - Int64: an untagged signed 64-bit integer
    266 //   - Uint64: an untagged unsigned 64-bit integer
    267 //   - Float32: an untagged float32
    268 
    269 // Boolean values can be:
    270 //   - Bool: a tagged pointer to either the canonical JS #false or
    271 //           the canonical JS #true object
    272 //   - Bit: an untagged integer 0 or 1, but word-sized
    273 class V8_EXPORT_PRIVATE SimplifiedOperatorBuilder final
    274     : public NON_EXPORTED_BASE(ZoneObject) {
    275  public:
    276   explicit SimplifiedOperatorBuilder(Zone* zone);
    277 
    278   const Operator* BooleanNot();
    279 
    280   const Operator* NumberEqual();
    281   const Operator* NumberLessThan();
    282   const Operator* NumberLessThanOrEqual();
    283   const Operator* NumberAdd();
    284   const Operator* NumberSubtract();
    285   const Operator* NumberMultiply();
    286   const Operator* NumberDivide();
    287   const Operator* NumberModulus();
    288   const Operator* NumberBitwiseOr();
    289   const Operator* NumberBitwiseXor();
    290   const Operator* NumberBitwiseAnd();
    291   const Operator* NumberShiftLeft();
    292   const Operator* NumberShiftRight();
    293   const Operator* NumberShiftRightLogical();
    294   const Operator* NumberImul();
    295   const Operator* NumberAbs();
    296   const Operator* NumberClz32();
    297   const Operator* NumberCeil();
    298   const Operator* NumberFloor();
    299   const Operator* NumberFround();
    300   const Operator* NumberAcos();
    301   const Operator* NumberAcosh();
    302   const Operator* NumberAsin();
    303   const Operator* NumberAsinh();
    304   const Operator* NumberAtan();
    305   const Operator* NumberAtan2();
    306   const Operator* NumberAtanh();
    307   const Operator* NumberCbrt();
    308   const Operator* NumberCos();
    309   const Operator* NumberCosh();
    310   const Operator* NumberExp();
    311   const Operator* NumberExpm1();
    312   const Operator* NumberLog();
    313   const Operator* NumberLog1p();
    314   const Operator* NumberLog10();
    315   const Operator* NumberLog2();
    316   const Operator* NumberMax();
    317   const Operator* NumberMin();
    318   const Operator* NumberPow();
    319   const Operator* NumberRound();
    320   const Operator* NumberSign();
    321   const Operator* NumberSin();
    322   const Operator* NumberSinh();
    323   const Operator* NumberSqrt();
    324   const Operator* NumberTan();
    325   const Operator* NumberTanh();
    326   const Operator* NumberTrunc();
    327   const Operator* NumberToBoolean();
    328   const Operator* NumberToInt32();
    329   const Operator* NumberToUint32();
    330   const Operator* NumberToUint8Clamped();
    331 
    332   const Operator* NumberSilenceNaN();
    333 
    334   const Operator* SpeculativeNumberAdd(NumberOperationHint hint);
    335   const Operator* SpeculativeNumberSubtract(NumberOperationHint hint);
    336   const Operator* SpeculativeNumberMultiply(NumberOperationHint hint);
    337   const Operator* SpeculativeNumberDivide(NumberOperationHint hint);
    338   const Operator* SpeculativeNumberModulus(NumberOperationHint hint);
    339   const Operator* SpeculativeNumberShiftLeft(NumberOperationHint hint);
    340   const Operator* SpeculativeNumberShiftRight(NumberOperationHint hint);
    341   const Operator* SpeculativeNumberShiftRightLogical(NumberOperationHint hint);
    342   const Operator* SpeculativeNumberBitwiseAnd(NumberOperationHint hint);
    343   const Operator* SpeculativeNumberBitwiseOr(NumberOperationHint hint);
    344   const Operator* SpeculativeNumberBitwiseXor(NumberOperationHint hint);
    345 
    346   const Operator* SpeculativeNumberLessThan(NumberOperationHint hint);
    347   const Operator* SpeculativeNumberLessThanOrEqual(NumberOperationHint hint);
    348   const Operator* SpeculativeNumberEqual(NumberOperationHint hint);
    349 
    350   const Operator* ReferenceEqual();
    351 
    352   const Operator* StringEqual();
    353   const Operator* StringLessThan();
    354   const Operator* StringLessThanOrEqual();
    355   const Operator* StringCharAt();
    356   const Operator* StringCharCodeAt();
    357   const Operator* StringFromCharCode();
    358   const Operator* StringFromCodePoint(UnicodeEncoding encoding);
    359   const Operator* StringIndexOf();
    360 
    361   const Operator* PlainPrimitiveToNumber();
    362   const Operator* PlainPrimitiveToWord32();
    363   const Operator* PlainPrimitiveToFloat64();
    364 
    365   const Operator* ChangeTaggedSignedToInt32();
    366   const Operator* ChangeTaggedToInt32();
    367   const Operator* ChangeTaggedToUint32();
    368   const Operator* ChangeTaggedToFloat64();
    369   const Operator* ChangeTaggedToTaggedSigned();
    370   const Operator* ChangeInt31ToTaggedSigned();
    371   const Operator* ChangeInt32ToTagged();
    372   const Operator* ChangeUint32ToTagged();
    373   const Operator* ChangeFloat64ToTagged();
    374   const Operator* ChangeFloat64ToTaggedPointer();
    375   const Operator* ChangeTaggedToBit();
    376   const Operator* ChangeBitToTagged();
    377   const Operator* TruncateTaggedToWord32();
    378   const Operator* TruncateTaggedToFloat64();
    379   const Operator* TruncateTaggedToBit();
    380 
    381   const Operator* CheckIf();
    382   const Operator* CheckBounds();
    383   const Operator* CheckMaps(CheckMapsFlags, ZoneHandleSet<Map>);
    384 
    385   const Operator* CheckHeapObject();
    386   const Operator* CheckInternalizedString();
    387   const Operator* CheckNumber();
    388   const Operator* CheckSmi();
    389   const Operator* CheckString();
    390   const Operator* CheckReceiver();
    391 
    392   const Operator* CheckedInt32Add();
    393   const Operator* CheckedInt32Sub();
    394   const Operator* CheckedInt32Div();
    395   const Operator* CheckedInt32Mod();
    396   const Operator* CheckedUint32Div();
    397   const Operator* CheckedUint32Mod();
    398   const Operator* CheckedInt32Mul(CheckForMinusZeroMode);
    399   const Operator* CheckedInt32ToTaggedSigned();
    400   const Operator* CheckedUint32ToInt32();
    401   const Operator* CheckedUint32ToTaggedSigned();
    402   const Operator* CheckedFloat64ToInt32(CheckForMinusZeroMode);
    403   const Operator* CheckedTaggedSignedToInt32();
    404   const Operator* CheckedTaggedToInt32(CheckForMinusZeroMode);
    405   const Operator* CheckedTaggedToFloat64(CheckTaggedInputMode);
    406   const Operator* CheckedTaggedToTaggedSigned();
    407   const Operator* CheckedTaggedToTaggedPointer();
    408   const Operator* CheckedTruncateTaggedToWord32();
    409 
    410   const Operator* CheckFloat64Hole(CheckFloat64HoleMode);
    411   const Operator* CheckTaggedHole();
    412   const Operator* ConvertTaggedHoleToUndefined();
    413 
    414   const Operator* ObjectIsDetectableCallable();
    415   const Operator* ObjectIsNonCallable();
    416   const Operator* ObjectIsNumber();
    417   const Operator* ObjectIsReceiver();
    418   const Operator* ObjectIsSmi();
    419   const Operator* ObjectIsString();
    420   const Operator* ObjectIsUndetectable();
    421 
    422   // new-rest-parameter-elements
    423   const Operator* NewRestParameterElements(int parameter_count);
    424 
    425   // new-unmapped-arguments-elements
    426   const Operator* NewUnmappedArgumentsElements(int parameter_count);
    427 
    428   // array-buffer-was-neutered buffer
    429   const Operator* ArrayBufferWasNeutered();
    430 
    431   // ensure-writable-fast-elements object, elements
    432   const Operator* EnsureWritableFastElements();
    433 
    434   // maybe-grow-fast-elements object, elements, index, length
    435   const Operator* MaybeGrowFastElements(GrowFastElementsFlags flags);
    436 
    437   // transition-elements-kind object, from-map, to-map
    438   const Operator* TransitionElementsKind(ElementsTransition transition);
    439 
    440   const Operator* Allocate(PretenureFlag pretenure = NOT_TENURED);
    441 
    442   const Operator* LoadField(FieldAccess const&);
    443   const Operator* StoreField(FieldAccess const&);
    444 
    445   // load-buffer buffer, offset, length
    446   const Operator* LoadBuffer(BufferAccess);
    447 
    448   // store-buffer buffer, offset, length, value
    449   const Operator* StoreBuffer(BufferAccess);
    450 
    451   // load-element [base + index]
    452   const Operator* LoadElement(ElementAccess const&);
    453 
    454   // store-element [base + index], value
    455   const Operator* StoreElement(ElementAccess const&);
    456 
    457   // load-typed-element buffer, [base + external + index]
    458   const Operator* LoadTypedElement(ExternalArrayType const&);
    459 
    460   // store-typed-element buffer, [base + external + index], value
    461   const Operator* StoreTypedElement(ExternalArrayType const&);
    462 
    463  private:
    464   Zone* zone() const { return zone_; }
    465 
    466   const SimplifiedOperatorGlobalCache& cache_;
    467   Zone* const zone_;
    468 
    469   DISALLOW_COPY_AND_ASSIGN(SimplifiedOperatorBuilder);
    470 };
    471 
    472 }  // namespace compiler
    473 }  // namespace internal
    474 }  // namespace v8
    475 
    476 #endif  // V8_COMPILER_SIMPLIFIED_OPERATOR_H_
    477