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

Generated by: LCOV version 1.10