LCOV - code coverage report
Current view: top level - src - globals.h (source / functions) Hit Total Coverage
Test: app.info Lines: 33 95 34.7 %
Date: 2019-03-21 Functions: 6 13 46.2 %

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

Generated by: LCOV version 1.10