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