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