LCOV - code coverage report
Current view: top level - src - globals.h (source / functions) Hit Total Coverage
Test: app.info Lines: 26 94 27.7 %
Date: 2019-04-17 Functions: 3 10 30.0 %

          Line data    Source code
       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 <limits>
      12             : #include <ostream>
      13             : 
      14             : #include "include/v8-internal.h"
      15             : #include "src/base/atomic-utils.h"
      16             : #include "src/base/build_config.h"
      17             : #include "src/base/flags.h"
      18             : #include "src/base/logging.h"
      19             : #include "src/base/macros.h"
      20             : 
      21             : #define V8_INFINITY std::numeric_limits<double>::infinity()
      22             : 
      23             : namespace v8 {
      24             : 
      25             : namespace base {
      26             : class Mutex;
      27             : class RecursiveMutex;
      28             : }
      29             : 
      30             : namespace internal {
      31             : 
      32             : // Determine whether we are running in a simulated environment.
      33             : // Setting USE_SIMULATOR explicitly from the build script will force
      34             : // the use of a simulated environment.
      35             : #if !defined(USE_SIMULATOR)
      36             : #if (V8_TARGET_ARCH_ARM64 && !V8_HOST_ARCH_ARM64)
      37             : #define USE_SIMULATOR 1
      38             : #endif
      39             : #if (V8_TARGET_ARCH_ARM && !V8_HOST_ARCH_ARM)
      40             : #define USE_SIMULATOR 1
      41             : #endif
      42             : #if (V8_TARGET_ARCH_PPC && !V8_HOST_ARCH_PPC)
      43             : #define USE_SIMULATOR 1
      44             : #endif
      45             : #if (V8_TARGET_ARCH_MIPS && !V8_HOST_ARCH_MIPS)
      46             : #define USE_SIMULATOR 1
      47             : #endif
      48             : #if (V8_TARGET_ARCH_MIPS64 && !V8_HOST_ARCH_MIPS64)
      49             : #define USE_SIMULATOR 1
      50             : #endif
      51             : #if (V8_TARGET_ARCH_S390 && !V8_HOST_ARCH_S390)
      52             : #define USE_SIMULATOR 1
      53             : #endif
      54             : #endif
      55             : 
      56             : // Determine whether the architecture uses an embedded constant pool
      57             : // (contiguous constant pool embedded in code object).
      58             : #if V8_TARGET_ARCH_PPC
      59             : #define V8_EMBEDDED_CONSTANT_POOL true
      60             : #else
      61             : #define V8_EMBEDDED_CONSTANT_POOL false
      62             : #endif
      63             : 
      64             : #ifdef V8_TARGET_ARCH_ARM
      65             : // Set stack limit lower for ARM than for other architectures because
      66             : // stack allocating MacroAssembler takes 120K bytes.
      67             : // See issue crbug.com/405338
      68             : #define V8_DEFAULT_STACK_SIZE_KB 864
      69             : #else
      70             : // Slightly less than 1MB, since Windows' default stack size for
      71             : // the main execution thread is 1MB for both 32 and 64-bit.
      72             : #define V8_DEFAULT_STACK_SIZE_KB 984
      73             : #endif
      74             : 
      75             : // Minimum stack size in KB required by compilers.
      76             : constexpr int kStackSpaceRequiredForCompilation = 40;
      77             : 
      78             : // Determine whether double field unboxing feature is enabled.
      79             : #if V8_TARGET_ARCH_64_BIT && !defined(V8_COMPRESS_POINTERS)
      80             : #define V8_DOUBLE_FIELDS_UNBOXING true
      81             : #else
      82             : #define V8_DOUBLE_FIELDS_UNBOXING false
      83             : #endif
      84             : 
      85             : // Some types of tracing require the SFI to store a unique ID.
      86             : #if defined(V8_TRACE_MAPS) || defined(V8_TRACE_IGNITION)
      87             : #define V8_SFI_HAS_UNIQUE_ID true
      88             : #endif
      89             : 
      90             : #if defined(V8_OS_WIN) && defined(V8_TARGET_ARCH_X64)
      91             : #define V8_OS_WIN_X64 true
      92             : #endif
      93             : 
      94             : // Superclass for classes only using static method functions.
      95             : // The subclass of AllStatic cannot be instantiated at all.
      96             : class AllStatic {
      97             : #ifdef DEBUG
      98             :  public:
      99             :   AllStatic() = delete;
     100             : #endif
     101             : };
     102             : 
     103             : typedef uint8_t byte;
     104             : 
     105             : // -----------------------------------------------------------------------------
     106             : // Constants
     107             : 
     108             : constexpr int KB = 1024;
     109             : constexpr int MB = KB * KB;
     110             : constexpr int GB = KB * KB * KB;
     111             : constexpr int kMaxInt = 0x7FFFFFFF;
     112             : constexpr int kMinInt = -kMaxInt - 1;
     113             : constexpr int kMaxInt8 = (1 << 7) - 1;
     114             : constexpr int kMinInt8 = -(1 << 7);
     115             : constexpr int kMaxUInt8 = (1 << 8) - 1;
     116             : constexpr int kMinUInt8 = 0;
     117             : constexpr int kMaxInt16 = (1 << 15) - 1;
     118             : constexpr int kMinInt16 = -(1 << 15);
     119             : constexpr int kMaxUInt16 = (1 << 16) - 1;
     120             : constexpr int kMinUInt16 = 0;
     121             : 
     122             : constexpr uint32_t kMaxUInt32 = 0xFFFFFFFFu;
     123             : constexpr int kMinUInt32 = 0;
     124             : 
     125             : constexpr int kUInt8Size = sizeof(uint8_t);
     126             : constexpr int kByteSize = sizeof(byte);
     127             : constexpr int kCharSize = sizeof(char);
     128             : constexpr int kShortSize = sizeof(short);  // NOLINT
     129             : constexpr int kUInt16Size = sizeof(uint16_t);
     130             : constexpr int kIntSize = sizeof(int);
     131             : constexpr int kInt32Size = sizeof(int32_t);
     132             : constexpr int kInt64Size = sizeof(int64_t);
     133             : constexpr int kUInt32Size = sizeof(uint32_t);
     134             : constexpr int kSizetSize = sizeof(size_t);
     135             : constexpr int kFloatSize = sizeof(float);
     136             : constexpr int kDoubleSize = sizeof(double);
     137             : constexpr int kIntptrSize = sizeof(intptr_t);
     138             : constexpr int kUIntptrSize = sizeof(uintptr_t);
     139             : constexpr int kSystemPointerSize = sizeof(void*);
     140             : constexpr int kSystemPointerHexDigits = kSystemPointerSize == 4 ? 8 : 12;
     141             : constexpr int kPCOnStackSize = kSystemPointerSize;
     142             : constexpr int kFPOnStackSize = kSystemPointerSize;
     143             : 
     144             : #if V8_TARGET_ARCH_X64 || V8_TARGET_ARCH_IA32
     145             : constexpr int kElidedFrameSlots = kPCOnStackSize / kSystemPointerSize;
     146             : #else
     147             : constexpr int kElidedFrameSlots = 0;
     148             : #endif
     149             : 
     150             : constexpr int kDoubleSizeLog2 = 3;
     151             : #if V8_TARGET_ARCH_ARM64
     152             : // ARM64 only supports direct calls within a 128 MB range.
     153             : constexpr size_t kMaxWasmCodeMB = 128;
     154             : #else
     155             : constexpr size_t kMaxWasmCodeMB = 1024;
     156             : #endif
     157             : constexpr size_t kMaxWasmCodeMemory = kMaxWasmCodeMB * MB;
     158             : 
     159             : #if V8_HOST_ARCH_64_BIT
     160             : constexpr int kSystemPointerSizeLog2 = 3;
     161             : constexpr intptr_t kIntptrSignBit =
     162             :     static_cast<intptr_t>(uintptr_t{0x8000000000000000});
     163             : constexpr uintptr_t kUintptrAllBitsSet = uintptr_t{0xFFFFFFFFFFFFFFFF};
     164             : constexpr bool kRequiresCodeRange = true;
     165             : #if V8_HOST_ARCH_PPC && V8_TARGET_ARCH_PPC && V8_OS_LINUX
     166             : constexpr size_t kMaximalCodeRangeSize = 512 * MB;
     167             : constexpr size_t kMinExpectedOSPageSize = 64 * KB;  // OS page on PPC Linux
     168             : #elif V8_TARGET_ARCH_ARM64
     169             : constexpr size_t kMaximalCodeRangeSize = 128 * MB;
     170             : constexpr size_t kMinExpectedOSPageSize = 4 * KB;  // OS page.
     171             : #else
     172             : constexpr size_t kMaximalCodeRangeSize = 128 * MB;
     173             : constexpr size_t kMinExpectedOSPageSize = 4 * KB;  // OS page.
     174             : #endif
     175             : #if V8_OS_WIN
     176             : constexpr size_t kMinimumCodeRangeSize = 4 * MB;
     177             : constexpr size_t kReservedCodeRangePages = 1;
     178             : #else
     179             : constexpr size_t kMinimumCodeRangeSize = 3 * MB;
     180             : constexpr size_t kReservedCodeRangePages = 0;
     181             : #endif
     182             : #else
     183             : constexpr int kSystemPointerSizeLog2 = 2;
     184             : constexpr intptr_t kIntptrSignBit = 0x80000000;
     185             : constexpr uintptr_t kUintptrAllBitsSet = 0xFFFFFFFFu;
     186             : #if V8_HOST_ARCH_PPC && V8_TARGET_ARCH_PPC && V8_OS_LINUX
     187             : constexpr bool kRequiresCodeRange = false;
     188             : constexpr size_t kMaximalCodeRangeSize = 0 * MB;
     189             : constexpr size_t kMinimumCodeRangeSize = 0 * MB;
     190             : constexpr size_t kMinExpectedOSPageSize = 64 * KB;  // OS page on PPC Linux
     191             : #elif V8_TARGET_ARCH_MIPS
     192             : constexpr bool kRequiresCodeRange = false;
     193             : constexpr size_t kMaximalCodeRangeSize = 2048LL * MB;
     194             : constexpr size_t kMinimumCodeRangeSize = 0 * MB;
     195             : constexpr size_t kMinExpectedOSPageSize = 4 * KB;  // OS page.
     196             : #else
     197             : constexpr bool kRequiresCodeRange = false;
     198             : constexpr size_t kMaximalCodeRangeSize = 0 * MB;
     199             : constexpr size_t kMinimumCodeRangeSize = 0 * MB;
     200             : constexpr size_t kMinExpectedOSPageSize = 4 * KB;  // OS page.
     201             : #endif
     202             : constexpr size_t kReservedCodeRangePages = 0;
     203             : #endif
     204             : 
     205             : STATIC_ASSERT(kSystemPointerSize == (1 << kSystemPointerSizeLog2));
     206             : 
     207             : #ifdef V8_COMPRESS_POINTERS
     208             : static_assert(
     209             :     kSystemPointerSize == kInt64Size,
     210             :     "Pointer compression can be enabled only for 64-bit architectures");
     211             : 
     212             : constexpr int kTaggedSize = kInt32Size;
     213             : constexpr int kTaggedSizeLog2 = 2;
     214             : 
     215             : // These types define raw and atomic storage types for tagged values stored
     216             : // on V8 heap.
     217             : using Tagged_t = int32_t;
     218             : using AtomicTagged_t = base::Atomic32;
     219             : 
     220             : #else
     221             : 
     222             : constexpr int kTaggedSize = kSystemPointerSize;
     223             : constexpr int kTaggedSizeLog2 = kSystemPointerSizeLog2;
     224             : 
     225             : // These types define raw and atomic storage types for tagged values stored
     226             : // on V8 heap.
     227             : using Tagged_t = Address;
     228             : using AtomicTagged_t = base::AtomicWord;
     229             : 
     230             : #endif  // V8_COMPRESS_POINTERS
     231             : 
     232             : // Defines whether the branchless or branchful implementation of pointer
     233             : // decompression should be used.
     234             : constexpr bool kUseBranchlessPtrDecompression = true;
     235             : 
     236             : STATIC_ASSERT(kTaggedSize == (1 << kTaggedSizeLog2));
     237             : 
     238             : using AsAtomicTagged = base::AsAtomicPointerImpl<AtomicTagged_t>;
     239             : STATIC_ASSERT(sizeof(Tagged_t) == kTaggedSize);
     240             : STATIC_ASSERT(sizeof(AtomicTagged_t) == kTaggedSize);
     241             : 
     242             : STATIC_ASSERT(kTaggedSize == kApiTaggedSize);
     243             : 
     244             : // TODO(ishell): use kTaggedSize or kSystemPointerSize instead.
     245             : #ifndef V8_COMPRESS_POINTERS
     246             : constexpr int kPointerSize = kSystemPointerSize;
     247             : constexpr int kPointerSizeLog2 = kSystemPointerSizeLog2;
     248             : STATIC_ASSERT(kPointerSize == (1 << kPointerSizeLog2));
     249             : #endif
     250             : 
     251             : constexpr int kEmbedderDataSlotSize = kSystemPointerSize;
     252             : 
     253             : constexpr int kEmbedderDataSlotSizeInTaggedSlots =
     254             :     kEmbedderDataSlotSize / kTaggedSize;
     255             : STATIC_ASSERT(kEmbedderDataSlotSize >= kSystemPointerSize);
     256             : 
     257             : constexpr int kExternalAllocationSoftLimit =
     258             :     internal::Internals::kExternalAllocationSoftLimit;
     259             : 
     260             : // Maximum object size that gets allocated into regular pages. Objects larger
     261             : // than that size are allocated in large object space and are never moved in
     262             : // memory. This also applies to new space allocation, since objects are never
     263             : // migrated from new space to large object space. Takes double alignment into
     264             : // account.
     265             : //
     266             : // Current value: half of the page size.
     267             : constexpr int kMaxRegularHeapObjectSize = (1 << (kPageSizeBits - 1));
     268             : 
     269             : constexpr int kBitsPerByte = 8;
     270             : constexpr int kBitsPerByteLog2 = 3;
     271             : constexpr int kBitsPerSystemPointer = kSystemPointerSize * kBitsPerByte;
     272             : constexpr int kBitsPerInt = kIntSize * kBitsPerByte;
     273             : 
     274             : // IEEE 754 single precision floating point number bit layout.
     275             : constexpr uint32_t kBinary32SignMask = 0x80000000u;
     276             : constexpr uint32_t kBinary32ExponentMask = 0x7f800000u;
     277             : constexpr uint32_t kBinary32MantissaMask = 0x007fffffu;
     278             : constexpr int kBinary32ExponentBias = 127;
     279             : constexpr int kBinary32MaxExponent = 0xFE;
     280             : constexpr int kBinary32MinExponent = 0x01;
     281             : constexpr int kBinary32MantissaBits = 23;
     282             : constexpr int kBinary32ExponentShift = 23;
     283             : 
     284             : // Quiet NaNs have bits 51 to 62 set, possibly the sign bit, and no
     285             : // other bits set.
     286             : constexpr uint64_t kQuietNaNMask = static_cast<uint64_t>(0xfff) << 51;
     287             : 
     288             : // Latin1/UTF-16 constants
     289             : // Code-point values in Unicode 4.0 are 21 bits wide.
     290             : // Code units in UTF-16 are 16 bits wide.
     291             : typedef uint16_t uc16;
     292             : typedef int32_t uc32;
     293             : constexpr int kOneByteSize = kCharSize;
     294             : constexpr int kUC16Size = sizeof(uc16);  // NOLINT
     295             : 
     296             : // 128 bit SIMD value size.
     297             : constexpr int kSimd128Size = 16;
     298             : 
     299             : // FUNCTION_ADDR(f) gets the address of a C function f.
     300             : #define FUNCTION_ADDR(f) (reinterpret_cast<v8::internal::Address>(f))
     301             : 
     302             : // FUNCTION_CAST<F>(addr) casts an address into a function
     303             : // of type F. Used to invoke generated code from within C.
     304             : template <typename F>
     305             : F FUNCTION_CAST(byte* addr) {
     306             :   return reinterpret_cast<F>(reinterpret_cast<Address>(addr));
     307             : }
     308             : 
     309             : template <typename F>
     310             : F FUNCTION_CAST(Address addr) {
     311        7378 :   return reinterpret_cast<F>(addr);
     312             : }
     313             : 
     314             : 
     315             : // Determine whether the architecture uses function descriptors
     316             : // which provide a level of indirection between the function pointer
     317             : // and the function entrypoint.
     318             : #if V8_HOST_ARCH_PPC && \
     319             :     (V8_OS_AIX || (V8_TARGET_ARCH_PPC64 && V8_TARGET_BIG_ENDIAN && \
     320             :     (!defined(_CALL_ELF) || _CALL_ELF == 1)))
     321             : #define USES_FUNCTION_DESCRIPTORS 1
     322             : #define FUNCTION_ENTRYPOINT_ADDRESS(f)       \
     323             :   (reinterpret_cast<v8::internal::Address*>( \
     324             :       &(reinterpret_cast<intptr_t*>(f)[0])))
     325             : #else
     326             : #define USES_FUNCTION_DESCRIPTORS 0
     327             : #endif
     328             : 
     329             : 
     330             : // -----------------------------------------------------------------------------
     331             : // Declarations for use in both the preparser and the rest of V8.
     332             : 
     333             : // The Strict Mode (ECMA-262 5th edition, 4.2.2).
     334             : 
     335             : enum class LanguageMode : bool { kSloppy, kStrict };
     336             : static const size_t LanguageModeSize = 2;
     337             : 
     338             : inline size_t hash_value(LanguageMode mode) {
     339           0 :   return static_cast<size_t>(mode);
     340             : }
     341             : 
     342             : inline const char* LanguageMode2String(LanguageMode mode) {
     343           0 :   switch (mode) {
     344             :     case LanguageMode::kSloppy:
     345             :       return "sloppy";
     346             :     case LanguageMode::kStrict:
     347             :       return "strict";
     348             :   }
     349             :   UNREACHABLE();
     350             : }
     351             : 
     352             : inline std::ostream& operator<<(std::ostream& os, LanguageMode mode) {
     353           0 :   return os << LanguageMode2String(mode);
     354             : }
     355             : 
     356             : inline bool is_sloppy(LanguageMode language_mode) {
     357    26473553 :   return language_mode == LanguageMode::kSloppy;
     358             : }
     359             : 
     360             : inline bool is_strict(LanguageMode language_mode) {
     361             :   return language_mode != LanguageMode::kSloppy;
     362             : }
     363             : 
     364             : inline bool is_valid_language_mode(int language_mode) {
     365             :   return language_mode == static_cast<int>(LanguageMode::kSloppy) ||
     366             :          language_mode == static_cast<int>(LanguageMode::kStrict);
     367             : }
     368             : 
     369             : inline LanguageMode construct_language_mode(bool strict_bit) {
     370             :   return static_cast<LanguageMode>(strict_bit);
     371             : }
     372             : 
     373             : // Return kStrict if either of the language modes is kStrict, or kSloppy
     374             : // otherwise.
     375             : inline LanguageMode stricter_language_mode(LanguageMode mode1,
     376             :                                            LanguageMode mode2) {
     377             :   STATIC_ASSERT(LanguageModeSize == 2);
     378             :   return static_cast<LanguageMode>(static_cast<int>(mode1) |
     379      170512 :                                    static_cast<int>(mode2));
     380             : }
     381             : 
     382             : // A non-keyed store is of the form a.x = foo or a["x"] = foo whereas
     383             : // a keyed store is of the form a[expression] = foo.
     384             : enum class StoreOrigin { kMaybeKeyed, kNamed };
     385             : 
     386             : enum TypeofMode : int { INSIDE_TYPEOF, NOT_INSIDE_TYPEOF };
     387             : 
     388             : // Enums used by CEntry.
     389             : enum SaveFPRegsMode { kDontSaveFPRegs, kSaveFPRegs };
     390             : enum ArgvMode { kArgvOnStack, kArgvInRegister };
     391             : 
     392             : // This constant is used as an undefined value when passing source positions.
     393             : constexpr int kNoSourcePosition = -1;
     394             : 
     395             : // This constant is used to indicate missing deoptimization information.
     396             : constexpr int kNoDeoptimizationId = -1;
     397             : 
     398             : // Deoptimize bailout kind:
     399             : // - Eager: a check failed in the optimized code and deoptimization happens
     400             : //   immediately.
     401             : // - Lazy: the code has been marked as dependent on some assumption which
     402             : //   is checked elsewhere and can trigger deoptimization the next time the
     403             : //   code is executed.
     404             : // - Soft: similar to lazy deoptimization, but does not contribute to the
     405             : //   total deopt count which can lead to disabling optimization for a function.
     406             : enum class DeoptimizeKind : uint8_t {
     407             :   kEager,
     408             :   kSoft,
     409             :   kLazy,
     410             :   kLastDeoptimizeKind = kLazy
     411             : };
     412             : inline size_t hash_value(DeoptimizeKind kind) {
     413           0 :   return static_cast<size_t>(kind);
     414             : }
     415          72 : inline std::ostream& operator<<(std::ostream& os, DeoptimizeKind kind) {
     416          72 :   switch (kind) {
     417             :     case DeoptimizeKind::kEager:
     418          72 :       return os << "Eager";
     419             :     case DeoptimizeKind::kSoft:
     420           0 :       return os << "Soft";
     421             :     case DeoptimizeKind::kLazy:
     422           0 :       return os << "Lazy";
     423             :   }
     424           0 :   UNREACHABLE();
     425             : }
     426             : 
     427             : enum class IsolateAllocationMode {
     428             :   // Allocate Isolate in C++ heap using default new/delete operators.
     429             :   kInCppHeap,
     430             : 
     431             :   // Allocate Isolate in a committed region inside V8 heap reservation.
     432             :   kInV8Heap,
     433             : 
     434             : #ifdef V8_COMPRESS_POINTERS
     435             :   kDefault = kInV8Heap,
     436             : #else
     437             :   kDefault = kInCppHeap,
     438             : #endif
     439             : };
     440             : 
     441             : // Indicates whether the lookup is related to sloppy-mode block-scoped
     442             : // function hoisting, and is a synthetic assignment for that.
     443             : enum class LookupHoistingMode { kNormal, kLegacySloppy };
     444             : 
     445             : inline std::ostream& operator<<(std::ostream& os,
     446             :                                 const LookupHoistingMode& mode) {
     447             :   switch (mode) {
     448             :     case LookupHoistingMode::kNormal:
     449             :       return os << "normal hoisting";
     450             :     case LookupHoistingMode::kLegacySloppy:
     451             :       return os << "legacy sloppy hoisting";
     452             :   }
     453             :   UNREACHABLE();
     454             : }
     455             : 
     456             : static_assert(kSmiValueSize <= 32, "Unsupported Smi tagging scheme");
     457             : // Smi sign bit position must be 32-bit aligned so we can use sign extension
     458             : // instructions on 64-bit architectures without additional shifts.
     459             : static_assert((kSmiValueSize + kSmiShiftSize + kSmiTagSize) % 32 == 0,
     460             :               "Unsupported Smi tagging scheme");
     461             : 
     462             : constexpr bool kIsSmiValueInUpper32Bits =
     463             :     (kSmiValueSize + kSmiShiftSize + kSmiTagSize) == 64;
     464             : constexpr bool kIsSmiValueInLower32Bits =
     465             :     (kSmiValueSize + kSmiShiftSize + kSmiTagSize) == 32;
     466             : static_assert(!SmiValuesAre32Bits() == SmiValuesAre31Bits(),
     467             :               "Unsupported Smi tagging scheme");
     468             : static_assert(SmiValuesAre32Bits() == kIsSmiValueInUpper32Bits,
     469             :               "Unsupported Smi tagging scheme");
     470             : static_assert(SmiValuesAre31Bits() == kIsSmiValueInLower32Bits,
     471             :               "Unsupported Smi tagging scheme");
     472             : 
     473             : // Mask for the sign bit in a smi.
     474             : constexpr intptr_t kSmiSignMask = static_cast<intptr_t>(
     475             :     uintptr_t{1} << (kSmiValueSize + kSmiShiftSize + kSmiTagSize - 1));
     476             : 
     477             : // Desired alignment for tagged pointers.
     478             : constexpr int kObjectAlignmentBits = kTaggedSizeLog2;
     479             : constexpr intptr_t kObjectAlignment = 1 << kObjectAlignmentBits;
     480             : constexpr intptr_t kObjectAlignmentMask = kObjectAlignment - 1;
     481             : 
     482             : // Desired alignment for system pointers.
     483             : constexpr intptr_t kPointerAlignment = (1 << kSystemPointerSizeLog2);
     484             : constexpr intptr_t kPointerAlignmentMask = kPointerAlignment - 1;
     485             : 
     486             : // Desired alignment for double values.
     487             : constexpr intptr_t kDoubleAlignment = 8;
     488             : constexpr intptr_t kDoubleAlignmentMask = kDoubleAlignment - 1;
     489             : 
     490             : // Desired alignment for generated code is 32 bytes (to improve cache line
     491             : // utilization).
     492             : constexpr int kCodeAlignmentBits = 5;
     493             : constexpr intptr_t kCodeAlignment = 1 << kCodeAlignmentBits;
     494             : constexpr intptr_t kCodeAlignmentMask = kCodeAlignment - 1;
     495             : 
     496             : const Address kWeakHeapObjectMask = 1 << 1;
     497             : 
     498             : // The lower 32 bits of the cleared weak reference value is always equal to
     499             : // the |kClearedWeakHeapObjectLower32| constant but on 64-bit architectures
     500             : // the value of the upper 32 bits part may be
     501             : // 1) zero when pointer compression is disabled,
     502             : // 2) upper 32 bits of the isolate root value when pointer compression is
     503             : //    enabled.
     504             : // This is necessary to make pointer decompression computation also suitable
     505             : // for cleared weak reference.
     506             : // Note, that real heap objects can't have lower 32 bits equal to 3 because
     507             : // this offset belongs to page header. So, in either case it's enough to
     508             : // compare only the lower 32 bits of a MaybeObject value in order to figure
     509             : // out if it's a cleared reference or not.
     510             : const uint32_t kClearedWeakHeapObjectLower32 = 3;
     511             : 
     512             : // Zap-value: The value used for zapping dead objects.
     513             : // Should be a recognizable hex value tagged as a failure.
     514             : #ifdef V8_HOST_ARCH_64_BIT
     515             : constexpr uint64_t kClearedFreeMemoryValue = 0;
     516             : constexpr uint64_t kZapValue = uint64_t{0xdeadbeedbeadbeef};
     517             : constexpr uint64_t kHandleZapValue = uint64_t{0x1baddead0baddeaf};
     518             : constexpr uint64_t kGlobalHandleZapValue = uint64_t{0x1baffed00baffedf};
     519             : constexpr uint64_t kFromSpaceZapValue = uint64_t{0x1beefdad0beefdaf};
     520             : constexpr uint64_t kDebugZapValue = uint64_t{0xbadbaddbbadbaddb};
     521             : constexpr uint64_t kSlotsZapValue = uint64_t{0xbeefdeadbeefdeef};
     522             : constexpr uint64_t kFreeListZapValue = 0xfeed1eaffeed1eaf;
     523             : #else
     524             : constexpr uint32_t kClearedFreeMemoryValue = 0;
     525             : constexpr uint32_t kZapValue = 0xdeadbeef;
     526             : constexpr uint32_t kHandleZapValue = 0xbaddeaf;
     527             : constexpr uint32_t kGlobalHandleZapValue = 0xbaffedf;
     528             : constexpr uint32_t kFromSpaceZapValue = 0xbeefdaf;
     529             : constexpr uint32_t kSlotsZapValue = 0xbeefdeef;
     530             : constexpr uint32_t kDebugZapValue = 0xbadbaddb;
     531             : constexpr uint32_t kFreeListZapValue = 0xfeed1eaf;
     532             : #endif
     533             : 
     534             : constexpr int kCodeZapValue = 0xbadc0de;
     535             : constexpr uint32_t kPhantomReferenceZap = 0xca11bac;
     536             : 
     537             : // Page constants.
     538             : static const intptr_t kPageAlignmentMask = (intptr_t{1} << kPageSizeBits) - 1;
     539             : 
     540             : // On Intel architecture, cache line size is 64 bytes.
     541             : // On ARM it may be less (32 bytes), but as far this constant is
     542             : // used for aligning data, it doesn't hurt to align on a greater value.
     543             : #define PROCESSOR_CACHE_LINE_SIZE 64
     544             : 
     545             : // Constants relevant to double precision floating point numbers.
     546             : // If looking only at the top 32 bits, the QNaN mask is bits 19 to 30.
     547             : constexpr uint32_t kQuietNaNHighBitsMask = 0xfff << (51 - 32);
     548             : 
     549             : // -----------------------------------------------------------------------------
     550             : // Forward declarations for frequently used classes
     551             : 
     552             : class AccessorInfo;
     553             : class Arguments;
     554             : class Assembler;
     555             : class ClassScope;
     556             : class Code;
     557             : class CodeSpace;
     558             : class Context;
     559             : class DeclarationScope;
     560             : class Debug;
     561             : class DebugInfo;
     562             : class Descriptor;
     563             : class DescriptorArray;
     564             : class TransitionArray;
     565             : class ExternalReference;
     566             : class FeedbackVector;
     567             : class FixedArray;
     568             : class Foreign;
     569             : class FreeStoreAllocationPolicy;
     570             : class FunctionTemplateInfo;
     571             : class GlobalDictionary;
     572             : template <typename T> class Handle;
     573             : class Heap;
     574             : class HeapObject;
     575             : class HeapObjectReference;
     576             : class IC;
     577             : class InterceptorInfo;
     578             : class Isolate;
     579             : class JSReceiver;
     580             : class JSArray;
     581             : class JSFunction;
     582             : class JSObject;
     583             : class LargeObjectSpace;
     584             : class MacroAssembler;
     585             : class Map;
     586             : class MapSpace;
     587             : class MarkCompactCollector;
     588             : template <typename T>
     589             : class MaybeHandle;
     590             : class MaybeObject;
     591             : class MemoryChunk;
     592             : class MessageLocation;
     593             : class ModuleScope;
     594             : class Name;
     595             : class NameDictionary;
     596             : class NativeContext;
     597             : class NewSpace;
     598             : class NewLargeObjectSpace;
     599             : class NumberDictionary;
     600             : class Object;
     601             : class CompressedObjectSlot;
     602             : class CompressedMaybeObjectSlot;
     603             : class CompressedMapWordSlot;
     604             : class CompressedHeapObjectSlot;
     605             : class FullObjectSlot;
     606             : class FullMaybeObjectSlot;
     607             : class FullHeapObjectSlot;
     608             : class OldSpace;
     609             : class ParameterCount;
     610             : class ReadOnlySpace;
     611             : class RelocInfo;
     612             : class Scope;
     613             : class ScopeInfo;
     614             : class Script;
     615             : class SimpleNumberDictionary;
     616             : class Smi;
     617             : template <typename Config, class Allocator = FreeStoreAllocationPolicy>
     618             : class SplayTree;
     619             : class String;
     620             : class Struct;
     621             : class Symbol;
     622             : class Variable;
     623             : 
     624             : enum class SlotLocation { kOnHeap, kOffHeap };
     625             : 
     626             : template <SlotLocation slot_location>
     627             : struct SlotTraits;
     628             : 
     629             : // Off-heap slots are always full-pointer slots.
     630             : template <>
     631             : struct SlotTraits<SlotLocation::kOffHeap> {
     632             :   using TObjectSlot = FullObjectSlot;
     633             :   using TMapWordSlot = FullObjectSlot;
     634             :   using TMaybeObjectSlot = FullMaybeObjectSlot;
     635             :   using THeapObjectSlot = FullHeapObjectSlot;
     636             : };
     637             : 
     638             : // On-heap slots are either full-pointer slots or compressed slots depending
     639             : // on whether the pointer compression is enabled or not.
     640             : template <>
     641             : struct SlotTraits<SlotLocation::kOnHeap> {
     642             : #ifdef V8_COMPRESS_POINTERS
     643             :   using TObjectSlot = CompressedObjectSlot;
     644             :   using TMapWordSlot = CompressedMapWordSlot;
     645             :   using TMaybeObjectSlot = CompressedMaybeObjectSlot;
     646             :   using THeapObjectSlot = CompressedHeapObjectSlot;
     647             : #else
     648             :   using TObjectSlot = FullObjectSlot;
     649             :   using TMapWordSlot = FullObjectSlot;
     650             :   using TMaybeObjectSlot = FullMaybeObjectSlot;
     651             :   using THeapObjectSlot = FullHeapObjectSlot;
     652             : #endif
     653             : };
     654             : 
     655             : // An ObjectSlot instance describes a kTaggedSize-sized on-heap field ("slot")
     656             : // holding Object value (smi or strong heap object).
     657             : using ObjectSlot = SlotTraits<SlotLocation::kOnHeap>::TObjectSlot;
     658             : 
     659             : // An MapWordSlot instance describes a kTaggedSize-sized on-heap field ("slot")
     660             : // holding HeapObject (strong heap object) value or a forwarding pointer.
     661             : using MapWordSlot = SlotTraits<SlotLocation::kOnHeap>::TMapWordSlot;
     662             : 
     663             : // A MaybeObjectSlot instance describes a kTaggedSize-sized on-heap field
     664             : // ("slot") holding MaybeObject (smi or weak heap object or strong heap object).
     665             : using MaybeObjectSlot = SlotTraits<SlotLocation::kOnHeap>::TMaybeObjectSlot;
     666             : 
     667             : // A HeapObjectSlot instance describes a kTaggedSize-sized field ("slot")
     668             : // holding a weak or strong pointer to a heap object (think:
     669             : // HeapObjectReference).
     670             : using HeapObjectSlot = SlotTraits<SlotLocation::kOnHeap>::THeapObjectSlot;
     671             : 
     672             : typedef bool (*WeakSlotCallback)(FullObjectSlot pointer);
     673             : 
     674             : typedef bool (*WeakSlotCallbackWithHeap)(Heap* heap, FullObjectSlot pointer);
     675             : 
     676             : // -----------------------------------------------------------------------------
     677             : // Miscellaneous
     678             : 
     679             : // NOTE: SpaceIterator depends on AllocationSpace enumeration values being
     680             : // consecutive.
     681             : enum AllocationSpace {
     682             :   RO_SPACE,    // Immortal, immovable and immutable objects,
     683             :   NEW_SPACE,   // Young generation semispaces for regular objects collected with
     684             :                // Scavenger.
     685             :   OLD_SPACE,   // Old generation regular object space.
     686             :   CODE_SPACE,  // Old generation code object space, marked executable.
     687             :   MAP_SPACE,   // Old generation map object space, non-movable.
     688             :   LO_SPACE,    // Old generation large object space.
     689             :   CODE_LO_SPACE,  // Old generation large code object space.
     690             :   NEW_LO_SPACE,   // Young generation large object space.
     691             : 
     692             :   FIRST_SPACE = RO_SPACE,
     693             :   LAST_SPACE = NEW_LO_SPACE,
     694             :   FIRST_MUTABLE_SPACE = NEW_SPACE,
     695             :   LAST_MUTABLE_SPACE = NEW_LO_SPACE,
     696             :   FIRST_GROWABLE_PAGED_SPACE = OLD_SPACE,
     697             :   LAST_GROWABLE_PAGED_SPACE = MAP_SPACE
     698             : };
     699             : constexpr int kSpaceTagSize = 4;
     700             : STATIC_ASSERT(FIRST_SPACE == 0);
     701             : 
     702             : enum class AllocationType : uint8_t {
     703             :   kYoung,    // Regular object allocated in NEW_SPACE or NEW_LO_SPACE
     704             :   kOld,      // Regular object allocated in OLD_SPACE or LO_SPACE
     705             :   kCode,     // Code object allocated in CODE_SPACE or CODE_LO_SPACE
     706             :   kMap,      // Map object allocated in MAP_SPACE
     707             :   kReadOnly  // Object allocated in RO_SPACE
     708             : };
     709             : 
     710             : inline size_t hash_value(AllocationType kind) {
     711           0 :   return static_cast<uint8_t>(kind);
     712             : }
     713             : 
     714           0 : inline std::ostream& operator<<(std::ostream& os, AllocationType kind) {
     715           0 :   switch (kind) {
     716             :     case AllocationType::kYoung:
     717           0 :       return os << "Young";
     718             :     case AllocationType::kOld:
     719           0 :       return os << "Old";
     720             :     case AllocationType::kCode:
     721           0 :       return os << "Code";
     722             :     case AllocationType::kMap:
     723           0 :       return os << "Map";
     724             :     case AllocationType::kReadOnly:
     725           0 :       return os << "ReadOnly";
     726             :   }
     727           0 :   UNREACHABLE();
     728             : }
     729             : 
     730             : // TODO(ishell): review and rename kWordAligned to kTaggedAligned.
     731             : enum AllocationAlignment { kWordAligned, kDoubleAligned, kDoubleUnaligned };
     732             : 
     733             : enum class AccessMode { ATOMIC, NON_ATOMIC };
     734             : 
     735             : // Supported write barrier modes.
     736             : enum WriteBarrierKind : uint8_t {
     737             :   kNoWriteBarrier,
     738             :   kMapWriteBarrier,
     739             :   kPointerWriteBarrier,
     740             :   kEphemeronKeyWriteBarrier,
     741             :   kFullWriteBarrier
     742             : };
     743             : 
     744             : inline size_t hash_value(WriteBarrierKind kind) {
     745           0 :   return static_cast<uint8_t>(kind);
     746             : }
     747             : 
     748      487904 : inline std::ostream& operator<<(std::ostream& os, WriteBarrierKind kind) {
     749      487904 :   switch (kind) {
     750             :     case kNoWriteBarrier:
     751      308800 :       return os << "NoWriteBarrier";
     752             :     case kMapWriteBarrier:
     753           0 :       return os << "MapWriteBarrier";
     754             :     case kPointerWriteBarrier:
     755           0 :       return os << "PointerWriteBarrier";
     756             :     case kEphemeronKeyWriteBarrier:
     757           0 :       return os << "EphemeronKeyWriteBarrier";
     758             :     case kFullWriteBarrier:
     759      179104 :       return os << "FullWriteBarrier";
     760             :   }
     761           0 :   UNREACHABLE();
     762             : }
     763             : 
     764             : enum MinimumCapacity {
     765             :   USE_DEFAULT_MINIMUM_CAPACITY,
     766             :   USE_CUSTOM_MINIMUM_CAPACITY
     767             : };
     768             : 
     769             : enum GarbageCollector { SCAVENGER, MARK_COMPACTOR, MINOR_MARK_COMPACTOR };
     770             : 
     771             : enum Executability { NOT_EXECUTABLE, EXECUTABLE };
     772             : 
     773             : enum Movability { kMovable, kImmovable };
     774             : 
     775             : enum VisitMode {
     776             :   VISIT_ALL,
     777             :   VISIT_ALL_IN_MINOR_MC_MARK,
     778             :   VISIT_ALL_IN_MINOR_MC_UPDATE,
     779             :   VISIT_ALL_IN_SCAVENGE,
     780             :   VISIT_ALL_IN_SWEEP_NEWSPACE,
     781             :   VISIT_ONLY_STRONG,
     782             :   VISIT_FOR_SERIALIZATION,
     783             : };
     784             : 
     785             : enum class BytecodeFlushMode {
     786             :   kDoNotFlushBytecode,
     787             :   kFlushBytecode,
     788             :   kStressFlushBytecode,
     789             : };
     790             : 
     791             : // Flag indicating whether code is built into the VM (one of the natives files).
     792             : enum NativesFlag {
     793             :   NOT_NATIVES_CODE,
     794             :   EXTENSION_CODE,
     795             :   INSPECTOR_CODE
     796             : };
     797             : 
     798             : // ParseRestriction is used to restrict the set of valid statements in a
     799             : // unit of compilation.  Restriction violations cause a syntax error.
     800             : enum ParseRestriction {
     801             :   NO_PARSE_RESTRICTION,         // All expressions are allowed.
     802             :   ONLY_SINGLE_FUNCTION_LITERAL  // Only a single FunctionLiteral expression.
     803             : };
     804             : 
     805             : // State for inline cache call sites. Aliased as IC::State.
     806             : enum InlineCacheState {
     807             :   // No feedback will be collected.
     808             :   NO_FEEDBACK,
     809             :   // Has never been executed.
     810             :   UNINITIALIZED,
     811             :   // Has been executed but monomorphic state has been delayed.
     812             :   PREMONOMORPHIC,
     813             :   // Has been executed and only one receiver type has been seen.
     814             :   MONOMORPHIC,
     815             :   // Check failed due to prototype (or map deprecation).
     816             :   RECOMPUTE_HANDLER,
     817             :   // Multiple receiver types have been seen.
     818             :   POLYMORPHIC,
     819             :   // Many receiver types have been seen.
     820             :   MEGAMORPHIC,
     821             :   // A generic handler is installed and no extra typefeedback is recorded.
     822             :   GENERIC,
     823             : };
     824             : 
     825             : // Printing support.
     826         304 : inline const char* InlineCacheState2String(InlineCacheState state) {
     827         304 :   switch (state) {
     828             :     case NO_FEEDBACK:
     829             :       return "NOFEEDBACK";
     830             :     case UNINITIALIZED:
     831         304 :       return "UNINITIALIZED";
     832             :     case PREMONOMORPHIC:
     833           0 :       return "PREMONOMORPHIC";
     834             :     case MONOMORPHIC:
     835           0 :       return "MONOMORPHIC";
     836             :     case RECOMPUTE_HANDLER:
     837           0 :       return "RECOMPUTE_HANDLER";
     838             :     case POLYMORPHIC:
     839           0 :       return "POLYMORPHIC";
     840             :     case MEGAMORPHIC:
     841           0 :       return "MEGAMORPHIC";
     842             :     case GENERIC:
     843           0 :       return "GENERIC";
     844             :   }
     845           0 :   UNREACHABLE();
     846             : }
     847             : 
     848             : enum WhereToStart { kStartAtReceiver, kStartAtPrototype };
     849             : 
     850             : enum ResultSentinel { kNotFound = -1, kUnsupported = -2 };
     851             : 
     852             : enum ShouldThrow {
     853             :   kThrowOnError = Internals::kThrowOnError,
     854             :   kDontThrow = Internals::kDontThrow
     855             : };
     856             : 
     857             : // The Store Buffer (GC).
     858             : typedef enum {
     859             :   kStoreBufferFullEvent,
     860             :   kStoreBufferStartScanningPagesEvent,
     861             :   kStoreBufferScanningPageEvent
     862             : } StoreBufferEvent;
     863             : 
     864             : 
     865             : typedef void (*StoreBufferCallback)(Heap* heap,
     866             :                                     MemoryChunk* page,
     867             :                                     StoreBufferEvent event);
     868             : 
     869             : // Union used for customized checking of the IEEE double types
     870             : // inlined within v8 runtime, rather than going to the underlying
     871             : // platform headers and libraries
     872             : union IeeeDoubleLittleEndianArchType {
     873             :   double d;
     874             :   struct {
     875             :     unsigned int man_low  :32;
     876             :     unsigned int man_high :20;
     877             :     unsigned int exp      :11;
     878             :     unsigned int sign     :1;
     879             :   } bits;
     880             : };
     881             : 
     882             : 
     883             : union IeeeDoubleBigEndianArchType {
     884             :   double d;
     885             :   struct {
     886             :     unsigned int sign     :1;
     887             :     unsigned int exp      :11;
     888             :     unsigned int man_high :20;
     889             :     unsigned int man_low  :32;
     890             :   } bits;
     891             : };
     892             : 
     893             : #if V8_TARGET_LITTLE_ENDIAN
     894             : typedef IeeeDoubleLittleEndianArchType IeeeDoubleArchType;
     895             : constexpr int kIeeeDoubleMantissaWordOffset = 0;
     896             : constexpr int kIeeeDoubleExponentWordOffset = 4;
     897             : #else
     898             : typedef IeeeDoubleBigEndianArchType IeeeDoubleArchType;
     899             : constexpr int kIeeeDoubleMantissaWordOffset = 4;
     900             : constexpr int kIeeeDoubleExponentWordOffset = 0;
     901             : #endif
     902             : 
     903             : // -----------------------------------------------------------------------------
     904             : // Macros
     905             : 
     906             : // Testers for test.
     907             : 
     908             : #define HAS_SMI_TAG(value) \
     909             :   ((static_cast<intptr_t>(value) & ::i::kSmiTagMask) == ::i::kSmiTag)
     910             : 
     911             : #define HAS_HEAP_OBJECT_TAG(value)                              \
     912             :   (((static_cast<intptr_t>(value) & ::i::kHeapObjectTagMask) == \
     913             :     ::i::kHeapObjectTag))
     914             : 
     915             : // OBJECT_POINTER_ALIGN returns the value aligned as a HeapObject pointer
     916             : #define OBJECT_POINTER_ALIGN(value) \
     917             :   (((value) + ::i::kObjectAlignmentMask) & ~::i::kObjectAlignmentMask)
     918             : 
     919             : // OBJECT_POINTER_PADDING returns the padding size required to align value
     920             : // as a HeapObject pointer
     921             : #define OBJECT_POINTER_PADDING(value) (OBJECT_POINTER_ALIGN(value) - (value))
     922             : 
     923             : // POINTER_SIZE_ALIGN returns the value aligned as a system pointer.
     924             : #define POINTER_SIZE_ALIGN(value) \
     925             :   (((value) + ::i::kPointerAlignmentMask) & ~::i::kPointerAlignmentMask)
     926             : 
     927             : // POINTER_SIZE_PADDING returns the padding size required to align value
     928             : // as a system pointer.
     929             : #define POINTER_SIZE_PADDING(value) (POINTER_SIZE_ALIGN(value) - (value))
     930             : 
     931             : // CODE_POINTER_ALIGN returns the value aligned as a generated code segment.
     932             : #define CODE_POINTER_ALIGN(value) \
     933             :   (((value) + ::i::kCodeAlignmentMask) & ~::i::kCodeAlignmentMask)
     934             : 
     935             : // CODE_POINTER_PADDING returns the padding size required to align value
     936             : // as a generated code segment.
     937             : #define CODE_POINTER_PADDING(value) (CODE_POINTER_ALIGN(value) - (value))
     938             : 
     939             : // DOUBLE_POINTER_ALIGN returns the value algined for double pointers.
     940             : #define DOUBLE_POINTER_ALIGN(value) \
     941             :   (((value) + ::i::kDoubleAlignmentMask) & ~::i::kDoubleAlignmentMask)
     942             : 
     943             : // Defines hints about receiver values based on structural knowledge.
     944             : enum class ConvertReceiverMode : unsigned {
     945             :   kNullOrUndefined,     // Guaranteed to be null or undefined.
     946             :   kNotNullOrUndefined,  // Guaranteed to never be null or undefined.
     947             :   kAny                  // No specific knowledge about receiver.
     948             : };
     949             : 
     950             : inline size_t hash_value(ConvertReceiverMode mode) {
     951           0 :   return bit_cast<unsigned>(mode);
     952             : }
     953             : 
     954           0 : inline std::ostream& operator<<(std::ostream& os, ConvertReceiverMode mode) {
     955           0 :   switch (mode) {
     956             :     case ConvertReceiverMode::kNullOrUndefined:
     957           0 :       return os << "NULL_OR_UNDEFINED";
     958             :     case ConvertReceiverMode::kNotNullOrUndefined:
     959           0 :       return os << "NOT_NULL_OR_UNDEFINED";
     960             :     case ConvertReceiverMode::kAny:
     961           0 :       return os << "ANY";
     962             :   }
     963           0 :   UNREACHABLE();
     964             : }
     965             : 
     966             : // Valid hints for the abstract operation OrdinaryToPrimitive,
     967             : // implemented according to ES6, section 7.1.1.
     968             : enum class OrdinaryToPrimitiveHint { kNumber, kString };
     969             : 
     970             : // Valid hints for the abstract operation ToPrimitive,
     971             : // implemented according to ES6, section 7.1.1.
     972             : enum class ToPrimitiveHint { kDefault, kNumber, kString };
     973             : 
     974             : // Defines specifics about arguments object or rest parameter creation.
     975             : enum class CreateArgumentsType : uint8_t {
     976             :   kMappedArguments,
     977             :   kUnmappedArguments,
     978             :   kRestParameter
     979             : };
     980             : 
     981             : inline size_t hash_value(CreateArgumentsType type) {
     982        7891 :   return bit_cast<uint8_t>(type);
     983             : }
     984             : 
     985           0 : inline std::ostream& operator<<(std::ostream& os, CreateArgumentsType type) {
     986           0 :   switch (type) {
     987             :     case CreateArgumentsType::kMappedArguments:
     988           0 :       return os << "MAPPED_ARGUMENTS";
     989             :     case CreateArgumentsType::kUnmappedArguments:
     990           0 :       return os << "UNMAPPED_ARGUMENTS";
     991             :     case CreateArgumentsType::kRestParameter:
     992           0 :       return os << "REST_PARAMETER";
     993             :   }
     994           0 :   UNREACHABLE();
     995             : }
     996             : 
     997             : enum ScopeType : uint8_t {
     998             :   CLASS_SCOPE,     // The scope introduced by a class.
     999             :   EVAL_SCOPE,      // The top-level scope for an eval source.
    1000             :   FUNCTION_SCOPE,  // The top-level scope for a function.
    1001             :   MODULE_SCOPE,    // The scope introduced by a module literal
    1002             :   SCRIPT_SCOPE,    // The top-level scope for a script or a top-level eval.
    1003             :   CATCH_SCOPE,     // The scope introduced by catch.
    1004             :   BLOCK_SCOPE,     // The scope introduced by a new block.
    1005             :   WITH_SCOPE       // The scope introduced by with.
    1006             : };
    1007             : 
    1008           0 : inline std::ostream& operator<<(std::ostream& os, ScopeType type) {
    1009           0 :   switch (type) {
    1010             :     case ScopeType::EVAL_SCOPE:
    1011           0 :       return os << "EVAL_SCOPE";
    1012             :     case ScopeType::FUNCTION_SCOPE:
    1013           0 :       return os << "FUNCTION_SCOPE";
    1014             :     case ScopeType::MODULE_SCOPE:
    1015           0 :       return os << "MODULE_SCOPE";
    1016             :     case ScopeType::SCRIPT_SCOPE:
    1017           0 :       return os << "SCRIPT_SCOPE";
    1018             :     case ScopeType::CATCH_SCOPE:
    1019           0 :       return os << "CATCH_SCOPE";
    1020             :     case ScopeType::BLOCK_SCOPE:
    1021           0 :       return os << "BLOCK_SCOPE";
    1022             :     case ScopeType::CLASS_SCOPE:
    1023           0 :       return os << "CLASS_SCOPE";
    1024             :     case ScopeType::WITH_SCOPE:
    1025           0 :       return os << "WITH_SCOPE";
    1026             :   }
    1027           0 :   UNREACHABLE();
    1028             : }
    1029             : 
    1030             : // AllocationSiteMode controls whether allocations are tracked by an allocation
    1031             : // site.
    1032             : enum AllocationSiteMode {
    1033             :   DONT_TRACK_ALLOCATION_SITE,
    1034             :   TRACK_ALLOCATION_SITE,
    1035             :   LAST_ALLOCATION_SITE_MODE = TRACK_ALLOCATION_SITE
    1036             : };
    1037             : 
    1038             : enum class AllocationSiteUpdateMode { kUpdate, kCheckOnly };
    1039             : 
    1040             : // The mips architecture prior to revision 5 has inverted encoding for sNaN.
    1041             : #if (V8_TARGET_ARCH_MIPS && !defined(_MIPS_ARCH_MIPS32R6) &&           \
    1042             :      (!defined(USE_SIMULATOR) || !defined(_MIPS_TARGET_SIMULATOR))) || \
    1043             :     (V8_TARGET_ARCH_MIPS64 && !defined(_MIPS_ARCH_MIPS64R6) &&         \
    1044             :      (!defined(USE_SIMULATOR) || !defined(_MIPS_TARGET_SIMULATOR)))
    1045             : constexpr uint32_t kHoleNanUpper32 = 0xFFFF7FFF;
    1046             : constexpr uint32_t kHoleNanLower32 = 0xFFFF7FFF;
    1047             : #else
    1048             : constexpr uint32_t kHoleNanUpper32 = 0xFFF7FFFF;
    1049             : constexpr uint32_t kHoleNanLower32 = 0xFFF7FFFF;
    1050             : #endif
    1051             : 
    1052             : constexpr uint64_t kHoleNanInt64 =
    1053             :     (static_cast<uint64_t>(kHoleNanUpper32) << 32) | kHoleNanLower32;
    1054             : 
    1055             : // ES6 section 20.1.2.6 Number.MAX_SAFE_INTEGER
    1056             : constexpr double kMaxSafeInteger = 9007199254740991.0;  // 2^53-1
    1057             : 
    1058             : // The order of this enum has to be kept in sync with the predicates below.
    1059             : enum class VariableMode : uint8_t {
    1060             :   // User declared variables:
    1061             :   kLet,  // declared via 'let' declarations (first lexical)
    1062             : 
    1063             :   kConst,  // declared via 'const' declarations (last lexical)
    1064             : 
    1065             :   kVar,  // declared via 'var', and 'function' declarations
    1066             : 
    1067             :   // Variables introduced by the compiler:
    1068             :   kTemporary,  // temporary variables (not user-visible), stack-allocated
    1069             :                // unless the scope as a whole has forced context allocation
    1070             : 
    1071             :   kDynamic,  // always require dynamic lookup (we don't know
    1072             :              // the declaration)
    1073             : 
    1074             :   kDynamicGlobal,  // requires dynamic lookup, but we know that the
    1075             :                    // variable is global unless it has been shadowed
    1076             :                    // by an eval-introduced variable
    1077             : 
    1078             :   kDynamicLocal,  // requires dynamic lookup, but we know that the
    1079             :                   // variable is local and where it is unless it
    1080             :                   // has been shadowed by an eval-introduced
    1081             :                   // variable
    1082             : 
    1083             :   kLastLexicalVariableMode = kConst,
    1084             : };
    1085             : 
    1086             : // Printing support
    1087             : #ifdef DEBUG
    1088             : inline const char* VariableMode2String(VariableMode mode) {
    1089             :   switch (mode) {
    1090             :     case VariableMode::kVar:
    1091             :       return "VAR";
    1092             :     case VariableMode::kLet:
    1093             :       return "LET";
    1094             :     case VariableMode::kConst:
    1095             :       return "CONST";
    1096             :     case VariableMode::kDynamic:
    1097             :       return "DYNAMIC";
    1098             :     case VariableMode::kDynamicGlobal:
    1099             :       return "DYNAMIC_GLOBAL";
    1100             :     case VariableMode::kDynamicLocal:
    1101             :       return "DYNAMIC_LOCAL";
    1102             :     case VariableMode::kTemporary:
    1103             :       return "TEMPORARY";
    1104             :   }
    1105             :   UNREACHABLE();
    1106             : }
    1107             : #endif
    1108             : 
    1109             : enum VariableKind : uint8_t {
    1110             :   NORMAL_VARIABLE,
    1111             :   PARAMETER_VARIABLE,
    1112             :   THIS_VARIABLE,
    1113             :   SLOPPY_BLOCK_FUNCTION_VARIABLE,
    1114             :   SLOPPY_FUNCTION_NAME_VARIABLE
    1115             : };
    1116             : 
    1117             : inline bool IsDynamicVariableMode(VariableMode mode) {
    1118    29146366 :   return mode >= VariableMode::kDynamic && mode <= VariableMode::kDynamicLocal;
    1119             : }
    1120             : 
    1121             : inline bool IsDeclaredVariableMode(VariableMode mode) {
    1122             :   STATIC_ASSERT(static_cast<uint8_t>(VariableMode::kLet) ==
    1123             :                 0);  // Implies that mode >= VariableMode::kLet.
    1124             :   return mode <= VariableMode::kVar;
    1125             : }
    1126             : 
    1127             : inline bool IsLexicalVariableMode(VariableMode mode) {
    1128             :   STATIC_ASSERT(static_cast<uint8_t>(VariableMode::kLet) ==
    1129             :                 0);  // Implies that mode >= VariableMode::kLet.
    1130     3179648 :   return mode <= VariableMode::kLastLexicalVariableMode;
    1131             : }
    1132             : 
    1133             : enum VariableLocation : uint8_t {
    1134             :   // Before and during variable allocation, a variable whose location is
    1135             :   // not yet determined.  After allocation, a variable looked up as a
    1136             :   // property on the global object (and possibly absent).  name() is the
    1137             :   // variable name, index() is invalid.
    1138             :   UNALLOCATED,
    1139             : 
    1140             :   // A slot in the parameter section on the stack.  index() is the
    1141             :   // parameter index, counting left-to-right.  The receiver is index -1;
    1142             :   // the first parameter is index 0.
    1143             :   PARAMETER,
    1144             : 
    1145             :   // A slot in the local section on the stack.  index() is the variable
    1146             :   // index in the stack frame, starting at 0.
    1147             :   LOCAL,
    1148             : 
    1149             :   // An indexed slot in a heap context.  index() is the variable index in
    1150             :   // the context object on the heap, starting at 0.  scope() is the
    1151             :   // corresponding scope.
    1152             :   CONTEXT,
    1153             : 
    1154             :   // A named slot in a heap context.  name() is the variable name in the
    1155             :   // context object on the heap, with lookup starting at the current
    1156             :   // context.  index() is invalid.
    1157             :   LOOKUP,
    1158             : 
    1159             :   // A named slot in a module's export table.
    1160             :   MODULE,
    1161             : 
    1162             :   kLastVariableLocation = MODULE
    1163             : };
    1164             : 
    1165             : // ES6 specifies declarative environment records with mutable and immutable
    1166             : // bindings that can be in two states: initialized and uninitialized.
    1167             : // When accessing a binding, it needs to be checked for initialization.
    1168             : // However in the following cases the binding is initialized immediately
    1169             : // after creation so the initialization check can always be skipped:
    1170             : //
    1171             : // 1. Var declared local variables.
    1172             : //      var foo;
    1173             : // 2. A local variable introduced by a function declaration.
    1174             : //      function foo() {}
    1175             : // 3. Parameters
    1176             : //      function x(foo) {}
    1177             : // 4. Catch bound variables.
    1178             : //      try {} catch (foo) {}
    1179             : // 6. Function name variables of named function expressions.
    1180             : //      var x = function foo() {}
    1181             : // 7. Implicit binding of 'this'.
    1182             : // 8. Implicit binding of 'arguments' in functions.
    1183             : //
    1184             : // The following enum specifies a flag that indicates if the binding needs a
    1185             : // distinct initialization step (kNeedsInitialization) or if the binding is
    1186             : // immediately initialized upon creation (kCreatedInitialized).
    1187             : enum InitializationFlag : uint8_t { kNeedsInitialization, kCreatedInitialized };
    1188             : 
    1189             : enum MaybeAssignedFlag : uint8_t { kNotAssigned, kMaybeAssigned };
    1190             : 
    1191             : enum ParseErrorType { kSyntaxError = 0, kReferenceError = 1 };
    1192             : 
    1193             : 
    1194             : enum class InterpreterPushArgsMode : unsigned {
    1195             :   kArrayFunction,
    1196             :   kWithFinalSpread,
    1197             :   kOther
    1198             : };
    1199             : 
    1200             : inline size_t hash_value(InterpreterPushArgsMode mode) {
    1201             :   return bit_cast<unsigned>(mode);
    1202             : }
    1203             : 
    1204             : inline std::ostream& operator<<(std::ostream& os,
    1205             :                                 InterpreterPushArgsMode mode) {
    1206             :   switch (mode) {
    1207             :     case InterpreterPushArgsMode::kArrayFunction:
    1208             :       return os << "ArrayFunction";
    1209             :     case InterpreterPushArgsMode::kWithFinalSpread:
    1210             :       return os << "WithFinalSpread";
    1211             :     case InterpreterPushArgsMode::kOther:
    1212             :       return os << "Other";
    1213             :   }
    1214             :   UNREACHABLE();
    1215             : }
    1216             : 
    1217             : inline uint32_t ObjectHash(Address address) {
    1218             :   // All objects are at least pointer aligned, so we can remove the trailing
    1219             :   // zeros.
    1220             :   return static_cast<uint32_t>(address >> kTaggedSizeLog2);
    1221             : }
    1222             : 
    1223             : // Type feedback is encoded in such a way that, we can combine the feedback
    1224             : // at different points by performing an 'OR' operation. Type feedback moves
    1225             : // to a more generic type when we combine feedback.
    1226             : //
    1227             : //   kSignedSmall -> kSignedSmallInputs -> kNumber  -> kNumberOrOddball -> kAny
    1228             : //                   kConsString                    -> kString          -> kAny
    1229             : //                                                     kBigInt          -> kAny
    1230             : //
    1231             : // Technically we wouldn't need the separation between the kNumber and the
    1232             : // kNumberOrOddball values here, since for binary operations, we always
    1233             : // truncate oddballs to numbers. In practice though it causes TurboFan to
    1234             : // generate quite a lot of unused code though if we always handle numbers
    1235             : // and oddballs everywhere, although in 99% of the use sites they are only
    1236             : // used with numbers.
    1237             : class BinaryOperationFeedback {
    1238             :  public:
    1239             :   enum {
    1240             :     kNone = 0x0,
    1241             :     kSignedSmall = 0x1,
    1242             :     kSignedSmallInputs = 0x3,
    1243             :     kNumber = 0x7,
    1244             :     kNumberOrOddball = 0xF,
    1245             :     kConsOneByteString = 0x10,
    1246             :     kConsTwoByteString = 0x20,
    1247             :     kConsString = kConsOneByteString | kConsTwoByteString,
    1248             :     kString = 0x70,
    1249             :     kBigInt = 0x100,
    1250             :     kAny = 0x3FF
    1251             :   };
    1252             : };
    1253             : 
    1254             : // Type feedback is encoded in such a way that, we can combine the feedback
    1255             : // at different points by performing an 'OR' operation. Type feedback moves
    1256             : // to a more generic type when we combine feedback.
    1257             : //
    1258             : //   kSignedSmall -> kNumber             -> kNumberOrOddball           -> kAny
    1259             : //                   kReceiver           -> kReceiverOrNullOrUndefined -> kAny
    1260             : //                   kInternalizedString -> kString                    -> kAny
    1261             : //                                          kSymbol                    -> kAny
    1262             : //                                          kBigInt                    -> kAny
    1263             : //
    1264             : // This is distinct from BinaryOperationFeedback on purpose, because the
    1265             : // feedback that matters differs greatly as well as the way it is consumed.
    1266             : class CompareOperationFeedback {
    1267             :  public:
    1268             :   enum {
    1269             :     kNone = 0x000,
    1270             :     kSignedSmall = 0x001,
    1271             :     kNumber = 0x003,
    1272             :     kNumberOrOddball = 0x007,
    1273             :     kInternalizedString = 0x008,
    1274             :     kString = 0x018,
    1275             :     kSymbol = 0x020,
    1276             :     kBigInt = 0x040,
    1277             :     kReceiver = 0x080,
    1278             :     kReceiverOrNullOrUndefined = 0x180,
    1279             :     kAny = 0x1ff
    1280             :   };
    1281             : };
    1282             : 
    1283             : enum class Operation {
    1284             :   // Binary operations.
    1285             :   kAdd,
    1286             :   kSubtract,
    1287             :   kMultiply,
    1288             :   kDivide,
    1289             :   kModulus,
    1290             :   kExponentiate,
    1291             :   kBitwiseAnd,
    1292             :   kBitwiseOr,
    1293             :   kBitwiseXor,
    1294             :   kShiftLeft,
    1295             :   kShiftRight,
    1296             :   kShiftRightLogical,
    1297             :   // Unary operations.
    1298             :   kBitwiseNot,
    1299             :   kNegate,
    1300             :   kIncrement,
    1301             :   kDecrement,
    1302             :   // Compare operations.
    1303             :   kEqual,
    1304             :   kStrictEqual,
    1305             :   kLessThan,
    1306             :   kLessThanOrEqual,
    1307             :   kGreaterThan,
    1308             :   kGreaterThanOrEqual,
    1309             : };
    1310             : 
    1311             : // Type feedback is encoded in such a way that, we can combine the feedback
    1312             : // at different points by performing an 'OR' operation. Type feedback moves
    1313             : // to a more generic type when we combine feedback.
    1314             : // kNone -> kEnumCacheKeysAndIndices -> kEnumCacheKeys -> kAny
    1315             : class ForInFeedback {
    1316             :  public:
    1317             :   enum {
    1318             :     kNone = 0x0,
    1319             :     kEnumCacheKeysAndIndices = 0x1,
    1320             :     kEnumCacheKeys = 0x3,
    1321             :     kAny = 0x7
    1322             :   };
    1323             : };
    1324             : STATIC_ASSERT((ForInFeedback::kNone |
    1325             :                ForInFeedback::kEnumCacheKeysAndIndices) ==
    1326             :               ForInFeedback::kEnumCacheKeysAndIndices);
    1327             : STATIC_ASSERT((ForInFeedback::kEnumCacheKeysAndIndices |
    1328             :                ForInFeedback::kEnumCacheKeys) == ForInFeedback::kEnumCacheKeys);
    1329             : STATIC_ASSERT((ForInFeedback::kEnumCacheKeys | ForInFeedback::kAny) ==
    1330             :               ForInFeedback::kAny);
    1331             : 
    1332             : enum class UnicodeEncoding : uint8_t {
    1333             :   // Different unicode encodings in a |word32|:
    1334             :   UTF16,  // hi 16bits -> trailing surrogate or 0, low 16bits -> lead surrogate
    1335             :   UTF32,  // full UTF32 code unit / Unicode codepoint
    1336             : };
    1337             : 
    1338             : inline size_t hash_value(UnicodeEncoding encoding) {
    1339         945 :   return static_cast<uint8_t>(encoding);
    1340             : }
    1341             : 
    1342           0 : inline std::ostream& operator<<(std::ostream& os, UnicodeEncoding encoding) {
    1343           0 :   switch (encoding) {
    1344             :     case UnicodeEncoding::UTF16:
    1345           0 :       return os << "UTF16";
    1346             :     case UnicodeEncoding::UTF32:
    1347           0 :       return os << "UTF32";
    1348             :   }
    1349           0 :   UNREACHABLE();
    1350             : }
    1351             : 
    1352             : enum class IterationKind { kKeys, kValues, kEntries };
    1353             : 
    1354           0 : inline std::ostream& operator<<(std::ostream& os, IterationKind kind) {
    1355           0 :   switch (kind) {
    1356             :     case IterationKind::kKeys:
    1357           0 :       return os << "IterationKind::kKeys";
    1358             :     case IterationKind::kValues:
    1359           0 :       return os << "IterationKind::kValues";
    1360             :     case IterationKind::kEntries:
    1361           0 :       return os << "IterationKind::kEntries";
    1362             :   }
    1363           0 :   UNREACHABLE();
    1364             : }
    1365             : 
    1366             : enum class CollectionKind { kMap, kSet };
    1367             : 
    1368           0 : inline std::ostream& operator<<(std::ostream& os, CollectionKind kind) {
    1369           0 :   switch (kind) {
    1370             :     case CollectionKind::kMap:
    1371           0 :       return os << "CollectionKind::kMap";
    1372             :     case CollectionKind::kSet:
    1373           0 :       return os << "CollectionKind::kSet";
    1374             :   }
    1375           0 :   UNREACHABLE();
    1376             : }
    1377             : 
    1378             : // Flags for the runtime function kDefineDataPropertyInLiteral. A property can
    1379             : // be enumerable or not, and, in case of functions, the function name
    1380             : // can be set or not.
    1381             : enum class DataPropertyInLiteralFlag {
    1382             :   kNoFlags = 0,
    1383             :   kDontEnum = 1 << 0,
    1384             :   kSetFunctionName = 1 << 1
    1385             : };
    1386             : typedef base::Flags<DataPropertyInLiteralFlag> DataPropertyInLiteralFlags;
    1387             : DEFINE_OPERATORS_FOR_FLAGS(DataPropertyInLiteralFlags)
    1388             : 
    1389             : enum ExternalArrayType {
    1390             :   kExternalInt8Array = 1,
    1391             :   kExternalUint8Array,
    1392             :   kExternalInt16Array,
    1393             :   kExternalUint16Array,
    1394             :   kExternalInt32Array,
    1395             :   kExternalUint32Array,
    1396             :   kExternalFloat32Array,
    1397             :   kExternalFloat64Array,
    1398             :   kExternalUint8ClampedArray,
    1399             :   kExternalBigInt64Array,
    1400             :   kExternalBigUint64Array,
    1401             : };
    1402             : 
    1403             : struct AssemblerDebugInfo {
    1404             :   AssemblerDebugInfo(const char* name, const char* file, int line)
    1405             :       : name(name), file(file), line(line) {}
    1406             :   const char* name;
    1407             :   const char* file;
    1408             :   int line;
    1409             : };
    1410             : 
    1411             : inline std::ostream& operator<<(std::ostream& os,
    1412             :                                 const AssemblerDebugInfo& info) {
    1413             :   os << "(" << info.name << ":" << info.file << ":" << info.line << ")";
    1414             :   return os;
    1415             : }
    1416             : 
    1417             : enum class OptimizationMarker {
    1418             :   kLogFirstExecution,
    1419             :   kNone,
    1420             :   kCompileOptimized,
    1421             :   kCompileOptimizedConcurrent,
    1422             :   kInOptimizationQueue
    1423             : };
    1424             : 
    1425             : inline std::ostream& operator<<(std::ostream& os,
    1426             :                                 const OptimizationMarker& marker) {
    1427             :   switch (marker) {
    1428             :     case OptimizationMarker::kLogFirstExecution:
    1429             :       return os << "OptimizationMarker::kLogFirstExecution";
    1430             :     case OptimizationMarker::kNone:
    1431             :       return os << "OptimizationMarker::kNone";
    1432             :     case OptimizationMarker::kCompileOptimized:
    1433             :       return os << "OptimizationMarker::kCompileOptimized";
    1434             :     case OptimizationMarker::kCompileOptimizedConcurrent:
    1435             :       return os << "OptimizationMarker::kCompileOptimizedConcurrent";
    1436             :     case OptimizationMarker::kInOptimizationQueue:
    1437             :       return os << "OptimizationMarker::kInOptimizationQueue";
    1438             :   }
    1439             :   UNREACHABLE();
    1440             :   return os;
    1441             : }
    1442             : 
    1443             : enum class SpeculationMode { kAllowSpeculation, kDisallowSpeculation };
    1444             : 
    1445             : inline std::ostream& operator<<(std::ostream& os,
    1446             :                                 SpeculationMode speculation_mode) {
    1447             :   switch (speculation_mode) {
    1448             :     case SpeculationMode::kAllowSpeculation:
    1449             :       return os << "SpeculationMode::kAllowSpeculation";
    1450             :     case SpeculationMode::kDisallowSpeculation:
    1451             :       return os << "SpeculationMode::kDisallowSpeculation";
    1452             :   }
    1453             :   UNREACHABLE();
    1454             :   return os;
    1455             : }
    1456             : 
    1457             : enum class BlockingBehavior { kBlock, kDontBlock };
    1458             : 
    1459             : enum class ConcurrencyMode { kNotConcurrent, kConcurrent };
    1460             : 
    1461             : #define FOR_EACH_ISOLATE_ADDRESS_NAME(C)                       \
    1462             :   C(Handler, handler)                                          \
    1463             :   C(CEntryFP, c_entry_fp)                                      \
    1464             :   C(CFunction, c_function)                                     \
    1465             :   C(Context, context)                                          \
    1466             :   C(PendingException, pending_exception)                       \
    1467             :   C(PendingHandlerContext, pending_handler_context)            \
    1468             :   C(PendingHandlerEntrypoint, pending_handler_entrypoint)      \
    1469             :   C(PendingHandlerConstantPool, pending_handler_constant_pool) \
    1470             :   C(PendingHandlerFP, pending_handler_fp)                      \
    1471             :   C(PendingHandlerSP, pending_handler_sp)                      \
    1472             :   C(ExternalCaughtException, external_caught_exception)        \
    1473             :   C(JSEntrySP, js_entry_sp)
    1474             : 
    1475             : enum IsolateAddressId {
    1476             : #define DECLARE_ENUM(CamelName, hacker_name) k##CamelName##Address,
    1477             :   FOR_EACH_ISOLATE_ADDRESS_NAME(DECLARE_ENUM)
    1478             : #undef DECLARE_ENUM
    1479             :       kIsolateAddressCount
    1480             : };
    1481             : 
    1482             : V8_INLINE static bool HasWeakHeapObjectTag(Address value) {
    1483             :   // TODO(jkummerow): Consolidate integer types here.
    1484   812120689 :   return ((static_cast<intptr_t>(value) & kHeapObjectTagMask) ==
    1485             :           kWeakHeapObjectTag);
    1486             : }
    1487             : 
    1488             : enum class HeapObjectReferenceType {
    1489             :   WEAK,
    1490             :   STRONG,
    1491             : };
    1492             : 
    1493             : enum class PoisoningMitigationLevel {
    1494             :   kPoisonAll,
    1495             :   kDontPoison,
    1496             :   kPoisonCriticalOnly
    1497             : };
    1498             : 
    1499             : enum class LoadSensitivity {
    1500             :   kCritical,  // Critical loads are poisoned whenever we can run untrusted
    1501             :               // code (i.e., when --untrusted-code-mitigations is on).
    1502             :   kUnsafe,    // Unsafe loads are poisoned when full poisoning is on
    1503             :               // (--branch-load-poisoning).
    1504             :   kSafe       // Safe loads are never poisoned.
    1505             : };
    1506             : 
    1507             : // The reason for a WebAssembly trap.
    1508             : #define FOREACH_WASM_TRAPREASON(V) \
    1509             :   V(TrapUnreachable)               \
    1510             :   V(TrapMemOutOfBounds)            \
    1511             :   V(TrapUnalignedAccess)           \
    1512             :   V(TrapDivByZero)                 \
    1513             :   V(TrapDivUnrepresentable)        \
    1514             :   V(TrapRemByZero)                 \
    1515             :   V(TrapFloatUnrepresentable)      \
    1516             :   V(TrapFuncInvalid)               \
    1517             :   V(TrapFuncSigMismatch)           \
    1518             :   V(TrapDataSegmentDropped)        \
    1519             :   V(TrapElemSegmentDropped)        \
    1520             :   V(TrapTableOutOfBounds)
    1521             : 
    1522             : enum KeyedAccessLoadMode {
    1523             :   STANDARD_LOAD,
    1524             :   LOAD_IGNORE_OUT_OF_BOUNDS,
    1525             : };
    1526             : 
    1527             : enum KeyedAccessStoreMode {
    1528             :   STANDARD_STORE,
    1529             :   STORE_TRANSITION_TO_OBJECT,
    1530             :   STORE_TRANSITION_TO_DOUBLE,
    1531             :   STORE_AND_GROW_NO_TRANSITION_HANDLE_COW,
    1532             :   STORE_AND_GROW_TRANSITION_TO_OBJECT,
    1533             :   STORE_AND_GROW_TRANSITION_TO_DOUBLE,
    1534             :   STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS,
    1535             :   STORE_NO_TRANSITION_HANDLE_COW
    1536             : };
    1537             : 
    1538             : enum MutableMode { MUTABLE, IMMUTABLE };
    1539             : 
    1540             : static inline bool IsTransitionStoreMode(KeyedAccessStoreMode store_mode) {
    1541       15373 :   return store_mode == STORE_TRANSITION_TO_OBJECT ||
    1542       15373 :          store_mode == STORE_TRANSITION_TO_DOUBLE ||
    1543       33237 :          store_mode == STORE_AND_GROW_TRANSITION_TO_OBJECT ||
    1544             :          store_mode == STORE_AND_GROW_TRANSITION_TO_DOUBLE;
    1545             : }
    1546             : 
    1547             : static inline bool IsCOWHandlingStoreMode(KeyedAccessStoreMode store_mode) {
    1548        6826 :   return store_mode == STORE_NO_TRANSITION_HANDLE_COW ||
    1549        6826 :          store_mode == STORE_AND_GROW_NO_TRANSITION_HANDLE_COW;
    1550             : }
    1551             : 
    1552             : static inline KeyedAccessStoreMode GetNonTransitioningStoreMode(
    1553             :     KeyedAccessStoreMode store_mode, bool receiver_was_cow) {
    1554      278434 :   switch (store_mode) {
    1555             :     case STORE_AND_GROW_NO_TRANSITION_HANDLE_COW:
    1556             :     case STORE_AND_GROW_TRANSITION_TO_OBJECT:
    1557             :     case STORE_AND_GROW_TRANSITION_TO_DOUBLE:
    1558             :       store_mode = STORE_AND_GROW_NO_TRANSITION_HANDLE_COW;
    1559             :       break;
    1560             :     case STANDARD_STORE:
    1561             :     case STORE_TRANSITION_TO_OBJECT:
    1562             :     case STORE_TRANSITION_TO_DOUBLE:
    1563             :       store_mode =
    1564      257212 :           receiver_was_cow ? STORE_NO_TRANSITION_HANDLE_COW : STANDARD_STORE;
    1565             :       break;
    1566             :     case STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS:
    1567             :     case STORE_NO_TRANSITION_HANDLE_COW:
    1568             :       break;
    1569             :   }
    1570             :   DCHECK(!IsTransitionStoreMode(store_mode));
    1571             :   DCHECK_IMPLIES(receiver_was_cow, IsCOWHandlingStoreMode(store_mode));
    1572             :   return store_mode;
    1573             : }
    1574             : 
    1575             : static inline bool IsGrowStoreMode(KeyedAccessStoreMode store_mode) {
    1576       24274 :   return store_mode >= STORE_AND_GROW_NO_TRANSITION_HANDLE_COW &&
    1577             :          store_mode <= STORE_AND_GROW_TRANSITION_TO_DOUBLE;
    1578             : }
    1579             : 
    1580             : enum IcCheckType { ELEMENT, PROPERTY };
    1581             : 
    1582             : // Helper stubs can be called in different ways depending on where the target
    1583             : // code is located and how the call sequence is expected to look like:
    1584             : //  - CodeObject: Call on-heap {Code} object via {RelocInfo::CODE_TARGET}.
    1585             : //  - WasmRuntimeStub: Call native {WasmCode} stub via
    1586             : //    {RelocInfo::WASM_STUB_CALL}.
    1587             : //  - BuiltinPointer: Call a builtin based on a builtin pointer with dynamic
    1588             : //    contents. If builtins are embedded, we call directly into off-heap code
    1589             : //    without going through the on-heap Code trampoline.
    1590             : enum class StubCallMode {
    1591             :   kCallCodeObject,
    1592             :   kCallWasmRuntimeStub,
    1593             :   kCallBuiltinPointer,
    1594             : };
    1595             : 
    1596             : constexpr int kFunctionLiteralIdInvalid = -1;
    1597             : constexpr int kFunctionLiteralIdTopLevel = 0;
    1598             : 
    1599             : constexpr int kSmallOrderedHashSetMinCapacity = 4;
    1600             : constexpr int kSmallOrderedHashMapMinCapacity = 4;
    1601             : 
    1602             : }  // namespace internal
    1603             : }  // namespace v8
    1604             : 
    1605             : namespace i = v8::internal;
    1606             : 
    1607             : #endif  // V8_GLOBALS_H_

Generated by: LCOV version 1.10