1 // Copyright 2012 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_GLOBALS_H_ 6 #define V8_GLOBALS_H_ 7 8 #include <stddef.h> 9 #include <stdint.h> 10 11 #include <ostream> 12 13 #include "src/base/build_config.h" 14 #include "src/base/logging.h" 15 #include "src/base/macros.h" 16 17 // Unfortunately, the INFINITY macro cannot be used with the '-pedantic' 18 // warning flag and certain versions of GCC due to a bug: 19 // http://gcc.gnu.org/bugzilla/show_bug.cgi?id=11931 20 // For now, we use the more involved template-based version from <limits>, but 21 // only when compiling with GCC versions affected by the bug (2.96.x - 4.0.x) 22 #if V8_CC_GNU && V8_GNUC_PREREQ(2, 96, 0) && !V8_GNUC_PREREQ(4, 1, 0) 23 # include <limits> // NOLINT 24 # define V8_INFINITY std::numeric_limits<double>::infinity() 25 #elif V8_LIBC_MSVCRT 26 # define V8_INFINITY HUGE_VAL 27 #elif V8_OS_AIX 28 #define V8_INFINITY (__builtin_inff()) 29 #else 30 # define V8_INFINITY INFINITY 31 #endif 32 33 namespace v8 { 34 35 namespace base { 36 class Mutex; 37 class RecursiveMutex; 38 class VirtualMemory; 39 } 40 41 namespace internal { 42 43 // Determine whether we are running in a simulated environment. 44 // Setting USE_SIMULATOR explicitly from the build script will force 45 // the use of a simulated environment. 46 #if !defined(USE_SIMULATOR) 47 #if (V8_TARGET_ARCH_ARM64 && !V8_HOST_ARCH_ARM64) 48 #define USE_SIMULATOR 1 49 #endif 50 #if (V8_TARGET_ARCH_ARM && !V8_HOST_ARCH_ARM) 51 #define USE_SIMULATOR 1 52 #endif 53 #if (V8_TARGET_ARCH_PPC && !V8_HOST_ARCH_PPC) 54 #define USE_SIMULATOR 1 55 #endif 56 #if (V8_TARGET_ARCH_MIPS && !V8_HOST_ARCH_MIPS) 57 #define USE_SIMULATOR 1 58 #endif 59 #if (V8_TARGET_ARCH_MIPS64 && !V8_HOST_ARCH_MIPS64) 60 #define USE_SIMULATOR 1 61 #endif 62 #if (V8_TARGET_ARCH_S390 && !V8_HOST_ARCH_S390) 63 #define USE_SIMULATOR 1 64 #endif 65 #endif 66 67 // Determine whether the architecture uses an embedded constant pool 68 // (contiguous constant pool embedded in code object). 69 #if V8_TARGET_ARCH_PPC 70 #define V8_EMBEDDED_CONSTANT_POOL 1 71 #else 72 #define V8_EMBEDDED_CONSTANT_POOL 0 73 #endif 74 75 #ifdef V8_TARGET_ARCH_ARM 76 // Set stack limit lower for ARM than for other architectures because 77 // stack allocating MacroAssembler takes 120K bytes. 78 // See issue crbug.com/405338 79 #define V8_DEFAULT_STACK_SIZE_KB 864 80 #else 81 // Slightly less than 1MB, since Windows' default stack size for 82 // the main execution thread is 1MB for both 32 and 64-bit. 83 #define V8_DEFAULT_STACK_SIZE_KB 984 84 #endif 85 86 87 // Determine whether double field unboxing feature is enabled. 88 #if V8_TARGET_ARCH_64_BIT 89 #define V8_DOUBLE_FIELDS_UNBOXING 1 90 #else 91 #define V8_DOUBLE_FIELDS_UNBOXING 0 92 #endif 93 94 95 typedef uint8_t byte; 96 typedef byte* Address; 97 98 // ----------------------------------------------------------------------------- 99 // Constants 100 101 const int KB = 1024; 102 const int MB = KB * KB; 103 const int GB = KB * KB * KB; 104 const int kMaxInt = 0x7FFFFFFF; 105 const int kMinInt = -kMaxInt - 1; 106 const int kMaxInt8 = (1 << 7) - 1; 107 const int kMinInt8 = -(1 << 7); 108 const int kMaxUInt8 = (1 << 8) - 1; 109 const int kMinUInt8 = 0; 110 const int kMaxInt16 = (1 << 15) - 1; 111 const int kMinInt16 = -(1 << 15); 112 const int kMaxUInt16 = (1 << 16) - 1; 113 const int kMinUInt16 = 0; 114 115 const uint32_t kMaxUInt32 = 0xFFFFFFFFu; 116 const int kMinUInt32 = 0; 117 118 const int kCharSize = sizeof(char); // NOLINT 119 const int kShortSize = sizeof(short); // NOLINT 120 const int kIntSize = sizeof(int); // NOLINT 121 const int kInt32Size = sizeof(int32_t); // NOLINT 122 const int kInt64Size = sizeof(int64_t); // NOLINT 123 const int kFloatSize = sizeof(float); // NOLINT 124 const int kDoubleSize = sizeof(double); // NOLINT 125 const int kIntptrSize = sizeof(intptr_t); // NOLINT 126 const int kPointerSize = sizeof(void*); // NOLINT 127 #if V8_TARGET_ARCH_X64 && V8_TARGET_ARCH_32_BIT 128 const int kRegisterSize = kPointerSize + kPointerSize; 129 #else 130 const int kRegisterSize = kPointerSize; 131 #endif 132 const int kPCOnStackSize = kRegisterSize; 133 const int kFPOnStackSize = kRegisterSize; 134 135 #if V8_TARGET_ARCH_X64 || V8_TARGET_ARCH_IA32 || V8_TARGET_ARCH_X87 136 const int kElidedFrameSlots = kPCOnStackSize / kPointerSize; 137 #else 138 const int kElidedFrameSlots = 0; 139 #endif 140 141 const int kDoubleSizeLog2 = 3; 142 143 #if V8_HOST_ARCH_64_BIT 144 const int kPointerSizeLog2 = 3; 145 const intptr_t kIntptrSignBit = V8_INT64_C(0x8000000000000000); 146 const uintptr_t kUintptrAllBitsSet = V8_UINT64_C(0xFFFFFFFFFFFFFFFF); 147 const bool kRequiresCodeRange = true; 148 #if V8_TARGET_ARCH_MIPS64 149 // To use pseudo-relative jumps such as j/jal instructions which have 28-bit 150 // encoded immediate, the addresses have to be in range of 256MB aligned 151 // region. Used only for large object space. 152 const size_t kMaximalCodeRangeSize = 256 * MB; 153 const size_t kCodeRangeAreaAlignment = 256 * MB; 154 #elif V8_HOST_ARCH_PPC && V8_TARGET_ARCH_PPC && V8_OS_LINUX 155 const size_t kMaximalCodeRangeSize = 512 * MB; 156 const size_t kCodeRangeAreaAlignment = 64 * KB; // OS page on PPC Linux 157 #else 158 const size_t kMaximalCodeRangeSize = 512 * MB; 159 const size_t kCodeRangeAreaAlignment = 4 * KB; // OS page. 160 #endif 161 #if V8_OS_WIN 162 const size_t kMinimumCodeRangeSize = 4 * MB; 163 const size_t kReservedCodeRangePages = 1; 164 // On PPC Linux PageSize is 4MB 165 #elif V8_HOST_ARCH_PPC && V8_TARGET_ARCH_PPC && V8_OS_LINUX 166 const size_t kMinimumCodeRangeSize = 12 * MB; 167 const size_t kReservedCodeRangePages = 0; 168 #else 169 const size_t kMinimumCodeRangeSize = 3 * MB; 170 const size_t kReservedCodeRangePages = 0; 171 #endif 172 #else 173 const int kPointerSizeLog2 = 2; 174 const intptr_t kIntptrSignBit = 0x80000000; 175 const uintptr_t kUintptrAllBitsSet = 0xFFFFFFFFu; 176 #if V8_TARGET_ARCH_X64 && V8_TARGET_ARCH_32_BIT 177 // x32 port also requires code range. 178 const bool kRequiresCodeRange = true; 179 const size_t kMaximalCodeRangeSize = 256 * MB; 180 const size_t kMinimumCodeRangeSize = 3 * MB; 181 const size_t kCodeRangeAreaAlignment = 4 * KB; // OS page. 182 #elif V8_HOST_ARCH_PPC && V8_TARGET_ARCH_PPC && V8_OS_LINUX 183 const bool kRequiresCodeRange = false; 184 const size_t kMaximalCodeRangeSize = 0 * MB; 185 const size_t kMinimumCodeRangeSize = 0 * MB; 186 const size_t kCodeRangeAreaAlignment = 64 * KB; // OS page on PPC Linux 187 #else 188 const bool kRequiresCodeRange = false; 189 const size_t kMaximalCodeRangeSize = 0 * MB; 190 const size_t kMinimumCodeRangeSize = 0 * MB; 191 const size_t kCodeRangeAreaAlignment = 4 * KB; // OS page. 192 #endif 193 const size_t kReservedCodeRangePages = 0; 194 #endif 195 196 // The external allocation limit should be below 256 MB on all architectures 197 // to avoid that resource-constrained embedders run low on memory. 198 const int kExternalAllocationLimit = 192 * 1024 * 1024; 199 200 STATIC_ASSERT(kPointerSize == (1 << kPointerSizeLog2)); 201 202 const int kBitsPerByte = 8; 203 const int kBitsPerByteLog2 = 3; 204 const int kBitsPerPointer = kPointerSize * kBitsPerByte; 205 const int kBitsPerInt = kIntSize * kBitsPerByte; 206 207 // IEEE 754 single precision floating point number bit layout. 208 const uint32_t kBinary32SignMask = 0x80000000u; 209 const uint32_t kBinary32ExponentMask = 0x7f800000u; 210 const uint32_t kBinary32MantissaMask = 0x007fffffu; 211 const int kBinary32ExponentBias = 127; 212 const int kBinary32MaxExponent = 0xFE; 213 const int kBinary32MinExponent = 0x01; 214 const int kBinary32MantissaBits = 23; 215 const int kBinary32ExponentShift = 23; 216 217 // Quiet NaNs have bits 51 to 62 set, possibly the sign bit, and no 218 // other bits set. 219 const uint64_t kQuietNaNMask = static_cast<uint64_t>(0xfff) << 51; 220 221 // Latin1/UTF-16 constants 222 // Code-point values in Unicode 4.0 are 21 bits wide. 223 // Code units in UTF-16 are 16 bits wide. 224 typedef uint16_t uc16; 225 typedef int32_t uc32; 226 const int kOneByteSize = kCharSize; 227 const int kUC16Size = sizeof(uc16); // NOLINT 228 229 // 128 bit SIMD value size. 230 const int kSimd128Size = 16; 231 232 // Round up n to be a multiple of sz, where sz is a power of 2. 233 #define ROUND_UP(n, sz) (((n) + ((sz) - 1)) & ~((sz) - 1)) 234 235 236 // FUNCTION_ADDR(f) gets the address of a C function f. 237 #define FUNCTION_ADDR(f) \ 238 (reinterpret_cast<v8::internal::Address>(reinterpret_cast<intptr_t>(f))) 239 240 241 // FUNCTION_CAST<F>(addr) casts an address into a function 242 // of type F. Used to invoke generated code from within C. 243 template <typename F> 244 F FUNCTION_CAST(Address addr) { 245 return reinterpret_cast<F>(reinterpret_cast<intptr_t>(addr)); 246 } 247 248 249 // Determine whether the architecture uses function descriptors 250 // which provide a level of indirection between the function pointer 251 // and the function entrypoint. 252 #if V8_HOST_ARCH_PPC && \ 253 (V8_OS_AIX || (V8_TARGET_ARCH_PPC64 && V8_TARGET_BIG_ENDIAN)) 254 #define USES_FUNCTION_DESCRIPTORS 1 255 #define FUNCTION_ENTRYPOINT_ADDRESS(f) \ 256 (reinterpret_cast<v8::internal::Address*>( \ 257 &(reinterpret_cast<intptr_t*>(f)[0]))) 258 #else 259 #define USES_FUNCTION_DESCRIPTORS 0 260 #endif 261 262 263 // ----------------------------------------------------------------------------- 264 // Forward declarations for frequently used classes 265 // (sorted alphabetically) 266 267 class FreeStoreAllocationPolicy; 268 template <typename T, class P = FreeStoreAllocationPolicy> class List; 269 270 // ----------------------------------------------------------------------------- 271 // Declarations for use in both the preparser and the rest of V8. 272 273 // The Strict Mode (ECMA-262 5th edition, 4.2.2). 274 275 enum LanguageMode { SLOPPY, STRICT, LANGUAGE_END = 3 }; 276 277 278 inline std::ostream& operator<<(std::ostream& os, const LanguageMode& mode) { 279 switch (mode) { 280 case SLOPPY: return os << "sloppy"; 281 case STRICT: return os << "strict"; 282 default: UNREACHABLE(); 283 } 284 return os; 285 } 286 287 288 inline bool is_sloppy(LanguageMode language_mode) { 289 return language_mode == SLOPPY; 290 } 291 292 293 inline bool is_strict(LanguageMode language_mode) { 294 return language_mode != SLOPPY; 295 } 296 297 298 inline bool is_valid_language_mode(int language_mode) { 299 return language_mode == SLOPPY || language_mode == STRICT; 300 } 301 302 303 inline LanguageMode construct_language_mode(bool strict_bit) { 304 return static_cast<LanguageMode>(strict_bit); 305 } 306 307 308 // Mask for the sign bit in a smi. 309 const intptr_t kSmiSignMask = kIntptrSignBit; 310 311 const int kObjectAlignmentBits = kPointerSizeLog2; 312 const intptr_t kObjectAlignment = 1 << kObjectAlignmentBits; 313 const intptr_t kObjectAlignmentMask = kObjectAlignment - 1; 314 315 // Desired alignment for pointers. 316 const intptr_t kPointerAlignment = (1 << kPointerSizeLog2); 317 const intptr_t kPointerAlignmentMask = kPointerAlignment - 1; 318 319 // Desired alignment for double values. 320 const intptr_t kDoubleAlignment = 8; 321 const intptr_t kDoubleAlignmentMask = kDoubleAlignment - 1; 322 323 // Desired alignment for 128 bit SIMD values. 324 const intptr_t kSimd128Alignment = 16; 325 const intptr_t kSimd128AlignmentMask = kSimd128Alignment - 1; 326 327 // Desired alignment for generated code is 32 bytes (to improve cache line 328 // utilization). 329 const int kCodeAlignmentBits = 5; 330 const intptr_t kCodeAlignment = 1 << kCodeAlignmentBits; 331 const intptr_t kCodeAlignmentMask = kCodeAlignment - 1; 332 333 // The owner field of a page is tagged with the page header tag. We need that 334 // to find out if a slot is part of a large object. If we mask out the lower 335 // 0xfffff bits (1M pages), go to the owner offset, and see that this field 336 // is tagged with the page header tag, we can just look up the owner. 337 // Otherwise, we know that we are somewhere (not within the first 1M) in a 338 // large object. 339 const int kPageHeaderTag = 3; 340 const int kPageHeaderTagSize = 2; 341 const intptr_t kPageHeaderTagMask = (1 << kPageHeaderTagSize) - 1; 342 343 344 // Zap-value: The value used for zapping dead objects. 345 // Should be a recognizable hex value tagged as a failure. 346 #ifdef V8_HOST_ARCH_64_BIT 347 const Address kZapValue = 348 reinterpret_cast<Address>(V8_UINT64_C(0xdeadbeedbeadbeef)); 349 const Address kHandleZapValue = 350 reinterpret_cast<Address>(V8_UINT64_C(0x1baddead0baddeaf)); 351 const Address kGlobalHandleZapValue = 352 reinterpret_cast<Address>(V8_UINT64_C(0x1baffed00baffedf)); 353 const Address kFromSpaceZapValue = 354 reinterpret_cast<Address>(V8_UINT64_C(0x1beefdad0beefdaf)); 355 const uint64_t kDebugZapValue = V8_UINT64_C(0xbadbaddbbadbaddb); 356 const uint64_t kSlotsZapValue = V8_UINT64_C(0xbeefdeadbeefdeef); 357 const uint64_t kFreeListZapValue = 0xfeed1eaffeed1eaf; 358 #else 359 const Address kZapValue = reinterpret_cast<Address>(0xdeadbeef); 360 const Address kHandleZapValue = reinterpret_cast<Address>(0xbaddeaf); 361 const Address kGlobalHandleZapValue = reinterpret_cast<Address>(0xbaffedf); 362 const Address kFromSpaceZapValue = reinterpret_cast<Address>(0xbeefdaf); 363 const uint32_t kSlotsZapValue = 0xbeefdeef; 364 const uint32_t kDebugZapValue = 0xbadbaddb; 365 const uint32_t kFreeListZapValue = 0xfeed1eaf; 366 #endif 367 368 const int kCodeZapValue = 0xbadc0de; 369 const uint32_t kPhantomReferenceZap = 0xca11bac; 370 371 // On Intel architecture, cache line size is 64 bytes. 372 // On ARM it may be less (32 bytes), but as far this constant is 373 // used for aligning data, it doesn't hurt to align on a greater value. 374 #define PROCESSOR_CACHE_LINE_SIZE 64 375 376 // Constants relevant to double precision floating point numbers. 377 // If looking only at the top 32 bits, the QNaN mask is bits 19 to 30. 378 const uint32_t kQuietNaNHighBitsMask = 0xfff << (51 - 32); 379 380 381 // ----------------------------------------------------------------------------- 382 // Forward declarations for frequently used classes 383 384 class AccessorInfo; 385 class Allocation; 386 class Arguments; 387 class Assembler; 388 class Code; 389 class CodeGenerator; 390 class CodeStub; 391 class Context; 392 class Debug; 393 class DebugInfo; 394 class Descriptor; 395 class DescriptorArray; 396 class TransitionArray; 397 class ExternalReference; 398 class FixedArray; 399 class FunctionTemplateInfo; 400 class MemoryChunk; 401 class SeededNumberDictionary; 402 class UnseededNumberDictionary; 403 class NameDictionary; 404 class GlobalDictionary; 405 template <typename T> class MaybeHandle; 406 template <typename T> class Handle; 407 class Heap; 408 class HeapObject; 409 class IC; 410 class InterceptorInfo; 411 class Isolate; 412 class JSReceiver; 413 class JSArray; 414 class JSFunction; 415 class JSObject; 416 class LargeObjectSpace; 417 class MacroAssembler; 418 class Map; 419 class MapSpace; 420 class MarkCompactCollector; 421 class NewSpace; 422 class Object; 423 class OldSpace; 424 class ParameterCount; 425 class Foreign; 426 class Scope; 427 class ScopeInfo; 428 class Script; 429 class Smi; 430 template <typename Config, class Allocator = FreeStoreAllocationPolicy> 431 class SplayTree; 432 class String; 433 class Symbol; 434 class Name; 435 class Struct; 436 class TypeFeedbackVector; 437 class Variable; 438 class RelocInfo; 439 class Deserializer; 440 class MessageLocation; 441 442 typedef bool (*WeakSlotCallback)(Object** pointer); 443 444 typedef bool (*WeakSlotCallbackWithHeap)(Heap* heap, Object** pointer); 445 446 // ----------------------------------------------------------------------------- 447 // Miscellaneous 448 449 // NOTE: SpaceIterator depends on AllocationSpace enumeration values being 450 // consecutive. 451 // Keep this enum in sync with the ObjectSpace enum in v8.h 452 enum AllocationSpace { 453 NEW_SPACE, // Semispaces collected with copying collector. 454 OLD_SPACE, // May contain pointers to new space. 455 CODE_SPACE, // No pointers to new space, marked executable. 456 MAP_SPACE, // Only and all map objects. 457 LO_SPACE, // Promoted large objects. 458 459 FIRST_SPACE = NEW_SPACE, 460 LAST_SPACE = LO_SPACE, 461 FIRST_PAGED_SPACE = OLD_SPACE, 462 LAST_PAGED_SPACE = MAP_SPACE 463 }; 464 const int kSpaceTagSize = 3; 465 const int kSpaceTagMask = (1 << kSpaceTagSize) - 1; 466 467 enum AllocationAlignment { 468 kWordAligned, 469 kDoubleAligned, 470 kDoubleUnaligned, 471 kSimd128Unaligned 472 }; 473 474 // Possible outcomes for decisions. 475 enum class Decision : uint8_t { kUnknown, kTrue, kFalse }; 476 477 inline size_t hash_value(Decision decision) { 478 return static_cast<uint8_t>(decision); 479 } 480 481 inline std::ostream& operator<<(std::ostream& os, Decision decision) { 482 switch (decision) { 483 case Decision::kUnknown: 484 return os << "Unknown"; 485 case Decision::kTrue: 486 return os << "True"; 487 case Decision::kFalse: 488 return os << "False"; 489 } 490 UNREACHABLE(); 491 return os; 492 } 493 494 // Supported write barrier modes. 495 enum WriteBarrierKind : uint8_t { 496 kNoWriteBarrier, 497 kMapWriteBarrier, 498 kPointerWriteBarrier, 499 kFullWriteBarrier 500 }; 501 502 inline size_t hash_value(WriteBarrierKind kind) { 503 return static_cast<uint8_t>(kind); 504 } 505 506 inline std::ostream& operator<<(std::ostream& os, WriteBarrierKind kind) { 507 switch (kind) { 508 case kNoWriteBarrier: 509 return os << "NoWriteBarrier"; 510 case kMapWriteBarrier: 511 return os << "MapWriteBarrier"; 512 case kPointerWriteBarrier: 513 return os << "PointerWriteBarrier"; 514 case kFullWriteBarrier: 515 return os << "FullWriteBarrier"; 516 } 517 UNREACHABLE(); 518 return os; 519 } 520 521 // A flag that indicates whether objects should be pretenured when 522 // allocated (allocated directly into the old generation) or not 523 // (allocated in the young generation if the object size and type 524 // allows). 525 enum PretenureFlag { NOT_TENURED, TENURED }; 526 527 inline std::ostream& operator<<(std::ostream& os, const PretenureFlag& flag) { 528 switch (flag) { 529 case NOT_TENURED: 530 return os << "NotTenured"; 531 case TENURED: 532 return os << "Tenured"; 533 } 534 UNREACHABLE(); 535 return os; 536 } 537 538 enum MinimumCapacity { 539 USE_DEFAULT_MINIMUM_CAPACITY, 540 USE_CUSTOM_MINIMUM_CAPACITY 541 }; 542 543 enum GarbageCollector { SCAVENGER, MARK_COMPACTOR }; 544 545 enum Executability { NOT_EXECUTABLE, EXECUTABLE }; 546 547 enum VisitMode { 548 VISIT_ALL, 549 VISIT_ALL_IN_SCAVENGE, 550 VISIT_ALL_IN_SWEEP_NEWSPACE, 551 VISIT_ONLY_STRONG, 552 VISIT_ONLY_STRONG_FOR_SERIALIZATION, 553 VISIT_ONLY_STRONG_ROOT_LIST, 554 }; 555 556 // Flag indicating whether code is built into the VM (one of the natives files). 557 enum NativesFlag { NOT_NATIVES_CODE, EXTENSION_CODE, NATIVES_CODE }; 558 559 // JavaScript defines two kinds of 'nil'. 560 enum NilValue { kNullValue, kUndefinedValue }; 561 562 // ParseRestriction is used to restrict the set of valid statements in a 563 // unit of compilation. Restriction violations cause a syntax error. 564 enum ParseRestriction { 565 NO_PARSE_RESTRICTION, // All expressions are allowed. 566 ONLY_SINGLE_FUNCTION_LITERAL // Only a single FunctionLiteral expression. 567 }; 568 569 // A CodeDesc describes a buffer holding instructions and relocation 570 // information. The instructions start at the beginning of the buffer 571 // and grow forward, the relocation information starts at the end of 572 // the buffer and grows backward. A constant pool may exist at the 573 // end of the instructions. 574 // 575 // |<--------------- buffer_size ----------------------------------->| 576 // |<------------- instr_size ---------->| |<-- reloc_size -->| 577 // | |<- const_pool_size ->| | 578 // +=====================================+========+==================+ 579 // | instructions | data | free | reloc info | 580 // +=====================================+========+==================+ 581 // ^ 582 // | 583 // buffer 584 585 struct CodeDesc { 586 byte* buffer; 587 int buffer_size; 588 int instr_size; 589 int reloc_size; 590 int constant_pool_size; 591 byte* unwinding_info; 592 int unwinding_info_size; 593 Assembler* origin; 594 }; 595 596 597 // Callback function used for checking constraints when copying/relocating 598 // objects. Returns true if an object can be copied/relocated from its 599 // old_addr to a new_addr. 600 typedef bool (*ConstraintCallback)(Address new_addr, Address old_addr); 601 602 603 // Callback function on inline caches, used for iterating over inline caches 604 // in compiled code. 605 typedef void (*InlineCacheCallback)(Code* code, Address ic); 606 607 608 // State for inline cache call sites. Aliased as IC::State. 609 enum InlineCacheState { 610 // Has never been executed. 611 UNINITIALIZED, 612 // Has been executed but monomorhic state has been delayed. 613 PREMONOMORPHIC, 614 // Has been executed and only one receiver type has been seen. 615 MONOMORPHIC, 616 // Check failed due to prototype (or map deprecation). 617 RECOMPUTE_HANDLER, 618 // Multiple receiver types have been seen. 619 POLYMORPHIC, 620 // Many receiver types have been seen. 621 MEGAMORPHIC, 622 // A generic handler is installed and no extra typefeedback is recorded. 623 GENERIC, 624 }; 625 626 enum CacheHolderFlag { 627 kCacheOnPrototype, 628 kCacheOnPrototypeReceiverIsDictionary, 629 kCacheOnPrototypeReceiverIsPrimitive, 630 kCacheOnReceiver 631 }; 632 633 enum WhereToStart { kStartAtReceiver, kStartAtPrototype }; 634 635 // The Store Buffer (GC). 636 typedef enum { 637 kStoreBufferFullEvent, 638 kStoreBufferStartScanningPagesEvent, 639 kStoreBufferScanningPageEvent 640 } StoreBufferEvent; 641 642 643 typedef void (*StoreBufferCallback)(Heap* heap, 644 MemoryChunk* page, 645 StoreBufferEvent event); 646 647 648 // Union used for fast testing of specific double values. 649 union DoubleRepresentation { 650 double value; 651 int64_t bits; 652 DoubleRepresentation(double x) { value = x; } 653 bool operator==(const DoubleRepresentation& other) const { 654 return bits == other.bits; 655 } 656 }; 657 658 659 // Union used for customized checking of the IEEE double types 660 // inlined within v8 runtime, rather than going to the underlying 661 // platform headers and libraries 662 union IeeeDoubleLittleEndianArchType { 663 double d; 664 struct { 665 unsigned int man_low :32; 666 unsigned int man_high :20; 667 unsigned int exp :11; 668 unsigned int sign :1; 669 } bits; 670 }; 671 672 673 union IeeeDoubleBigEndianArchType { 674 double d; 675 struct { 676 unsigned int sign :1; 677 unsigned int exp :11; 678 unsigned int man_high :20; 679 unsigned int man_low :32; 680 } bits; 681 }; 682 683 #if V8_TARGET_LITTLE_ENDIAN 684 typedef IeeeDoubleLittleEndianArchType IeeeDoubleArchType; 685 const int kIeeeDoubleMantissaWordOffset = 0; 686 const int kIeeeDoubleExponentWordOffset = 4; 687 #else 688 typedef IeeeDoubleBigEndianArchType IeeeDoubleArchType; 689 const int kIeeeDoubleMantissaWordOffset = 4; 690 const int kIeeeDoubleExponentWordOffset = 0; 691 #endif 692 693 // AccessorCallback 694 struct AccessorDescriptor { 695 Object* (*getter)(Isolate* isolate, Object* object, void* data); 696 Object* (*setter)( 697 Isolate* isolate, JSObject* object, Object* value, void* data); 698 void* data; 699 }; 700 701 702 // ----------------------------------------------------------------------------- 703 // Macros 704 705 // Testers for test. 706 707 #define HAS_SMI_TAG(value) \ 708 ((reinterpret_cast<intptr_t>(value) & kSmiTagMask) == kSmiTag) 709 710 // OBJECT_POINTER_ALIGN returns the value aligned as a HeapObject pointer 711 #define OBJECT_POINTER_ALIGN(value) \ 712 (((value) + kObjectAlignmentMask) & ~kObjectAlignmentMask) 713 714 // POINTER_SIZE_ALIGN returns the value aligned as a pointer. 715 #define POINTER_SIZE_ALIGN(value) \ 716 (((value) + kPointerAlignmentMask) & ~kPointerAlignmentMask) 717 718 // CODE_POINTER_ALIGN returns the value aligned as a generated code segment. 719 #define CODE_POINTER_ALIGN(value) \ 720 (((value) + kCodeAlignmentMask) & ~kCodeAlignmentMask) 721 722 // DOUBLE_POINTER_ALIGN returns the value algined for double pointers. 723 #define DOUBLE_POINTER_ALIGN(value) \ 724 (((value) + kDoubleAlignmentMask) & ~kDoubleAlignmentMask) 725 726 727 // CPU feature flags. 728 enum CpuFeature { 729 // x86 730 SSE4_1, 731 SSE3, 732 SAHF, 733 AVX, 734 FMA3, 735 BMI1, 736 BMI2, 737 LZCNT, 738 POPCNT, 739 ATOM, 740 // ARM 741 VFP3, 742 ARMv7, 743 ARMv8, 744 SUDIV, 745 UNALIGNED_ACCESSES, 746 MOVW_MOVT_IMMEDIATE_LOADS, 747 VFP32DREGS, 748 NEON, 749 // MIPS, MIPS64 750 FPU, 751 FP64FPU, 752 MIPSr1, 753 MIPSr2, 754 MIPSr6, 755 // ARM64 756 ALWAYS_ALIGN_CSP, 757 // PPC 758 FPR_GPR_MOV, 759 LWSYNC, 760 ISELECT, 761 // S390 762 DISTINCT_OPS, 763 GENERAL_INSTR_EXT, 764 FLOATING_POINT_EXT, 765 NUMBER_OF_CPU_FEATURES 766 }; 767 768 // Defines hints about receiver values based on structural knowledge. 769 enum class ConvertReceiverMode : unsigned { 770 kNullOrUndefined, // Guaranteed to be null or undefined. 771 kNotNullOrUndefined, // Guaranteed to never be null or undefined. 772 kAny // No specific knowledge about receiver. 773 }; 774 775 inline size_t hash_value(ConvertReceiverMode mode) { 776 return bit_cast<unsigned>(mode); 777 } 778 779 inline std::ostream& operator<<(std::ostream& os, ConvertReceiverMode mode) { 780 switch (mode) { 781 case ConvertReceiverMode::kNullOrUndefined: 782 return os << "NULL_OR_UNDEFINED"; 783 case ConvertReceiverMode::kNotNullOrUndefined: 784 return os << "NOT_NULL_OR_UNDEFINED"; 785 case ConvertReceiverMode::kAny: 786 return os << "ANY"; 787 } 788 UNREACHABLE(); 789 return os; 790 } 791 792 // Defines whether tail call optimization is allowed. 793 enum class TailCallMode : unsigned { kAllow, kDisallow }; 794 795 inline size_t hash_value(TailCallMode mode) { return bit_cast<unsigned>(mode); } 796 797 inline std::ostream& operator<<(std::ostream& os, TailCallMode mode) { 798 switch (mode) { 799 case TailCallMode::kAllow: 800 return os << "ALLOW_TAIL_CALLS"; 801 case TailCallMode::kDisallow: 802 return os << "DISALLOW_TAIL_CALLS"; 803 } 804 UNREACHABLE(); 805 return os; 806 } 807 808 // Defines specifics about arguments object or rest parameter creation. 809 enum class CreateArgumentsType : uint8_t { 810 kMappedArguments, 811 kUnmappedArguments, 812 kRestParameter 813 }; 814 815 inline size_t hash_value(CreateArgumentsType type) { 816 return bit_cast<uint8_t>(type); 817 } 818 819 inline std::ostream& operator<<(std::ostream& os, CreateArgumentsType type) { 820 switch (type) { 821 case CreateArgumentsType::kMappedArguments: 822 return os << "MAPPED_ARGUMENTS"; 823 case CreateArgumentsType::kUnmappedArguments: 824 return os << "UNMAPPED_ARGUMENTS"; 825 case CreateArgumentsType::kRestParameter: 826 return os << "REST_PARAMETER"; 827 } 828 UNREACHABLE(); 829 return os; 830 } 831 832 // Used to specify if a macro instruction must perform a smi check on tagged 833 // values. 834 enum SmiCheckType { 835 DONT_DO_SMI_CHECK, 836 DO_SMI_CHECK 837 }; 838 839 840 enum ScopeType { 841 EVAL_SCOPE, // The top-level scope for an eval source. 842 FUNCTION_SCOPE, // The top-level scope for a function. 843 MODULE_SCOPE, // The scope introduced by a module literal 844 SCRIPT_SCOPE, // The top-level scope for a script or a top-level eval. 845 CATCH_SCOPE, // The scope introduced by catch. 846 BLOCK_SCOPE, // The scope introduced by a new block. 847 WITH_SCOPE // The scope introduced by with. 848 }; 849 850 // The mips architecture prior to revision 5 has inverted encoding for sNaN. 851 // The x87 FPU convert the sNaN to qNaN automatically when loading sNaN from 852 // memmory. 853 // Use mips sNaN which is a not used qNaN in x87 port as sNaN to workaround this 854 // issue 855 // for some test cases. 856 #if (V8_TARGET_ARCH_MIPS && !defined(_MIPS_ARCH_MIPS32R6)) || \ 857 (V8_TARGET_ARCH_MIPS64 && !defined(_MIPS_ARCH_MIPS64R6)) || \ 858 (V8_TARGET_ARCH_X87) 859 const uint32_t kHoleNanUpper32 = 0xFFFF7FFF; 860 const uint32_t kHoleNanLower32 = 0xFFFF7FFF; 861 #else 862 const uint32_t kHoleNanUpper32 = 0xFFF7FFFF; 863 const uint32_t kHoleNanLower32 = 0xFFF7FFFF; 864 #endif 865 866 const uint64_t kHoleNanInt64 = 867 (static_cast<uint64_t>(kHoleNanUpper32) << 32) | kHoleNanLower32; 868 869 870 // ES6 section 20.1.2.6 Number.MAX_SAFE_INTEGER 871 const double kMaxSafeInteger = 9007199254740991.0; // 2^53-1 872 873 874 // The order of this enum has to be kept in sync with the predicates below. 875 enum VariableMode { 876 // User declared variables: 877 VAR, // declared via 'var', and 'function' declarations 878 879 CONST_LEGACY, // declared via legacy 'const' declarations 880 881 LET, // declared via 'let' declarations (first lexical) 882 883 CONST, // declared via 'const' declarations (last lexical) 884 885 // Variables introduced by the compiler: 886 TEMPORARY, // temporary variables (not user-visible), stack-allocated 887 // unless the scope as a whole has forced context allocation 888 889 DYNAMIC, // always require dynamic lookup (we don't know 890 // the declaration) 891 892 DYNAMIC_GLOBAL, // requires dynamic lookup, but we know that the 893 // variable is global unless it has been shadowed 894 // by an eval-introduced variable 895 896 DYNAMIC_LOCAL // requires dynamic lookup, but we know that the 897 // variable is local and where it is unless it 898 // has been shadowed by an eval-introduced 899 // variable 900 }; 901 902 inline bool IsDynamicVariableMode(VariableMode mode) { 903 return mode >= DYNAMIC && mode <= DYNAMIC_LOCAL; 904 } 905 906 907 inline bool IsDeclaredVariableMode(VariableMode mode) { 908 return mode >= VAR && mode <= CONST; 909 } 910 911 912 inline bool IsLexicalVariableMode(VariableMode mode) { 913 return mode >= LET && mode <= CONST; 914 } 915 916 917 inline bool IsImmutableVariableMode(VariableMode mode) { 918 return mode == CONST || mode == CONST_LEGACY; 919 } 920 921 922 enum class VariableLocation { 923 // Before and during variable allocation, a variable whose location is 924 // not yet determined. After allocation, a variable looked up as a 925 // property on the global object (and possibly absent). name() is the 926 // variable name, index() is invalid. 927 UNALLOCATED, 928 929 // A slot in the parameter section on the stack. index() is the 930 // parameter index, counting left-to-right. The receiver is index -1; 931 // the first parameter is index 0. 932 PARAMETER, 933 934 // A slot in the local section on the stack. index() is the variable 935 // index in the stack frame, starting at 0. 936 LOCAL, 937 938 // An indexed slot in a heap context. index() is the variable index in 939 // the context object on the heap, starting at 0. scope() is the 940 // corresponding scope. 941 CONTEXT, 942 943 // An indexed slot in a script context that contains a respective global 944 // property cell. name() is the variable name, index() is the variable 945 // index in the context object on the heap, starting at 0. scope() is the 946 // corresponding script scope. 947 GLOBAL, 948 949 // A named slot in a heap context. name() is the variable name in the 950 // context object on the heap, with lookup starting at the current 951 // context. index() is invalid. 952 LOOKUP 953 }; 954 955 956 // ES6 Draft Rev3 10.2 specifies declarative environment records with mutable 957 // and immutable bindings that can be in two states: initialized and 958 // uninitialized. In ES5 only immutable bindings have these two states. When 959 // accessing a binding, it needs to be checked for initialization. However in 960 // the following cases the binding is initialized immediately after creation 961 // so the initialization check can always be skipped: 962 // 1. Var declared local variables. 963 // var foo; 964 // 2. A local variable introduced by a function declaration. 965 // function foo() {} 966 // 3. Parameters 967 // function x(foo) {} 968 // 4. Catch bound variables. 969 // try {} catch (foo) {} 970 // 6. Function variables of named function expressions. 971 // var x = function foo() {} 972 // 7. Implicit binding of 'this'. 973 // 8. Implicit binding of 'arguments' in functions. 974 // 975 // ES5 specified object environment records which are introduced by ES elements 976 // such as Program and WithStatement that associate identifier bindings with the 977 // properties of some object. In the specification only mutable bindings exist 978 // (which may be non-writable) and have no distinct initialization step. However 979 // V8 allows const declarations in global code with distinct creation and 980 // initialization steps which are represented by non-writable properties in the 981 // global object. As a result also these bindings need to be checked for 982 // initialization. 983 // 984 // The following enum specifies a flag that indicates if the binding needs a 985 // distinct initialization step (kNeedsInitialization) or if the binding is 986 // immediately initialized upon creation (kCreatedInitialized). 987 enum InitializationFlag { 988 kNeedsInitialization, 989 kCreatedInitialized 990 }; 991 992 993 enum MaybeAssignedFlag { kNotAssigned, kMaybeAssigned }; 994 995 996 // Serialized in PreparseData, so numeric values should not be changed. 997 enum ParseErrorType { kSyntaxError = 0, kReferenceError = 1 }; 998 999 1000 enum MinusZeroMode { 1001 TREAT_MINUS_ZERO_AS_ZERO, 1002 FAIL_ON_MINUS_ZERO 1003 }; 1004 1005 1006 enum Signedness { kSigned, kUnsigned }; 1007 1008 enum FunctionKind { 1009 kNormalFunction = 0, 1010 kArrowFunction = 1 << 0, 1011 kGeneratorFunction = 1 << 1, 1012 kConciseMethod = 1 << 2, 1013 kConciseGeneratorMethod = kGeneratorFunction | kConciseMethod, 1014 kDefaultConstructor = 1 << 3, 1015 kSubclassConstructor = 1 << 4, 1016 kBaseConstructor = 1 << 5, 1017 kGetterFunction = 1 << 6, 1018 kSetterFunction = 1 << 7, 1019 kAsyncFunction = 1 << 8, 1020 kAccessorFunction = kGetterFunction | kSetterFunction, 1021 kDefaultBaseConstructor = kDefaultConstructor | kBaseConstructor, 1022 kDefaultSubclassConstructor = kDefaultConstructor | kSubclassConstructor, 1023 kClassConstructor = 1024 kBaseConstructor | kSubclassConstructor | kDefaultConstructor, 1025 kAsyncArrowFunction = kArrowFunction | kAsyncFunction, 1026 kAsyncConciseMethod = kAsyncFunction | kConciseMethod 1027 }; 1028 1029 inline bool IsValidFunctionKind(FunctionKind kind) { 1030 return kind == FunctionKind::kNormalFunction || 1031 kind == FunctionKind::kArrowFunction || 1032 kind == FunctionKind::kGeneratorFunction || 1033 kind == FunctionKind::kConciseMethod || 1034 kind == FunctionKind::kConciseGeneratorMethod || 1035 kind == FunctionKind::kGetterFunction || 1036 kind == FunctionKind::kSetterFunction || 1037 kind == FunctionKind::kAccessorFunction || 1038 kind == FunctionKind::kDefaultBaseConstructor || 1039 kind == FunctionKind::kDefaultSubclassConstructor || 1040 kind == FunctionKind::kBaseConstructor || 1041 kind == FunctionKind::kSubclassConstructor || 1042 kind == FunctionKind::kAsyncFunction || 1043 kind == FunctionKind::kAsyncArrowFunction || 1044 kind == FunctionKind::kAsyncConciseMethod; 1045 } 1046 1047 1048 inline bool IsArrowFunction(FunctionKind kind) { 1049 DCHECK(IsValidFunctionKind(kind)); 1050 return kind & FunctionKind::kArrowFunction; 1051 } 1052 1053 1054 inline bool IsGeneratorFunction(FunctionKind kind) { 1055 DCHECK(IsValidFunctionKind(kind)); 1056 return kind & FunctionKind::kGeneratorFunction; 1057 } 1058 1059 inline bool IsAsyncFunction(FunctionKind kind) { 1060 DCHECK(IsValidFunctionKind(kind)); 1061 return kind & FunctionKind::kAsyncFunction; 1062 } 1063 1064 inline bool IsResumableFunction(FunctionKind kind) { 1065 return IsGeneratorFunction(kind) || IsAsyncFunction(kind); 1066 } 1067 1068 inline bool IsConciseMethod(FunctionKind kind) { 1069 DCHECK(IsValidFunctionKind(kind)); 1070 return kind & FunctionKind::kConciseMethod; 1071 } 1072 1073 inline bool IsGetterFunction(FunctionKind kind) { 1074 DCHECK(IsValidFunctionKind(kind)); 1075 return kind & FunctionKind::kGetterFunction; 1076 } 1077 1078 inline bool IsSetterFunction(FunctionKind kind) { 1079 DCHECK(IsValidFunctionKind(kind)); 1080 return kind & FunctionKind::kSetterFunction; 1081 } 1082 1083 inline bool IsAccessorFunction(FunctionKind kind) { 1084 DCHECK(IsValidFunctionKind(kind)); 1085 return kind & FunctionKind::kAccessorFunction; 1086 } 1087 1088 1089 inline bool IsDefaultConstructor(FunctionKind kind) { 1090 DCHECK(IsValidFunctionKind(kind)); 1091 return kind & FunctionKind::kDefaultConstructor; 1092 } 1093 1094 1095 inline bool IsBaseConstructor(FunctionKind kind) { 1096 DCHECK(IsValidFunctionKind(kind)); 1097 return kind & FunctionKind::kBaseConstructor; 1098 } 1099 1100 1101 inline bool IsSubclassConstructor(FunctionKind kind) { 1102 DCHECK(IsValidFunctionKind(kind)); 1103 return kind & FunctionKind::kSubclassConstructor; 1104 } 1105 1106 1107 inline bool IsClassConstructor(FunctionKind kind) { 1108 DCHECK(IsValidFunctionKind(kind)); 1109 return kind & FunctionKind::kClassConstructor; 1110 } 1111 1112 1113 inline bool IsConstructable(FunctionKind kind, LanguageMode mode) { 1114 if (IsAccessorFunction(kind)) return false; 1115 if (IsConciseMethod(kind)) return false; 1116 if (IsArrowFunction(kind)) return false; 1117 if (IsGeneratorFunction(kind)) return false; 1118 if (IsAsyncFunction(kind)) return false; 1119 return true; 1120 } 1121 1122 1123 inline uint32_t ObjectHash(Address address) { 1124 // All objects are at least pointer aligned, so we can remove the trailing 1125 // zeros. 1126 return static_cast<uint32_t>(bit_cast<uintptr_t>(address) >> 1127 kPointerSizeLog2); 1128 } 1129 1130 } // namespace internal 1131 } // namespace v8 1132 1133 namespace i = v8::internal; 1134 1135 #endif // V8_GLOBALS_H_ 1136