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: BufferAccess(ExternalArrayType external_array_type)41 explicit BufferAccess(ExternalArrayType external_array_type) 42 : external_array_type_(external_array_type) {} 43 external_array_type()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 tagFieldAccess73 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 tagElementAccess100 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: CheckMapsParameters(CheckMapsFlags flags,ZoneHandleSet<Map> const & maps)162 CheckMapsParameters(CheckMapsFlags flags, ZoneHandleSet<Map> const& maps) 163 : flags_(flags), maps_(maps) {} 164 flags()165 CheckMapsFlags flags() const { return flags_; } maps()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 ElementsTransition(Mode mode,Handle<Map> source,Handle<Map> target)207 ElementsTransition(Mode mode, Handle<Map> source, Handle<Map> target) 208 : mode_(mode), source_(source), target_(target) {} 209 mode()210 Mode mode() const { return mode_; } source()211 Handle<Map> source() const { return source_; } target()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 NON_EXPORTED_BASE(ZoneObject)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