LCOV - code coverage report
Current view: top level - src - globals.h (source / functions) Hit Total Coverage
Test: app.info Lines: 44 84 52.4 %
Date: 2017-10-20 Functions: 11 22 50.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 "src/base/build_config.h"
      15             : #include "src/base/flags.h"
      16             : #include "src/base/logging.h"
      17             : #include "src/base/macros.h"
      18             : 
      19             : #ifdef V8_OS_WIN
      20             : 
      21             : // Setup for Windows shared library export.
      22             : #ifdef BUILDING_V8_SHARED
      23             : #define V8_EXPORT_PRIVATE __declspec(dllexport)
      24             : #elif USING_V8_SHARED
      25             : #define V8_EXPORT_PRIVATE __declspec(dllimport)
      26             : #else
      27             : #define V8_EXPORT_PRIVATE
      28             : #endif  // BUILDING_V8_SHARED
      29             : 
      30             : #else  // V8_OS_WIN
      31             : 
      32             : // Setup for Linux shared library export.
      33             : #if V8_HAS_ATTRIBUTE_VISIBILITY
      34             : #ifdef BUILDING_V8_SHARED
      35             : #define V8_EXPORT_PRIVATE __attribute__((visibility("default")))
      36             : #else
      37             : #define V8_EXPORT_PRIVATE
      38             : #endif
      39             : #else
      40             : #define V8_EXPORT_PRIVATE
      41             : #endif
      42             : 
      43             : #endif  // V8_OS_WIN
      44             : 
      45             : #define V8_INFINITY std::numeric_limits<double>::infinity()
      46             : 
      47             : namespace v8 {
      48             : 
      49             : namespace base {
      50             : class Mutex;
      51             : class RecursiveMutex;
      52             : class VirtualMemory;
      53             : }
      54             : 
      55             : namespace internal {
      56             : 
      57             : // Determine whether we are running in a simulated environment.
      58             : // Setting USE_SIMULATOR explicitly from the build script will force
      59             : // the use of a simulated environment.
      60             : #if !defined(USE_SIMULATOR)
      61             : #if (V8_TARGET_ARCH_ARM64 && !V8_HOST_ARCH_ARM64)
      62             : #define USE_SIMULATOR 1
      63             : #endif
      64             : #if (V8_TARGET_ARCH_ARM && !V8_HOST_ARCH_ARM)
      65             : #define USE_SIMULATOR 1
      66             : #endif
      67             : #if (V8_TARGET_ARCH_PPC && !V8_HOST_ARCH_PPC)
      68             : #define USE_SIMULATOR 1
      69             : #endif
      70             : #if (V8_TARGET_ARCH_MIPS && !V8_HOST_ARCH_MIPS)
      71             : #define USE_SIMULATOR 1
      72             : #endif
      73             : #if (V8_TARGET_ARCH_MIPS64 && !V8_HOST_ARCH_MIPS64)
      74             : #define USE_SIMULATOR 1
      75             : #endif
      76             : #if (V8_TARGET_ARCH_S390 && !V8_HOST_ARCH_S390)
      77             : #define USE_SIMULATOR 1
      78             : #endif
      79             : #endif
      80             : 
      81             : // Determine whether the architecture uses an embedded constant pool
      82             : // (contiguous constant pool embedded in code object).
      83             : #if V8_TARGET_ARCH_PPC
      84             : #define V8_EMBEDDED_CONSTANT_POOL 1
      85             : #else
      86             : #define V8_EMBEDDED_CONSTANT_POOL 0
      87             : #endif
      88             : 
      89             : #ifdef V8_TARGET_ARCH_ARM
      90             : // Set stack limit lower for ARM than for other architectures because
      91             : // stack allocating MacroAssembler takes 120K bytes.
      92             : // See issue crbug.com/405338
      93             : #define V8_DEFAULT_STACK_SIZE_KB 864
      94             : #else
      95             : // Slightly less than 1MB, since Windows' default stack size for
      96             : // the main execution thread is 1MB for both 32 and 64-bit.
      97             : #define V8_DEFAULT_STACK_SIZE_KB 984
      98             : #endif
      99             : 
     100             : // Minimum stack size in KB required by compilers.
     101             : const int kStackSpaceRequiredForCompilation = 40;
     102             : 
     103             : // Determine whether double field unboxing feature is enabled.
     104             : #if V8_TARGET_ARCH_64_BIT
     105             : #define V8_DOUBLE_FIELDS_UNBOXING 1
     106             : #else
     107             : #define V8_DOUBLE_FIELDS_UNBOXING 0
     108             : #endif
     109             : 
     110             : // Some types of tracing require the SFI to store a unique ID.
     111             : #if defined(V8_TRACE_MAPS) || defined(V8_TRACE_IGNITION)
     112             : #define V8_SFI_HAS_UNIQUE_ID 1
     113             : #endif
     114             : 
     115             : // Superclass for classes only using static method functions.
     116             : // The subclass of AllStatic cannot be instantiated at all.
     117             : class AllStatic {
     118             : #ifdef DEBUG
     119             :  public:
     120             :   AllStatic() = delete;
     121             : #endif
     122             : };
     123             : 
     124             : // DEPRECATED
     125             : // TODO(leszeks): Delete this during a quiet period
     126             : #define BASE_EMBEDDED
     127             : 
     128             : typedef uint8_t byte;
     129             : typedef byte* Address;
     130             : 
     131             : // -----------------------------------------------------------------------------
     132             : // Constants
     133             : 
     134             : const int KB = 1024;
     135             : const int MB = KB * KB;
     136             : const int GB = KB * KB * KB;
     137             : const int kMaxInt = 0x7FFFFFFF;
     138             : const int kMinInt = -kMaxInt - 1;
     139             : const int kMaxInt8 = (1 << 7) - 1;
     140             : const int kMinInt8 = -(1 << 7);
     141             : const int kMaxUInt8 = (1 << 8) - 1;
     142             : const int kMinUInt8 = 0;
     143             : const int kMaxInt16 = (1 << 15) - 1;
     144             : const int kMinInt16 = -(1 << 15);
     145             : const int kMaxUInt16 = (1 << 16) - 1;
     146             : const int kMinUInt16 = 0;
     147             : 
     148             : const uint32_t kMaxUInt32 = 0xFFFFFFFFu;
     149             : const int kMinUInt32 = 0;
     150             : 
     151             : const int kCharSize = sizeof(char);
     152             : const int kShortSize = sizeof(short);  // NOLINT
     153             : const int kIntSize = sizeof(int);
     154             : const int kInt32Size = sizeof(int32_t);
     155             : const int kInt64Size = sizeof(int64_t);
     156             : const int kUInt32Size = sizeof(uint32_t);
     157             : const int kSizetSize = sizeof(size_t);
     158             : const int kFloatSize = sizeof(float);
     159             : const int kDoubleSize = sizeof(double);
     160             : const int kIntptrSize = sizeof(intptr_t);
     161             : const int kUIntptrSize = sizeof(uintptr_t);
     162             : const int kPointerSize = sizeof(void*);
     163             : #if V8_TARGET_ARCH_X64 && V8_TARGET_ARCH_32_BIT
     164             : const int kRegisterSize = kPointerSize + kPointerSize;
     165             : #else
     166             : const int kRegisterSize = kPointerSize;
     167             : #endif
     168             : const int kPCOnStackSize = kRegisterSize;
     169             : const int kFPOnStackSize = kRegisterSize;
     170             : 
     171             : #if V8_TARGET_ARCH_X64 || V8_TARGET_ARCH_IA32
     172             : const int kElidedFrameSlots = kPCOnStackSize / kPointerSize;
     173             : #else
     174             : const int kElidedFrameSlots = 0;
     175             : #endif
     176             : 
     177             : const int kDoubleSizeLog2 = 3;
     178             : 
     179             : #if V8_HOST_ARCH_64_BIT
     180             : const int kPointerSizeLog2 = 3;
     181             : const intptr_t kIntptrSignBit = V8_INT64_C(0x8000000000000000);
     182             : const uintptr_t kUintptrAllBitsSet = V8_UINT64_C(0xFFFFFFFFFFFFFFFF);
     183             : const bool kRequiresCodeRange = true;
     184             : #if V8_TARGET_ARCH_MIPS64
     185             : // To use pseudo-relative jumps such as j/jal instructions which have 28-bit
     186             : // encoded immediate, the addresses have to be in range of 256MB aligned
     187             : // region. Used only for large object space.
     188             : const size_t kMaximalCodeRangeSize = 256 * MB;
     189             : const size_t kCodeRangeAreaAlignment = 256 * MB;
     190             : #elif V8_HOST_ARCH_PPC && V8_TARGET_ARCH_PPC && V8_OS_LINUX
     191             : const size_t kMaximalCodeRangeSize = 512 * MB;
     192             : const size_t kCodeRangeAreaAlignment = 64 * KB;  // OS page on PPC Linux
     193             : #else
     194             : const size_t kMaximalCodeRangeSize = 512 * MB;
     195             : const size_t kCodeRangeAreaAlignment = 4 * KB;  // OS page.
     196             : #endif
     197             : #if V8_OS_WIN
     198             : const size_t kMinimumCodeRangeSize = 4 * MB;
     199             : const size_t kReservedCodeRangePages = 1;
     200             : #else
     201             : const size_t kMinimumCodeRangeSize = 3 * MB;
     202             : const size_t kReservedCodeRangePages = 0;
     203             : #endif
     204             : #else
     205             : const int kPointerSizeLog2 = 2;
     206             : const intptr_t kIntptrSignBit = 0x80000000;
     207             : const uintptr_t kUintptrAllBitsSet = 0xFFFFFFFFu;
     208             : #if V8_TARGET_ARCH_X64 && V8_TARGET_ARCH_32_BIT
     209             : // x32 port also requires code range.
     210             : const bool kRequiresCodeRange = true;
     211             : const size_t kMaximalCodeRangeSize = 256 * MB;
     212             : const size_t kMinimumCodeRangeSize = 3 * MB;
     213             : const size_t kCodeRangeAreaAlignment = 4 * KB;  // OS page.
     214             : #elif V8_HOST_ARCH_PPC && V8_TARGET_ARCH_PPC && V8_OS_LINUX
     215             : const bool kRequiresCodeRange = false;
     216             : const size_t kMaximalCodeRangeSize = 0 * MB;
     217             : const size_t kMinimumCodeRangeSize = 0 * MB;
     218             : const size_t kCodeRangeAreaAlignment = 64 * KB;  // OS page on PPC Linux
     219             : #else
     220             : const bool kRequiresCodeRange = false;
     221             : const size_t kMaximalCodeRangeSize = 0 * MB;
     222             : const size_t kMinimumCodeRangeSize = 0 * MB;
     223             : const size_t kCodeRangeAreaAlignment = 4 * KB;  // OS page.
     224             : #endif
     225             : const size_t kReservedCodeRangePages = 0;
     226             : #endif
     227             : 
     228             : // Trigger an incremental GCs once the external memory reaches this limit.
     229             : const int kExternalAllocationSoftLimit = 64 * MB;
     230             : 
     231             : // Maximum object size that gets allocated into regular pages. Objects larger
     232             : // than that size are allocated in large object space and are never moved in
     233             : // memory. This also applies to new space allocation, since objects are never
     234             : // migrated from new space to large object space. Takes double alignment into
     235             : // account.
     236             : //
     237             : // Current value: Page::kAllocatableMemory (on 32-bit arch) - 512 (slack).
     238             : const int kMaxRegularHeapObjectSize = 507136;
     239             : 
     240             : STATIC_ASSERT(kPointerSize == (1 << kPointerSizeLog2));
     241             : 
     242             : const int kBitsPerByte = 8;
     243             : const int kBitsPerByteLog2 = 3;
     244             : const int kBitsPerPointer = kPointerSize * kBitsPerByte;
     245             : const int kBitsPerInt = kIntSize * kBitsPerByte;
     246             : 
     247             : // IEEE 754 single precision floating point number bit layout.
     248             : const uint32_t kBinary32SignMask = 0x80000000u;
     249             : const uint32_t kBinary32ExponentMask = 0x7f800000u;
     250             : const uint32_t kBinary32MantissaMask = 0x007fffffu;
     251             : const int kBinary32ExponentBias = 127;
     252             : const int kBinary32MaxExponent  = 0xFE;
     253             : const int kBinary32MinExponent  = 0x01;
     254             : const int kBinary32MantissaBits = 23;
     255             : const int kBinary32ExponentShift = 23;
     256             : 
     257             : // Quiet NaNs have bits 51 to 62 set, possibly the sign bit, and no
     258             : // other bits set.
     259             : const uint64_t kQuietNaNMask = static_cast<uint64_t>(0xfff) << 51;
     260             : 
     261             : // Latin1/UTF-16 constants
     262             : // Code-point values in Unicode 4.0 are 21 bits wide.
     263             : // Code units in UTF-16 are 16 bits wide.
     264             : typedef uint16_t uc16;
     265             : typedef int32_t uc32;
     266             : const int kOneByteSize    = kCharSize;
     267             : const int kUC16Size     = sizeof(uc16);      // NOLINT
     268             : 
     269             : // 128 bit SIMD value size.
     270             : const int kSimd128Size = 16;
     271             : 
     272             : // Round up n to be a multiple of sz, where sz is a power of 2.
     273             : #define ROUND_UP(n, sz) (((n) + ((sz) - 1)) & ~((sz) - 1))
     274             : 
     275             : 
     276             : // FUNCTION_ADDR(f) gets the address of a C function f.
     277             : #define FUNCTION_ADDR(f)                                        \
     278             :   (reinterpret_cast<v8::internal::Address>(reinterpret_cast<intptr_t>(f)))
     279             : 
     280             : 
     281             : // FUNCTION_CAST<F>(addr) casts an address into a function
     282             : // of type F. Used to invoke generated code from within C.
     283             : template <typename F>
     284      634477 : F FUNCTION_CAST(Address addr) {
     285    96806652 :   return reinterpret_cast<F>(reinterpret_cast<intptr_t>(addr));
     286             : }
     287             : 
     288             : 
     289             : // Determine whether the architecture uses function descriptors
     290             : // which provide a level of indirection between the function pointer
     291             : // and the function entrypoint.
     292             : #if V8_HOST_ARCH_PPC && \
     293             :     (V8_OS_AIX || (V8_TARGET_ARCH_PPC64 && V8_TARGET_BIG_ENDIAN))
     294             : #define USES_FUNCTION_DESCRIPTORS 1
     295             : #define FUNCTION_ENTRYPOINT_ADDRESS(f)       \
     296             :   (reinterpret_cast<v8::internal::Address*>( \
     297             :       &(reinterpret_cast<intptr_t*>(f)[0])))
     298             : #else
     299             : #define USES_FUNCTION_DESCRIPTORS 0
     300             : #endif
     301             : 
     302             : 
     303             : // -----------------------------------------------------------------------------
     304             : // Forward declarations for frequently used classes
     305             : // (sorted alphabetically)
     306             : 
     307             : class FreeStoreAllocationPolicy;
     308             : template <typename T, class P = FreeStoreAllocationPolicy> class List;
     309             : 
     310             : // -----------------------------------------------------------------------------
     311             : // Declarations for use in both the preparser and the rest of V8.
     312             : 
     313             : // The Strict Mode (ECMA-262 5th edition, 4.2.2).
     314             : 
     315             : enum class LanguageMode : bool { kSloppy, kStrict };
     316             : static const size_t LanguageModeSize = 2;
     317             : 
     318           0 : inline size_t hash_value(LanguageMode mode) {
     319           0 :   return static_cast<size_t>(mode);
     320             : }
     321             : 
     322           0 : inline std::ostream& operator<<(std::ostream& os, const LanguageMode& mode) {
     323           0 :   switch (mode) {
     324             :     case LanguageMode::kSloppy:
     325           0 :       return os << "sloppy";
     326             :     case LanguageMode::kStrict:
     327           0 :       return os << "strict";
     328             :   }
     329             :   UNREACHABLE();
     330             : }
     331             : 
     332      634477 : inline bool is_sloppy(LanguageMode language_mode) {
     333     1170243 :   return language_mode == LanguageMode::kSloppy;
     334             : }
     335             : 
     336             : inline bool is_strict(LanguageMode language_mode) {
     337             :   return language_mode != LanguageMode::kSloppy;
     338             : }
     339             : 
     340    12403897 : inline bool is_valid_language_mode(int language_mode) {
     341    12403897 :   return language_mode == static_cast<int>(LanguageMode::kSloppy) ||
     342    12403897 :          language_mode == static_cast<int>(LanguageMode::kStrict);
     343             : }
     344             : 
     345             : inline LanguageMode construct_language_mode(bool strict_bit) {
     346             :   return static_cast<LanguageMode>(strict_bit);
     347             : }
     348             : 
     349             : // Return kStrict if either of the language modes is kStrict, or kSloppy
     350             : // otherwise.
     351             : inline LanguageMode stricter_language_mode(LanguageMode mode1,
     352             :                                            LanguageMode mode2) {
     353             :   STATIC_ASSERT(LanguageModeSize == 2);
     354             :   return static_cast<LanguageMode>(static_cast<int>(mode1) |
     355      145133 :                                    static_cast<int>(mode2));
     356             : }
     357             : 
     358             : enum TypeofMode : int { INSIDE_TYPEOF, NOT_INSIDE_TYPEOF };
     359             : 
     360             : // This constant is used as an undefined value when passing source positions.
     361             : const int kNoSourcePosition = -1;
     362             : 
     363             : // This constant is used to indicate missing deoptimization information.
     364             : const int kNoDeoptimizationId = -1;
     365             : 
     366             : // Deoptimize bailout kind.
     367             : enum class DeoptimizeKind : uint8_t { kEager, kSoft, kLazy };
     368           0 : inline size_t hash_value(DeoptimizeKind kind) {
     369           0 :   return static_cast<size_t>(kind);
     370             : }
     371           0 : inline std::ostream& operator<<(std::ostream& os, DeoptimizeKind kind) {
     372           0 :   switch (kind) {
     373             :     case DeoptimizeKind::kEager:
     374           0 :       return os << "Eager";
     375             :     case DeoptimizeKind::kSoft:
     376           0 :       return os << "Soft";
     377             :     case DeoptimizeKind::kLazy:
     378           0 :       return os << "Lazy";
     379             :   }
     380           0 :   UNREACHABLE();
     381             : }
     382             : 
     383             : // Indicates whether the lookup is related to sloppy-mode block-scoped
     384             : // function hoisting, and is a synthetic assignment for that.
     385             : enum class LookupHoistingMode { kNormal, kLegacySloppy };
     386             : 
     387             : inline std::ostream& operator<<(std::ostream& os,
     388             :                                 const LookupHoistingMode& mode) {
     389             :   switch (mode) {
     390             :     case LookupHoistingMode::kNormal:
     391             :       return os << "normal hoisting";
     392             :     case LookupHoistingMode::kLegacySloppy:
     393             :       return os << "legacy sloppy hoisting";
     394             :   }
     395             :   UNREACHABLE();
     396             : }
     397             : 
     398             : // Mask for the sign bit in a smi.
     399             : const intptr_t kSmiSignMask = kIntptrSignBit;
     400             : 
     401             : const int kObjectAlignmentBits = kPointerSizeLog2;
     402             : const intptr_t kObjectAlignment = 1 << kObjectAlignmentBits;
     403             : const intptr_t kObjectAlignmentMask = kObjectAlignment - 1;
     404             : 
     405             : // Desired alignment for pointers.
     406             : const intptr_t kPointerAlignment = (1 << kPointerSizeLog2);
     407             : const intptr_t kPointerAlignmentMask = kPointerAlignment - 1;
     408             : 
     409             : // Desired alignment for double values.
     410             : const intptr_t kDoubleAlignment = 8;
     411             : const intptr_t kDoubleAlignmentMask = kDoubleAlignment - 1;
     412             : 
     413             : // Desired alignment for generated code is 32 bytes (to improve cache line
     414             : // utilization).
     415             : const int kCodeAlignmentBits = 5;
     416             : const intptr_t kCodeAlignment = 1 << kCodeAlignmentBits;
     417             : const intptr_t kCodeAlignmentMask = kCodeAlignment - 1;
     418             : 
     419             : // The owner field of a page is tagged with the page header tag. We need that
     420             : // to find out if a slot is part of a large object. If we mask out the lower
     421             : // 0xfffff bits (1M pages), go to the owner offset, and see that this field
     422             : // is tagged with the page header tag, we can just look up the owner.
     423             : // Otherwise, we know that we are somewhere (not within the first 1M) in a
     424             : // large object.
     425             : const int kPageHeaderTag = 3;
     426             : const int kPageHeaderTagSize = 2;
     427             : const intptr_t kPageHeaderTagMask = (1 << kPageHeaderTagSize) - 1;
     428             : 
     429             : 
     430             : // Zap-value: The value used for zapping dead objects.
     431             : // Should be a recognizable hex value tagged as a failure.
     432             : #ifdef V8_HOST_ARCH_64_BIT
     433             : const Address kZapValue =
     434             :     reinterpret_cast<Address>(V8_UINT64_C(0xdeadbeedbeadbeef));
     435             : const Address kHandleZapValue =
     436             :     reinterpret_cast<Address>(V8_UINT64_C(0x1baddead0baddeaf));
     437             : const Address kGlobalHandleZapValue =
     438             :     reinterpret_cast<Address>(V8_UINT64_C(0x1baffed00baffedf));
     439             : const Address kFromSpaceZapValue =
     440             :     reinterpret_cast<Address>(V8_UINT64_C(0x1beefdad0beefdaf));
     441             : const uint64_t kDebugZapValue = V8_UINT64_C(0xbadbaddbbadbaddb);
     442             : const uint64_t kSlotsZapValue = V8_UINT64_C(0xbeefdeadbeefdeef);
     443             : const uint64_t kFreeListZapValue = 0xfeed1eaffeed1eaf;
     444             : #else
     445             : const Address kZapValue = reinterpret_cast<Address>(0xdeadbeef);
     446             : const Address kHandleZapValue = reinterpret_cast<Address>(0xbaddeaf);
     447             : const Address kGlobalHandleZapValue = reinterpret_cast<Address>(0xbaffedf);
     448             : const Address kFromSpaceZapValue = reinterpret_cast<Address>(0xbeefdaf);
     449             : const uint32_t kSlotsZapValue = 0xbeefdeef;
     450             : const uint32_t kDebugZapValue = 0xbadbaddb;
     451             : const uint32_t kFreeListZapValue = 0xfeed1eaf;
     452             : #endif
     453             : 
     454             : const int kCodeZapValue = 0xbadc0de;
     455             : const uint32_t kPhantomReferenceZap = 0xca11bac;
     456             : 
     457             : // On Intel architecture, cache line size is 64 bytes.
     458             : // On ARM it may be less (32 bytes), but as far this constant is
     459             : // used for aligning data, it doesn't hurt to align on a greater value.
     460             : #define PROCESSOR_CACHE_LINE_SIZE 64
     461             : 
     462             : // Constants relevant to double precision floating point numbers.
     463             : // If looking only at the top 32 bits, the QNaN mask is bits 19 to 30.
     464             : const uint32_t kQuietNaNHighBitsMask = 0xfff << (51 - 32);
     465             : 
     466             : 
     467             : // -----------------------------------------------------------------------------
     468             : // Forward declarations for frequently used classes
     469             : 
     470             : class AccessorInfo;
     471             : class Allocation;
     472             : class Arguments;
     473             : class Assembler;
     474             : class Code;
     475             : class CodeGenerator;
     476             : class CodeStub;
     477             : class Context;
     478             : class Debug;
     479             : class DebugInfo;
     480             : class Descriptor;
     481             : class DescriptorArray;
     482             : class TransitionArray;
     483             : class ExternalReference;
     484             : class FixedArray;
     485             : class FunctionTemplateInfo;
     486             : class MemoryChunk;
     487             : class SeededNumberDictionary;
     488             : class UnseededNumberDictionary;
     489             : class NameDictionary;
     490             : class GlobalDictionary;
     491             : template <typename T> class MaybeHandle;
     492             : template <typename T> class Handle;
     493             : class Heap;
     494             : class HeapObject;
     495             : class IC;
     496             : class InterceptorInfo;
     497             : class Isolate;
     498             : class JSReceiver;
     499             : class JSArray;
     500             : class JSFunction;
     501             : class JSObject;
     502             : class LargeObjectSpace;
     503             : class MacroAssembler;
     504             : class Map;
     505             : class MapSpace;
     506             : class MarkCompactCollector;
     507             : class NewSpace;
     508             : class Object;
     509             : class OldSpace;
     510             : class ParameterCount;
     511             : class Foreign;
     512             : class Scope;
     513             : class DeclarationScope;
     514             : class ModuleScope;
     515             : class ScopeInfo;
     516             : class Script;
     517             : class Smi;
     518             : template <typename Config, class Allocator = FreeStoreAllocationPolicy>
     519             : class SplayTree;
     520             : class String;
     521             : class Symbol;
     522             : class Name;
     523             : class Struct;
     524             : class FeedbackVector;
     525             : class Variable;
     526             : class RelocInfo;
     527             : class MessageLocation;
     528             : 
     529             : typedef bool (*WeakSlotCallback)(Object** pointer);
     530             : 
     531             : typedef bool (*WeakSlotCallbackWithHeap)(Heap* heap, Object** pointer);
     532             : 
     533             : // -----------------------------------------------------------------------------
     534             : // Miscellaneous
     535             : 
     536             : // NOTE: SpaceIterator depends on AllocationSpace enumeration values being
     537             : // consecutive.
     538             : // Keep this enum in sync with the ObjectSpace enum in v8.h
     539             : enum AllocationSpace {
     540             :   NEW_SPACE,   // Semispaces collected with copying collector.
     541             :   OLD_SPACE,   // May contain pointers to new space.
     542             :   CODE_SPACE,  // No pointers to new space, marked executable.
     543             :   MAP_SPACE,   // Only and all map objects.
     544             :   LO_SPACE,    // Promoted large objects.
     545             : 
     546             :   FIRST_SPACE = NEW_SPACE,
     547             :   LAST_SPACE = LO_SPACE,
     548             :   FIRST_PAGED_SPACE = OLD_SPACE,
     549             :   LAST_PAGED_SPACE = MAP_SPACE
     550             : };
     551             : const int kSpaceTagSize = 3;
     552             : const int kSpaceTagMask = (1 << kSpaceTagSize) - 1;
     553             : 
     554             : enum AllocationAlignment { kWordAligned, kDoubleAligned, kDoubleUnaligned };
     555             : 
     556             : enum class AccessMode { ATOMIC, NON_ATOMIC };
     557             : 
     558             : // Possible outcomes for decisions.
     559             : enum class Decision : uint8_t { kUnknown, kTrue, kFalse };
     560             : 
     561             : inline size_t hash_value(Decision decision) {
     562             :   return static_cast<uint8_t>(decision);
     563             : }
     564             : 
     565             : inline std::ostream& operator<<(std::ostream& os, Decision decision) {
     566             :   switch (decision) {
     567             :     case Decision::kUnknown:
     568             :       return os << "Unknown";
     569             :     case Decision::kTrue:
     570             :       return os << "True";
     571             :     case Decision::kFalse:
     572             :       return os << "False";
     573             :   }
     574             :   UNREACHABLE();
     575             : }
     576             : 
     577             : // Supported write barrier modes.
     578             : enum WriteBarrierKind : uint8_t {
     579             :   kNoWriteBarrier,
     580             :   kMapWriteBarrier,
     581             :   kPointerWriteBarrier,
     582             :   kFullWriteBarrier
     583             : };
     584             : 
     585           0 : inline size_t hash_value(WriteBarrierKind kind) {
     586           0 :   return static_cast<uint8_t>(kind);
     587             : }
     588             : 
     589      415698 : inline std::ostream& operator<<(std::ostream& os, WriteBarrierKind kind) {
     590      415698 :   switch (kind) {
     591             :     case kNoWriteBarrier:
     592      263100 :       return os << "NoWriteBarrier";
     593             :     case kMapWriteBarrier:
     594           0 :       return os << "MapWriteBarrier";
     595             :     case kPointerWriteBarrier:
     596           0 :       return os << "PointerWriteBarrier";
     597             :     case kFullWriteBarrier:
     598      152598 :       return os << "FullWriteBarrier";
     599             :   }
     600           0 :   UNREACHABLE();
     601             : }
     602             : 
     603             : // A flag that indicates whether objects should be pretenured when
     604             : // allocated (allocated directly into the old generation) or not
     605             : // (allocated in the young generation if the object size and type
     606             : // allows).
     607             : enum PretenureFlag { NOT_TENURED, TENURED };
     608             : 
     609          93 : inline std::ostream& operator<<(std::ostream& os, const PretenureFlag& flag) {
     610          93 :   switch (flag) {
     611             :     case NOT_TENURED:
     612          93 :       return os << "NotTenured";
     613             :     case TENURED:
     614           0 :       return os << "Tenured";
     615             :   }
     616           0 :   UNREACHABLE();
     617             : }
     618             : 
     619             : enum MinimumCapacity {
     620             :   USE_DEFAULT_MINIMUM_CAPACITY,
     621             :   USE_CUSTOM_MINIMUM_CAPACITY
     622             : };
     623             : 
     624             : enum GarbageCollector { SCAVENGER, MARK_COMPACTOR, MINOR_MARK_COMPACTOR };
     625             : 
     626             : enum Executability { NOT_EXECUTABLE, EXECUTABLE };
     627             : 
     628             : enum VisitMode {
     629             :   VISIT_ALL,
     630             :   VISIT_ALL_IN_MINOR_MC_MARK,
     631             :   VISIT_ALL_IN_MINOR_MC_UPDATE,
     632             :   VISIT_ALL_IN_SCAVENGE,
     633             :   VISIT_ALL_IN_SWEEP_NEWSPACE,
     634             :   VISIT_ONLY_STRONG,
     635             :   VISIT_ONLY_STRONG_FOR_SERIALIZATION,
     636             :   VISIT_ONLY_STRONG_ROOT_LIST,
     637             : };
     638             : 
     639             : // Flag indicating whether code is built into the VM (one of the natives files).
     640             : enum NativesFlag {
     641             :   NOT_NATIVES_CODE,
     642             :   EXTENSION_CODE,
     643             :   NATIVES_CODE,
     644             :   INSPECTOR_CODE
     645             : };
     646             : 
     647             : // JavaScript defines two kinds of 'nil'.
     648             : enum NilValue { kNullValue, kUndefinedValue };
     649             : 
     650             : // ParseRestriction is used to restrict the set of valid statements in a
     651             : // unit of compilation.  Restriction violations cause a syntax error.
     652             : enum ParseRestriction {
     653             :   NO_PARSE_RESTRICTION,         // All expressions are allowed.
     654             :   ONLY_SINGLE_FUNCTION_LITERAL  // Only a single FunctionLiteral expression.
     655             : };
     656             : 
     657             : // A CodeDesc describes a buffer holding instructions and relocation
     658             : // information. The instructions start at the beginning of the buffer
     659             : // and grow forward, the relocation information starts at the end of
     660             : // the buffer and grows backward.  A constant pool may exist at the
     661             : // end of the instructions.
     662             : //
     663             : //  |<--------------- buffer_size ----------------------------------->|
     664             : //  |<------------- instr_size ---------->|        |<-- reloc_size -->|
     665             : //  |               |<- const_pool_size ->|                           |
     666             : //  +=====================================+========+==================+
     667             : //  |  instructions |        data         |  free  |    reloc info    |
     668             : //  +=====================================+========+==================+
     669             : //  ^
     670             : //  |
     671             : //  buffer
     672             : 
     673             : struct CodeDesc {
     674             :   byte* buffer;
     675             :   int buffer_size;
     676             :   int instr_size;
     677             :   int reloc_size;
     678             :   int constant_pool_size;
     679             :   byte* unwinding_info;
     680             :   int unwinding_info_size;
     681             :   Assembler* origin;
     682             : };
     683             : 
     684             : 
     685             : // Callback function used for checking constraints when copying/relocating
     686             : // objects. Returns true if an object can be copied/relocated from its
     687             : // old_addr to a new_addr.
     688             : typedef bool (*ConstraintCallback)(Address new_addr, Address old_addr);
     689             : 
     690             : 
     691             : // Callback function on inline caches, used for iterating over inline caches
     692             : // in compiled code.
     693             : typedef void (*InlineCacheCallback)(Code* code, Address ic);
     694             : 
     695             : 
     696             : // State for inline cache call sites. Aliased as IC::State.
     697             : enum InlineCacheState {
     698             :   // Has never been executed.
     699             :   UNINITIALIZED,
     700             :   // Has been executed but monomorhic state has been delayed.
     701             :   PREMONOMORPHIC,
     702             :   // Has been executed and only one receiver type has been seen.
     703             :   MONOMORPHIC,
     704             :   // Check failed due to prototype (or map deprecation).
     705             :   RECOMPUTE_HANDLER,
     706             :   // Multiple receiver types have been seen.
     707             :   POLYMORPHIC,
     708             :   // Many receiver types have been seen.
     709             :   MEGAMORPHIC,
     710             :   // A generic handler is installed and no extra typefeedback is recorded.
     711             :   GENERIC,
     712             : };
     713             : 
     714             : enum WhereToStart { kStartAtReceiver, kStartAtPrototype };
     715             : 
     716             : enum ResultSentinel { kNotFound = -1, kUnsupported = -2 };
     717             : 
     718             : // The Store Buffer (GC).
     719             : typedef enum {
     720             :   kStoreBufferFullEvent,
     721             :   kStoreBufferStartScanningPagesEvent,
     722             :   kStoreBufferScanningPageEvent
     723             : } StoreBufferEvent;
     724             : 
     725             : 
     726             : typedef void (*StoreBufferCallback)(Heap* heap,
     727             :                                     MemoryChunk* page,
     728             :                                     StoreBufferEvent event);
     729             : 
     730             : // Union used for customized checking of the IEEE double types
     731             : // inlined within v8 runtime, rather than going to the underlying
     732             : // platform headers and libraries
     733             : union IeeeDoubleLittleEndianArchType {
     734             :   double d;
     735             :   struct {
     736             :     unsigned int man_low  :32;
     737             :     unsigned int man_high :20;
     738             :     unsigned int exp      :11;
     739             :     unsigned int sign     :1;
     740             :   } bits;
     741             : };
     742             : 
     743             : 
     744             : union IeeeDoubleBigEndianArchType {
     745             :   double d;
     746             :   struct {
     747             :     unsigned int sign     :1;
     748             :     unsigned int exp      :11;
     749             :     unsigned int man_high :20;
     750             :     unsigned int man_low  :32;
     751             :   } bits;
     752             : };
     753             : 
     754             : #if V8_TARGET_LITTLE_ENDIAN
     755             : typedef IeeeDoubleLittleEndianArchType IeeeDoubleArchType;
     756             : const int kIeeeDoubleMantissaWordOffset = 0;
     757             : const int kIeeeDoubleExponentWordOffset = 4;
     758             : #else
     759             : typedef IeeeDoubleBigEndianArchType IeeeDoubleArchType;
     760             : const int kIeeeDoubleMantissaWordOffset = 4;
     761             : const int kIeeeDoubleExponentWordOffset = 0;
     762             : #endif
     763             : 
     764             : // AccessorCallback
     765             : struct AccessorDescriptor {
     766             :   Object* (*getter)(Isolate* isolate, Object* object, void* data);
     767             :   Object* (*setter)(
     768             :       Isolate* isolate, JSObject* object, Object* value, void* data);
     769             :   void* data;
     770             : };
     771             : 
     772             : 
     773             : // -----------------------------------------------------------------------------
     774             : // Macros
     775             : 
     776             : // Testers for test.
     777             : 
     778             : #define HAS_SMI_TAG(value) \
     779             :   ((reinterpret_cast<intptr_t>(value) & ::i::kSmiTagMask) == ::i::kSmiTag)
     780             : 
     781             : #define HAS_HEAP_OBJECT_TAG(value)                                   \
     782             :   (((reinterpret_cast<intptr_t>(value) & ::i::kHeapObjectTagMask) == \
     783             :     ::i::kHeapObjectTag))
     784             : 
     785             : // OBJECT_POINTER_ALIGN returns the value aligned as a HeapObject pointer
     786             : #define OBJECT_POINTER_ALIGN(value)                             \
     787             :   (((value) + kObjectAlignmentMask) & ~kObjectAlignmentMask)
     788             : 
     789             : // POINTER_SIZE_ALIGN returns the value aligned as a pointer.
     790             : #define POINTER_SIZE_ALIGN(value)                               \
     791             :   (((value) + kPointerAlignmentMask) & ~kPointerAlignmentMask)
     792             : 
     793             : // CODE_POINTER_ALIGN returns the value aligned as a generated code segment.
     794             : #define CODE_POINTER_ALIGN(value)                               \
     795             :   (((value) + kCodeAlignmentMask) & ~kCodeAlignmentMask)
     796             : 
     797             : // DOUBLE_POINTER_ALIGN returns the value algined for double pointers.
     798             : #define DOUBLE_POINTER_ALIGN(value) \
     799             :   (((value) + kDoubleAlignmentMask) & ~kDoubleAlignmentMask)
     800             : 
     801             : 
     802             : // CPU feature flags.
     803             : enum CpuFeature {
     804             :   // x86
     805             :   SSE4_1,
     806             :   SSSE3,
     807             :   SSE3,
     808             :   SAHF,
     809             :   AVX,
     810             :   FMA3,
     811             :   BMI1,
     812             :   BMI2,
     813             :   LZCNT,
     814             :   POPCNT,
     815             :   ATOM,
     816             :   // ARM
     817             :   // - Standard configurations. The baseline is ARMv6+VFPv2.
     818             :   ARMv7,        // ARMv7-A + VFPv3-D32 + NEON
     819             :   ARMv7_SUDIV,  // ARMv7-A + VFPv4-D32 + NEON + SUDIV
     820             :   ARMv8,        // ARMv8-A (+ all of the above)
     821             :   // MIPS, MIPS64
     822             :   FPU,
     823             :   FP64FPU,
     824             :   MIPSr1,
     825             :   MIPSr2,
     826             :   MIPSr6,
     827             :   MIPS_SIMD,  // MSA instructions
     828             :   // ARM64
     829             :   ALWAYS_ALIGN_CSP,
     830             :   // PPC
     831             :   FPR_GPR_MOV,
     832             :   LWSYNC,
     833             :   ISELECT,
     834             :   VSX,
     835             :   MODULO,
     836             :   // S390
     837             :   DISTINCT_OPS,
     838             :   GENERAL_INSTR_EXT,
     839             :   FLOATING_POINT_EXT,
     840             :   VECTOR_FACILITY,
     841             :   MISC_INSTR_EXT2,
     842             : 
     843             :   NUMBER_OF_CPU_FEATURES,
     844             : 
     845             :   // ARM feature aliases (based on the standard configurations above).
     846             :   VFPv3 = ARMv7,
     847             :   NEON = ARMv7,
     848             :   VFP32DREGS = ARMv7,
     849             :   SUDIV = ARMv7_SUDIV
     850             : };
     851             : 
     852             : // Defines hints about receiver values based on structural knowledge.
     853             : enum class ConvertReceiverMode : unsigned {
     854             :   kNullOrUndefined,     // Guaranteed to be null or undefined.
     855             :   kNotNullOrUndefined,  // Guaranteed to never be null or undefined.
     856             :   kAny                  // No specific knowledge about receiver.
     857             : };
     858             : 
     859           0 : inline size_t hash_value(ConvertReceiverMode mode) {
     860           0 :   return bit_cast<unsigned>(mode);
     861             : }
     862             : 
     863           0 : inline std::ostream& operator<<(std::ostream& os, ConvertReceiverMode mode) {
     864           0 :   switch (mode) {
     865             :     case ConvertReceiverMode::kNullOrUndefined:
     866           0 :       return os << "NULL_OR_UNDEFINED";
     867             :     case ConvertReceiverMode::kNotNullOrUndefined:
     868           0 :       return os << "NOT_NULL_OR_UNDEFINED";
     869             :     case ConvertReceiverMode::kAny:
     870           0 :       return os << "ANY";
     871             :   }
     872           0 :   UNREACHABLE();
     873             : }
     874             : 
     875             : // Valid hints for the abstract operation OrdinaryToPrimitive,
     876             : // implemented according to ES6, section 7.1.1.
     877             : enum class OrdinaryToPrimitiveHint { kNumber, kString };
     878             : 
     879             : // Valid hints for the abstract operation ToPrimitive,
     880             : // implemented according to ES6, section 7.1.1.
     881             : enum class ToPrimitiveHint { kDefault, kNumber, kString };
     882             : 
     883             : // Defines specifics about arguments object or rest parameter creation.
     884             : enum class CreateArgumentsType : uint8_t {
     885             :   kMappedArguments,
     886             :   kUnmappedArguments,
     887             :   kRestParameter
     888             : };
     889             : 
     890        6237 : inline size_t hash_value(CreateArgumentsType type) {
     891        6237 :   return bit_cast<uint8_t>(type);
     892             : }
     893             : 
     894           0 : inline std::ostream& operator<<(std::ostream& os, CreateArgumentsType type) {
     895           0 :   switch (type) {
     896             :     case CreateArgumentsType::kMappedArguments:
     897           0 :       return os << "MAPPED_ARGUMENTS";
     898             :     case CreateArgumentsType::kUnmappedArguments:
     899           0 :       return os << "UNMAPPED_ARGUMENTS";
     900             :     case CreateArgumentsType::kRestParameter:
     901           0 :       return os << "REST_PARAMETER";
     902             :   }
     903           0 :   UNREACHABLE();
     904             : }
     905             : 
     906             : // Used to specify if a macro instruction must perform a smi check on tagged
     907             : // values.
     908             : enum SmiCheckType {
     909             :   DONT_DO_SMI_CHECK,
     910             :   DO_SMI_CHECK
     911             : };
     912             : 
     913             : enum ScopeType : uint8_t {
     914             :   EVAL_SCOPE,      // The top-level scope for an eval source.
     915             :   FUNCTION_SCOPE,  // The top-level scope for a function.
     916             :   MODULE_SCOPE,    // The scope introduced by a module literal
     917             :   SCRIPT_SCOPE,    // The top-level scope for a script or a top-level eval.
     918             :   CATCH_SCOPE,     // The scope introduced by catch.
     919             :   BLOCK_SCOPE,     // The scope introduced by a new block.
     920             :   WITH_SCOPE       // The scope introduced by with.
     921             : };
     922             : 
     923             : // AllocationSiteMode controls whether allocations are tracked by an allocation
     924             : // site.
     925             : enum AllocationSiteMode {
     926             :   DONT_TRACK_ALLOCATION_SITE,
     927             :   TRACK_ALLOCATION_SITE,
     928             :   LAST_ALLOCATION_SITE_MODE = TRACK_ALLOCATION_SITE
     929             : };
     930             : 
     931             : // The mips architecture prior to revision 5 has inverted encoding for sNaN.
     932             : #if (V8_TARGET_ARCH_MIPS && !defined(_MIPS_ARCH_MIPS32R6) &&           \
     933             :      (!defined(USE_SIMULATOR) || !defined(_MIPS_TARGET_SIMULATOR))) || \
     934             :     (V8_TARGET_ARCH_MIPS64 && !defined(_MIPS_ARCH_MIPS64R6) &&         \
     935             :      (!defined(USE_SIMULATOR) || !defined(_MIPS_TARGET_SIMULATOR)))
     936             : const uint32_t kHoleNanUpper32 = 0xFFFF7FFF;
     937             : const uint32_t kHoleNanLower32 = 0xFFFF7FFF;
     938             : #else
     939             : const uint32_t kHoleNanUpper32 = 0xFFF7FFFF;
     940             : const uint32_t kHoleNanLower32 = 0xFFF7FFFF;
     941             : #endif
     942             : 
     943             : const uint64_t kHoleNanInt64 =
     944             :     (static_cast<uint64_t>(kHoleNanUpper32) << 32) | kHoleNanLower32;
     945             : 
     946             : 
     947             : // ES6 section 20.1.2.6 Number.MAX_SAFE_INTEGER
     948             : const double kMaxSafeInteger = 9007199254740991.0;  // 2^53-1
     949             : 
     950             : 
     951             : // The order of this enum has to be kept in sync with the predicates below.
     952             : enum VariableMode : uint8_t {
     953             :   // User declared variables:
     954             :   LET,  // declared via 'let' declarations (first lexical)
     955             : 
     956             :   CONST,  // declared via 'const' declarations (last lexical)
     957             : 
     958             :   VAR,  // declared via 'var', and 'function' declarations
     959             : 
     960             :   // Variables introduced by the compiler:
     961             :   TEMPORARY,  // temporary variables (not user-visible), stack-allocated
     962             :               // unless the scope as a whole has forced context allocation
     963             : 
     964             :   DYNAMIC,  // always require dynamic lookup (we don't know
     965             :             // the declaration)
     966             : 
     967             :   DYNAMIC_GLOBAL,  // requires dynamic lookup, but we know that the
     968             :                    // variable is global unless it has been shadowed
     969             :                    // by an eval-introduced variable
     970             : 
     971             :   DYNAMIC_LOCAL  // requires dynamic lookup, but we know that the
     972             :                  // variable is local and where it is unless it
     973             :                  // has been shadowed by an eval-introduced
     974             :                  // variable
     975             : };
     976             : 
     977             : // Printing support
     978             : #ifdef DEBUG
     979             : inline const char* VariableMode2String(VariableMode mode) {
     980             :   switch (mode) {
     981             :     case VAR:
     982             :       return "VAR";
     983             :     case LET:
     984             :       return "LET";
     985             :     case CONST:
     986             :       return "CONST";
     987             :     case DYNAMIC:
     988             :       return "DYNAMIC";
     989             :     case DYNAMIC_GLOBAL:
     990             :       return "DYNAMIC_GLOBAL";
     991             :     case DYNAMIC_LOCAL:
     992             :       return "DYNAMIC_LOCAL";
     993             :     case TEMPORARY:
     994             :       return "TEMPORARY";
     995             :   }
     996             :   UNREACHABLE();
     997             : }
     998             : #endif
     999             : 
    1000             : enum VariableKind : uint8_t {
    1001             :   NORMAL_VARIABLE,
    1002             :   FUNCTION_VARIABLE,
    1003             :   THIS_VARIABLE,
    1004             :   SLOPPY_FUNCTION_NAME_VARIABLE
    1005             : };
    1006             : 
    1007             : inline bool IsDynamicVariableMode(VariableMode mode) {
    1008    54444534 :   return mode >= DYNAMIC && mode <= DYNAMIC_LOCAL;
    1009             : }
    1010             : 
    1011             : 
    1012             : inline bool IsDeclaredVariableMode(VariableMode mode) {
    1013             :   STATIC_ASSERT(LET == 0);  // Implies that mode >= LET.
    1014             :   return mode <= VAR;
    1015             : }
    1016             : 
    1017             : 
    1018      117890 : inline bool IsLexicalVariableMode(VariableMode mode) {
    1019             :   STATIC_ASSERT(LET == 0);  // Implies that mode >= LET.
    1020      122070 :   return mode <= CONST;
    1021             : }
    1022             : 
    1023             : enum VariableLocation : uint8_t {
    1024             :   // Before and during variable allocation, a variable whose location is
    1025             :   // not yet determined.  After allocation, a variable looked up as a
    1026             :   // property on the global object (and possibly absent).  name() is the
    1027             :   // variable name, index() is invalid.
    1028             :   UNALLOCATED,
    1029             : 
    1030             :   // A slot in the parameter section on the stack.  index() is the
    1031             :   // parameter index, counting left-to-right.  The receiver is index -1;
    1032             :   // the first parameter is index 0.
    1033             :   PARAMETER,
    1034             : 
    1035             :   // A slot in the local section on the stack.  index() is the variable
    1036             :   // index in the stack frame, starting at 0.
    1037             :   LOCAL,
    1038             : 
    1039             :   // An indexed slot in a heap context.  index() is the variable index in
    1040             :   // the context object on the heap, starting at 0.  scope() is the
    1041             :   // corresponding scope.
    1042             :   CONTEXT,
    1043             : 
    1044             :   // A named slot in a heap context.  name() is the variable name in the
    1045             :   // context object on the heap, with lookup starting at the current
    1046             :   // context.  index() is invalid.
    1047             :   LOOKUP,
    1048             : 
    1049             :   // A named slot in a module's export table.
    1050             :   MODULE,
    1051             : 
    1052             :   kLastVariableLocation = MODULE
    1053             : };
    1054             : 
    1055             : // ES6 specifies declarative environment records with mutable and immutable
    1056             : // bindings that can be in two states: initialized and uninitialized.
    1057             : // When accessing a binding, it needs to be checked for initialization.
    1058             : // However in the following cases the binding is initialized immediately
    1059             : // after creation so the initialization check can always be skipped:
    1060             : //
    1061             : // 1. Var declared local variables.
    1062             : //      var foo;
    1063             : // 2. A local variable introduced by a function declaration.
    1064             : //      function foo() {}
    1065             : // 3. Parameters
    1066             : //      function x(foo) {}
    1067             : // 4. Catch bound variables.
    1068             : //      try {} catch (foo) {}
    1069             : // 6. Function name variables of named function expressions.
    1070             : //      var x = function foo() {}
    1071             : // 7. Implicit binding of 'this'.
    1072             : // 8. Implicit binding of 'arguments' in functions.
    1073             : //
    1074             : // The following enum specifies a flag that indicates if the binding needs a
    1075             : // distinct initialization step (kNeedsInitialization) or if the binding is
    1076             : // immediately initialized upon creation (kCreatedInitialized).
    1077             : enum InitializationFlag : uint8_t { kNeedsInitialization, kCreatedInitialized };
    1078             : 
    1079             : enum class HoleCheckMode { kRequired, kElided };
    1080             : 
    1081             : enum MaybeAssignedFlag : uint8_t { kNotAssigned, kMaybeAssigned };
    1082             : 
    1083             : // Serialized in PreparseData, so numeric values should not be changed.
    1084             : enum ParseErrorType { kSyntaxError = 0, kReferenceError = 1 };
    1085             : 
    1086             : 
    1087             : enum MinusZeroMode {
    1088             :   TREAT_MINUS_ZERO_AS_ZERO,
    1089             :   FAIL_ON_MINUS_ZERO
    1090             : };
    1091             : 
    1092             : 
    1093             : enum Signedness { kSigned, kUnsigned };
    1094             : 
    1095             : enum FunctionKind : uint16_t {
    1096             :   kNormalFunction = 0,
    1097             :   kArrowFunction = 1 << 0,
    1098             :   kGeneratorFunction = 1 << 1,
    1099             :   kConciseMethod = 1 << 2,
    1100             :   kConciseGeneratorMethod = kGeneratorFunction | kConciseMethod,
    1101             :   kDefaultConstructor = 1 << 3,
    1102             :   kDerivedConstructor = 1 << 4,
    1103             :   kBaseConstructor = 1 << 5,
    1104             :   kGetterFunction = 1 << 6,
    1105             :   kSetterFunction = 1 << 7,
    1106             :   kAsyncFunction = 1 << 8,
    1107             :   kModule = 1 << 9,
    1108             :   kAccessorFunction = kGetterFunction | kSetterFunction,
    1109             :   kDefaultBaseConstructor = kDefaultConstructor | kBaseConstructor,
    1110             :   kDefaultDerivedConstructor = kDefaultConstructor | kDerivedConstructor,
    1111             :   kClassConstructor =
    1112             :       kBaseConstructor | kDerivedConstructor | kDefaultConstructor,
    1113             :   kAsyncArrowFunction = kArrowFunction | kAsyncFunction,
    1114             :   kAsyncConciseMethod = kAsyncFunction | kConciseMethod,
    1115             : 
    1116             :   // https://tc39.github.io/proposal-async-iteration/
    1117             :   kAsyncConciseGeneratorMethod = kAsyncFunction | kConciseGeneratorMethod,
    1118             :   kAsyncGeneratorFunction = kAsyncFunction | kGeneratorFunction
    1119             : };
    1120             : 
    1121             : inline bool IsValidFunctionKind(FunctionKind kind) {
    1122             :   return kind == FunctionKind::kNormalFunction ||
    1123             :          kind == FunctionKind::kArrowFunction ||
    1124             :          kind == FunctionKind::kGeneratorFunction ||
    1125             :          kind == FunctionKind::kModule ||
    1126             :          kind == FunctionKind::kConciseMethod ||
    1127             :          kind == FunctionKind::kConciseGeneratorMethod ||
    1128             :          kind == FunctionKind::kGetterFunction ||
    1129             :          kind == FunctionKind::kSetterFunction ||
    1130             :          kind == FunctionKind::kAccessorFunction ||
    1131             :          kind == FunctionKind::kDefaultBaseConstructor ||
    1132             :          kind == FunctionKind::kDefaultDerivedConstructor ||
    1133             :          kind == FunctionKind::kBaseConstructor ||
    1134             :          kind == FunctionKind::kDerivedConstructor ||
    1135             :          kind == FunctionKind::kAsyncFunction ||
    1136             :          kind == FunctionKind::kAsyncArrowFunction ||
    1137             :          kind == FunctionKind::kAsyncConciseMethod ||
    1138             :          kind == FunctionKind::kAsyncConciseGeneratorMethod ||
    1139             :          kind == FunctionKind::kAsyncGeneratorFunction;
    1140             : }
    1141             : 
    1142             : 
    1143             : inline bool IsArrowFunction(FunctionKind kind) {
    1144             :   DCHECK(IsValidFunctionKind(kind));
    1145    52647251 :   return (kind & FunctionKind::kArrowFunction) != 0;
    1146             : }
    1147             : 
    1148             : 
    1149             : inline bool IsGeneratorFunction(FunctionKind kind) {
    1150             :   DCHECK(IsValidFunctionKind(kind));
    1151    39827071 :   return (kind & FunctionKind::kGeneratorFunction) != 0;
    1152             : }
    1153             : 
    1154             : inline bool IsModule(FunctionKind kind) {
    1155             :   DCHECK(IsValidFunctionKind(kind));
    1156     4171660 :   return (kind & FunctionKind::kModule) != 0;
    1157             : }
    1158             : 
    1159             : inline bool IsAsyncFunction(FunctionKind kind) {
    1160             :   DCHECK(IsValidFunctionKind(kind));
    1161   103696705 :   return (kind & FunctionKind::kAsyncFunction) != 0;
    1162             : }
    1163             : 
    1164             : inline bool IsAsyncGeneratorFunction(FunctionKind kind) {
    1165             :   DCHECK(IsValidFunctionKind(kind));
    1166             :   const FunctionKind kMask = FunctionKind::kAsyncGeneratorFunction;
    1167     7835149 :   return (kind & kMask) == kMask;
    1168             : }
    1169             : 
    1170       11215 : inline bool IsResumableFunction(FunctionKind kind) {
    1171    12678693 :   return IsGeneratorFunction(kind) || IsAsyncFunction(kind) || IsModule(kind);
    1172             : }
    1173             : 
    1174             : inline bool IsConciseMethod(FunctionKind kind) {
    1175             :   DCHECK(IsValidFunctionKind(kind));
    1176    40377018 :   return (kind & FunctionKind::kConciseMethod) != 0;
    1177             : }
    1178             : 
    1179             : inline bool IsGetterFunction(FunctionKind kind) {
    1180             :   DCHECK(IsValidFunctionKind(kind));
    1181     5532248 :   return (kind & FunctionKind::kGetterFunction) != 0;
    1182             : }
    1183             : 
    1184             : inline bool IsSetterFunction(FunctionKind kind) {
    1185             :   DCHECK(IsValidFunctionKind(kind));
    1186     5497606 :   return (kind & FunctionKind::kSetterFunction) != 0;
    1187             : }
    1188             : 
    1189             : inline bool IsAccessorFunction(FunctionKind kind) {
    1190             :   DCHECK(IsValidFunctionKind(kind));
    1191    34473287 :   return (kind & FunctionKind::kAccessorFunction) != 0;
    1192             : }
    1193             : 
    1194             : 
    1195             : inline bool IsDefaultConstructor(FunctionKind kind) {
    1196             :   DCHECK(IsValidFunctionKind(kind));
    1197      836041 :   return (kind & FunctionKind::kDefaultConstructor) != 0;
    1198             : }
    1199             : 
    1200             : 
    1201             : inline bool IsBaseConstructor(FunctionKind kind) {
    1202             :   DCHECK(IsValidFunctionKind(kind));
    1203             :   return (kind & FunctionKind::kBaseConstructor) != 0;
    1204             : }
    1205             : 
    1206             : inline bool IsDerivedConstructor(FunctionKind kind) {
    1207             :   DCHECK(IsValidFunctionKind(kind));
    1208    12373876 :   return (kind & FunctionKind::kDerivedConstructor) != 0;
    1209             : }
    1210             : 
    1211             : 
    1212        8284 : inline bool IsClassConstructor(FunctionKind kind) {
    1213             :   DCHECK(IsValidFunctionKind(kind));
    1214    26632058 :   return (kind & FunctionKind::kClassConstructor) != 0;
    1215             : }
    1216             : 
    1217    10335659 : inline bool IsConstructable(FunctionKind kind) {
    1218    10335659 :   if (IsAccessorFunction(kind)) return false;
    1219    10308779 :   if (IsConciseMethod(kind)) return false;
    1220     9512627 :   if (IsArrowFunction(kind)) return false;
    1221     9019654 :   if (IsGeneratorFunction(kind)) return false;
    1222     9010894 :   if (IsAsyncFunction(kind)) return false;
    1223     9000392 :   return true;
    1224             : }
    1225             : 
    1226             : enum class InterpreterPushArgsMode : unsigned {
    1227             :   kJSFunction,
    1228             :   kWithFinalSpread,
    1229             :   kOther
    1230             : };
    1231             : 
    1232             : inline size_t hash_value(InterpreterPushArgsMode mode) {
    1233             :   return bit_cast<unsigned>(mode);
    1234             : }
    1235             : 
    1236             : inline std::ostream& operator<<(std::ostream& os,
    1237             :                                 InterpreterPushArgsMode mode) {
    1238             :   switch (mode) {
    1239             :     case InterpreterPushArgsMode::kJSFunction:
    1240             :       return os << "JSFunction";
    1241             :     case InterpreterPushArgsMode::kWithFinalSpread:
    1242             :       return os << "WithFinalSpread";
    1243             :     case InterpreterPushArgsMode::kOther:
    1244             :       return os << "Other";
    1245             :   }
    1246             :   UNREACHABLE();
    1247             : }
    1248             : 
    1249             : inline uint32_t ObjectHash(Address address) {
    1250             :   // All objects are at least pointer aligned, so we can remove the trailing
    1251             :   // zeros.
    1252             :   return static_cast<uint32_t>(bit_cast<uintptr_t>(address) >>
    1253             :                                kPointerSizeLog2);
    1254             : }
    1255             : 
    1256             : // Type feedback is encoded in such a way that, we can combine the feedback
    1257             : // at different points by performing an 'OR' operation. Type feedback moves
    1258             : // to a more generic type when we combine feedback.
    1259             : // kSignedSmall -> kSignedSmallInputs -> kNumber  -> kNumberOrOddball -> kAny
    1260             : //                                                   kString          -> kAny
    1261             : // kBigInt -> kAny
    1262             : // TODO(mythria): Remove kNumber type when crankshaft can handle Oddballs
    1263             : // similar to Numbers. We don't need kNumber feedback for Turbofan. Extra
    1264             : // information about Number might reduce few instructions but causes more
    1265             : // deopts. We collect Number only because crankshaft does not handle all
    1266             : // cases of oddballs.
    1267             : class BinaryOperationFeedback {
    1268             :  public:
    1269             :   enum {
    1270             :     kNone = 0x0,
    1271             :     kSignedSmall = 0x1,
    1272             :     kSignedSmallInputs = 0x3,
    1273             :     kNumber = 0x7,
    1274             :     kNumberOrOddball = 0xF,
    1275             :     kString = 0x10,
    1276             :     kBigInt = 0x20,
    1277             :     kAny = 0x7F
    1278             :   };
    1279             : };
    1280             : 
    1281             : // Type feedback is encoded in such a way that, we can combine the feedback
    1282             : // at different points by performing an 'OR' operation. Type feedback moves
    1283             : // to a more generic type when we combine feedback.
    1284             : // kSignedSmall        -> kNumber   -> kAny
    1285             : // kInternalizedString -> kString   -> kAny
    1286             : //                        kSymbol   -> kAny
    1287             : //                        kReceiver -> kAny
    1288             : // TODO(epertoso): consider unifying this with BinaryOperationFeedback.
    1289             : class CompareOperationFeedback {
    1290             :  public:
    1291             :   enum {
    1292             :     kNone = 0x00,
    1293             :     kSignedSmall = 0x01,
    1294             :     kNumber = 0x3,
    1295             :     kNumberOrOddball = 0x7,
    1296             :     kInternalizedString = 0x8,
    1297             :     kString = 0x18,
    1298             :     kSymbol = 0x20,
    1299             :     kReceiver = 0x40,
    1300             :     kAny = 0xff
    1301             :   };
    1302             : };
    1303             : 
    1304             : // Type feedback is encoded in such a way that, we can combine the feedback
    1305             : // at different points by performing an 'OR' operation. Type feedback moves
    1306             : // to a more generic type when we combine feedback.
    1307             : // kNone -> kEnumCacheKeysAndIndices -> kEnumCacheKeys -> kAny
    1308             : class ForInFeedback {
    1309             :  public:
    1310             :   enum {
    1311             :     kNone = 0x0,
    1312             :     kEnumCacheKeysAndIndices = 0x1,
    1313             :     kEnumCacheKeys = 0x3,
    1314             :     kAny = 0x7
    1315             :   };
    1316             : };
    1317             : STATIC_ASSERT((ForInFeedback::kNone |
    1318             :                ForInFeedback::kEnumCacheKeysAndIndices) ==
    1319             :               ForInFeedback::kEnumCacheKeysAndIndices);
    1320             : STATIC_ASSERT((ForInFeedback::kEnumCacheKeysAndIndices |
    1321             :                ForInFeedback::kEnumCacheKeys) == ForInFeedback::kEnumCacheKeys);
    1322             : STATIC_ASSERT((ForInFeedback::kEnumCacheKeys | ForInFeedback::kAny) ==
    1323             :               ForInFeedback::kAny);
    1324             : 
    1325             : enum class UnicodeEncoding : uint8_t {
    1326             :   // Different unicode encodings in a |word32|:
    1327             :   UTF16,  // hi 16bits -> trailing surrogate or 0, low 16bits -> lead surrogate
    1328             :   UTF32,  // full UTF32 code unit / Unicode codepoint
    1329             : };
    1330             : 
    1331          78 : inline size_t hash_value(UnicodeEncoding encoding) {
    1332          78 :   return static_cast<uint8_t>(encoding);
    1333             : }
    1334             : 
    1335           0 : inline std::ostream& operator<<(std::ostream& os, UnicodeEncoding encoding) {
    1336           0 :   switch (encoding) {
    1337             :     case UnicodeEncoding::UTF16:
    1338           0 :       return os << "UTF16";
    1339             :     case UnicodeEncoding::UTF32:
    1340           0 :       return os << "UTF32";
    1341             :   }
    1342           0 :   UNREACHABLE();
    1343             : }
    1344             : 
    1345             : enum class IterationKind { kKeys, kValues, kEntries };
    1346             : 
    1347             : inline std::ostream& operator<<(std::ostream& os, IterationKind kind) {
    1348             :   switch (kind) {
    1349             :     case IterationKind::kKeys:
    1350             :       return os << "IterationKind::kKeys";
    1351             :     case IterationKind::kValues:
    1352             :       return os << "IterationKind::kValues";
    1353             :     case IterationKind::kEntries:
    1354             :       return os << "IterationKind::kEntries";
    1355             :   }
    1356             :   UNREACHABLE();
    1357             : }
    1358             : 
    1359             : // Flags for the runtime function kDefineDataPropertyInLiteral. A property can
    1360             : // be enumerable or not, and, in case of functions, the function name
    1361             : // can be set or not.
    1362             : enum class DataPropertyInLiteralFlag {
    1363             :   kNoFlags = 0,
    1364             :   kDontEnum = 1 << 0,
    1365             :   kSetFunctionName = 1 << 1
    1366             : };
    1367             : typedef base::Flags<DataPropertyInLiteralFlag> DataPropertyInLiteralFlags;
    1368             : DEFINE_OPERATORS_FOR_FLAGS(DataPropertyInLiteralFlags)
    1369             : 
    1370             : enum ExternalArrayType {
    1371             :   kExternalInt8Array = 1,
    1372             :   kExternalUint8Array,
    1373             :   kExternalInt16Array,
    1374             :   kExternalUint16Array,
    1375             :   kExternalInt32Array,
    1376             :   kExternalUint32Array,
    1377             :   kExternalFloat32Array,
    1378             :   kExternalFloat64Array,
    1379             :   kExternalUint8ClampedArray,
    1380             : };
    1381             : 
    1382             : struct AssemblerDebugInfo {
    1383             :   AssemblerDebugInfo(const char* name, const char* file, int line)
    1384             :       : name(name), file(file), line(line) {}
    1385             :   const char* name;
    1386             :   const char* file;
    1387             :   int line;
    1388             : };
    1389             : 
    1390             : inline std::ostream& operator<<(std::ostream& os,
    1391             :                                 const AssemblerDebugInfo& info) {
    1392             :   os << "(" << info.name << ":" << info.file << ":" << info.line << ")";
    1393             :   return os;
    1394             : }
    1395             : 
    1396             : enum class OptimizationMarker {
    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::kNone:
    1407             :       return os << "OptimizationMarker::kNone";
    1408             :     case OptimizationMarker::kCompileOptimized:
    1409             :       return os << "OptimizationMarker::kCompileOptimized";
    1410             :     case OptimizationMarker::kCompileOptimizedConcurrent:
    1411             :       return os << "OptimizationMarker::kCompileOptimizedConcurrent";
    1412             :     case OptimizationMarker::kInOptimizationQueue:
    1413             :       return os << "OptimizationMarker::kInOptimizationQueue";
    1414             :   }
    1415             :   UNREACHABLE();
    1416             :   return os;
    1417             : }
    1418             : 
    1419             : enum class ConcurrencyMode { kNotConcurrent, kConcurrent };
    1420             : 
    1421             : #define FOR_EACH_ISOLATE_ADDRESS_NAME(C)                \
    1422             :   C(Handler, handler)                                   \
    1423             :   C(CEntryFP, c_entry_fp)                               \
    1424             :   C(CFunction, c_function)                              \
    1425             :   C(Context, context)                                   \
    1426             :   C(PendingException, pending_exception)                \
    1427             :   C(PendingHandlerContext, pending_handler_context)     \
    1428             :   C(PendingHandlerCode, pending_handler_code)           \
    1429             :   C(PendingHandlerOffset, pending_handler_offset)       \
    1430             :   C(PendingHandlerFP, pending_handler_fp)               \
    1431             :   C(PendingHandlerSP, pending_handler_sp)               \
    1432             :   C(ExternalCaughtException, external_caught_exception) \
    1433             :   C(JSEntrySP, js_entry_sp)
    1434             : 
    1435             : enum IsolateAddressId {
    1436             : #define DECLARE_ENUM(CamelName, hacker_name) k##CamelName##Address,
    1437             :   FOR_EACH_ISOLATE_ADDRESS_NAME(DECLARE_ENUM)
    1438             : #undef DECLARE_ENUM
    1439             :       kIsolateAddressCount
    1440             : };
    1441             : 
    1442             : }  // namespace internal
    1443             : }  // namespace v8
    1444             : 
    1445             : namespace i = v8::internal;
    1446             : 
    1447             : #endif  // V8_GLOBALS_H_

Generated by: LCOV version 1.10