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: BufferAccess(ExternalArrayType external_array_type)39 explicit BufferAccess(ExternalArrayType external_array_type) 40 : external_array_type_(external_array_type) {} 41 external_array_type()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 tagFieldAccess70 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 tagElementAccess94 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: zone()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