• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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  
122  typedef uint8_t byte;
123  typedef byte* Address;
124  
125  // -----------------------------------------------------------------------------
126  // Constants
127  
128  const int KB = 1024;
129  const int MB = KB * KB;
130  const int GB = KB * KB * KB;
131  const int kMaxInt = 0x7FFFFFFF;
132  const int kMinInt = -kMaxInt - 1;
133  const int kMaxInt8 = (1 << 7) - 1;
134  const int kMinInt8 = -(1 << 7);
135  const int kMaxUInt8 = (1 << 8) - 1;
136  const int kMinUInt8 = 0;
137  const int kMaxInt16 = (1 << 15) - 1;
138  const int kMinInt16 = -(1 << 15);
139  const int kMaxUInt16 = (1 << 16) - 1;
140  const int kMinUInt16 = 0;
141  
142  const uint32_t kMaxUInt32 = 0xFFFFFFFFu;
143  const int kMinUInt32 = 0;
144  
145  const int kCharSize = sizeof(char);
146  const int kShortSize = sizeof(short);  // NOLINT
147  const int kIntSize = sizeof(int);
148  const int kInt32Size = sizeof(int32_t);
149  const int kInt64Size = sizeof(int64_t);
150  const int kSizetSize = sizeof(size_t);
151  const int kFloatSize = sizeof(float);
152  const int kDoubleSize = sizeof(double);
153  const int kIntptrSize = sizeof(intptr_t);
154  const int kPointerSize = sizeof(void*);
155  #if V8_TARGET_ARCH_X64 && V8_TARGET_ARCH_32_BIT
156  const int kRegisterSize = kPointerSize + kPointerSize;
157  #else
158  const int kRegisterSize = kPointerSize;
159  #endif
160  const int kPCOnStackSize = kRegisterSize;
161  const int kFPOnStackSize = kRegisterSize;
162  
163  #if V8_TARGET_ARCH_X64 || V8_TARGET_ARCH_IA32 || V8_TARGET_ARCH_X87
164  const int kElidedFrameSlots = kPCOnStackSize / kPointerSize;
165  #else
166  const int kElidedFrameSlots = 0;
167  #endif
168  
169  const int kDoubleSizeLog2 = 3;
170  
171  #if V8_HOST_ARCH_64_BIT
172  const int kPointerSizeLog2 = 3;
173  const intptr_t kIntptrSignBit = V8_INT64_C(0x8000000000000000);
174  const uintptr_t kUintptrAllBitsSet = V8_UINT64_C(0xFFFFFFFFFFFFFFFF);
175  const 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.
180  const size_t kMaximalCodeRangeSize = 256 * MB;
181  const size_t kCodeRangeAreaAlignment = 256 * MB;
182  #elif V8_HOST_ARCH_PPC && V8_TARGET_ARCH_PPC && V8_OS_LINUX
183  const size_t kMaximalCodeRangeSize = 512 * MB;
184  const size_t kCodeRangeAreaAlignment = 64 * KB;  // OS page on PPC Linux
185  #else
186  const size_t kMaximalCodeRangeSize = 512 * MB;
187  const size_t kCodeRangeAreaAlignment = 4 * KB;  // OS page.
188  #endif
189  #if V8_OS_WIN
190  const size_t kMinimumCodeRangeSize = 4 * MB;
191  const size_t kReservedCodeRangePages = 1;
192  #else
193  const size_t kMinimumCodeRangeSize = 3 * MB;
194  const size_t kReservedCodeRangePages = 0;
195  #endif
196  #else
197  const int kPointerSizeLog2 = 2;
198  const intptr_t kIntptrSignBit = 0x80000000;
199  const uintptr_t kUintptrAllBitsSet = 0xFFFFFFFFu;
200  #if V8_TARGET_ARCH_X64 && V8_TARGET_ARCH_32_BIT
201  // x32 port also requires code range.
202  const bool kRequiresCodeRange = true;
203  const size_t kMaximalCodeRangeSize = 256 * MB;
204  const size_t kMinimumCodeRangeSize = 3 * MB;
205  const size_t kCodeRangeAreaAlignment = 4 * KB;  // OS page.
206  #elif V8_HOST_ARCH_PPC && V8_TARGET_ARCH_PPC && V8_OS_LINUX
207  const bool kRequiresCodeRange = false;
208  const size_t kMaximalCodeRangeSize = 0 * MB;
209  const size_t kMinimumCodeRangeSize = 0 * MB;
210  const size_t kCodeRangeAreaAlignment = 64 * KB;  // OS page on PPC Linux
211  #else
212  const bool kRequiresCodeRange = false;
213  const size_t kMaximalCodeRangeSize = 0 * MB;
214  const size_t kMinimumCodeRangeSize = 0 * MB;
215  const size_t kCodeRangeAreaAlignment = 4 * KB;  // OS page.
216  #endif
217  const size_t kReservedCodeRangePages = 0;
218  #endif
219  
220  // Trigger an incremental GCs once the external memory reaches this limit.
221  const 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).
230  const int kMaxRegularHeapObjectSize = 507136;
231  
232  STATIC_ASSERT(kPointerSize == (1 << kPointerSizeLog2));
233  
234  const int kBitsPerByte = 8;
235  const int kBitsPerByteLog2 = 3;
236  const int kBitsPerPointer = kPointerSize * kBitsPerByte;
237  const int kBitsPerInt = kIntSize * kBitsPerByte;
238  
239  // IEEE 754 single precision floating point number bit layout.
240  const uint32_t kBinary32SignMask = 0x80000000u;
241  const uint32_t kBinary32ExponentMask = 0x7f800000u;
242  const uint32_t kBinary32MantissaMask = 0x007fffffu;
243  const int kBinary32ExponentBias = 127;
244  const int kBinary32MaxExponent  = 0xFE;
245  const int kBinary32MinExponent  = 0x01;
246  const int kBinary32MantissaBits = 23;
247  const int kBinary32ExponentShift = 23;
248  
249  // Quiet NaNs have bits 51 to 62 set, possibly the sign bit, and no
250  // other bits set.
251  const 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.
256  typedef uint16_t uc16;
257  typedef int32_t uc32;
258  const int kOneByteSize    = kCharSize;
259  const int kUC16Size     = sizeof(uc16);      // NOLINT
260  
261  // 128 bit SIMD value size.
262  const 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.
275  template <typename F>
FUNCTION_CAST(Address addr)276  F 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  
299  class FreeStoreAllocationPolicy;
300  template <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  
307  enum LanguageMode : uint32_t { SLOPPY, STRICT, LANGUAGE_END };
308  
309  inline 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  
is_sloppy(LanguageMode language_mode)318  inline bool is_sloppy(LanguageMode language_mode) {
319    return language_mode == SLOPPY;
320  }
321  
is_strict(LanguageMode language_mode)322  inline bool is_strict(LanguageMode language_mode) {
323    return language_mode != SLOPPY;
324  }
325  
is_valid_language_mode(int language_mode)326  inline bool is_valid_language_mode(int language_mode) {
327    return language_mode == SLOPPY || language_mode == STRICT;
328  }
329  
construct_language_mode(bool strict_bit)330  inline LanguageMode construct_language_mode(bool strict_bit) {
331    return static_cast<LanguageMode>(strict_bit);
332  }
333  
334  enum TypeofMode : int { INSIDE_TYPEOF, NOT_INSIDE_TYPEOF };
335  
336  // This constant is used as an undefined value when passing source positions.
337  const int kNoSourcePosition = -1;
338  
339  // This constant is used to indicate missing deoptimization information.
340  const int kNoDeoptimizationId = -1;
341  
342  // Deoptimize bailout kind.
343  enum class DeoptimizeKind : uint8_t { kEager, kSoft };
hash_value(DeoptimizeKind kind)344  inline size_t hash_value(DeoptimizeKind kind) {
345    return static_cast<size_t>(kind);
346  }
347  inline 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.
359  const intptr_t kSmiSignMask = kIntptrSignBit;
360  
361  const int kObjectAlignmentBits = kPointerSizeLog2;
362  const intptr_t kObjectAlignment = 1 << kObjectAlignmentBits;
363  const intptr_t kObjectAlignmentMask = kObjectAlignment - 1;
364  
365  // Desired alignment for pointers.
366  const intptr_t kPointerAlignment = (1 << kPointerSizeLog2);
367  const intptr_t kPointerAlignmentMask = kPointerAlignment - 1;
368  
369  // Desired alignment for double values.
370  const intptr_t kDoubleAlignment = 8;
371  const intptr_t kDoubleAlignmentMask = kDoubleAlignment - 1;
372  
373  // Desired alignment for generated code is 32 bytes (to improve cache line
374  // utilization).
375  const int kCodeAlignmentBits = 5;
376  const intptr_t kCodeAlignment = 1 << kCodeAlignmentBits;
377  const 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.
385  const int kPageHeaderTag = 3;
386  const int kPageHeaderTagSize = 2;
387  const 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
393  const Address kZapValue =
394      reinterpret_cast<Address>(V8_UINT64_C(0xdeadbeedbeadbeef));
395  const Address kHandleZapValue =
396      reinterpret_cast<Address>(V8_UINT64_C(0x1baddead0baddeaf));
397  const Address kGlobalHandleZapValue =
398      reinterpret_cast<Address>(V8_UINT64_C(0x1baffed00baffedf));
399  const Address kFromSpaceZapValue =
400      reinterpret_cast<Address>(V8_UINT64_C(0x1beefdad0beefdaf));
401  const uint64_t kDebugZapValue = V8_UINT64_C(0xbadbaddbbadbaddb);
402  const uint64_t kSlotsZapValue = V8_UINT64_C(0xbeefdeadbeefdeef);
403  const uint64_t kFreeListZapValue = 0xfeed1eaffeed1eaf;
404  #else
405  const Address kZapValue = reinterpret_cast<Address>(0xdeadbeef);
406  const Address kHandleZapValue = reinterpret_cast<Address>(0xbaddeaf);
407  const Address kGlobalHandleZapValue = reinterpret_cast<Address>(0xbaffedf);
408  const Address kFromSpaceZapValue = reinterpret_cast<Address>(0xbeefdaf);
409  const uint32_t kSlotsZapValue = 0xbeefdeef;
410  const uint32_t kDebugZapValue = 0xbadbaddb;
411  const uint32_t kFreeListZapValue = 0xfeed1eaf;
412  #endif
413  
414  const int kCodeZapValue = 0xbadc0de;
415  const 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.
424  const uint32_t kQuietNaNHighBitsMask = 0xfff << (51 - 32);
425  
426  
427  // -----------------------------------------------------------------------------
428  // Forward declarations for frequently used classes
429  
430  class AccessorInfo;
431  class Allocation;
432  class Arguments;
433  class Assembler;
434  class Code;
435  class CodeGenerator;
436  class CodeStub;
437  class Context;
438  class Debug;
439  class DebugInfo;
440  class Descriptor;
441  class DescriptorArray;
442  class TransitionArray;
443  class ExternalReference;
444  class FixedArray;
445  class FunctionTemplateInfo;
446  class MemoryChunk;
447  class SeededNumberDictionary;
448  class UnseededNumberDictionary;
449  class NameDictionary;
450  class GlobalDictionary;
451  template <typename T> class MaybeHandle;
452  template <typename T> class Handle;
453  class Heap;
454  class HeapObject;
455  class IC;
456  class InterceptorInfo;
457  class Isolate;
458  class JSReceiver;
459  class JSArray;
460  class JSFunction;
461  class JSObject;
462  class LargeObjectSpace;
463  class MacroAssembler;
464  class Map;
465  class MapSpace;
466  class MarkCompactCollector;
467  class NewSpace;
468  class Object;
469  class OldSpace;
470  class ParameterCount;
471  class Foreign;
472  class Scope;
473  class DeclarationScope;
474  class ModuleScope;
475  class ScopeInfo;
476  class Script;
477  class Smi;
478  template <typename Config, class Allocator = FreeStoreAllocationPolicy>
479  class SplayTree;
480  class String;
481  class Symbol;
482  class Name;
483  class Struct;
484  class FeedbackVector;
485  class Variable;
486  class RelocInfo;
487  class Deserializer;
488  class MessageLocation;
489  
490  typedef bool (*WeakSlotCallback)(Object** pointer);
491  
492  typedef 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
500  enum 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  };
512  const int kSpaceTagSize = 3;
513  const int kSpaceTagMask = (1 << kSpaceTagSize) - 1;
514  
515  enum AllocationAlignment { kWordAligned, kDoubleAligned, kDoubleUnaligned };
516  
517  // Possible outcomes for decisions.
518  enum class Decision : uint8_t { kUnknown, kTrue, kFalse };
519  
hash_value(Decision decision)520  inline size_t hash_value(Decision decision) {
521    return static_cast<uint8_t>(decision);
522  }
523  
524  inline 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.
538  enum WriteBarrierKind : uint8_t {
539    kNoWriteBarrier,
540    kMapWriteBarrier,
541    kPointerWriteBarrier,
542    kFullWriteBarrier
543  };
544  
hash_value(WriteBarrierKind kind)545  inline size_t hash_value(WriteBarrierKind kind) {
546    return static_cast<uint8_t>(kind);
547  }
548  
549  inline 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).
568  enum PretenureFlag { NOT_TENURED, TENURED };
569  
570  inline 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  
581  enum MinimumCapacity {
582    USE_DEFAULT_MINIMUM_CAPACITY,
583    USE_CUSTOM_MINIMUM_CAPACITY
584  };
585  
586  enum GarbageCollector { SCAVENGER, MARK_COMPACTOR, MINOR_MARK_COMPACTOR };
587  
588  enum Executability { NOT_EXECUTABLE, EXECUTABLE };
589  
590  enum 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).
600  enum NativesFlag {
601    NOT_NATIVES_CODE,
602    EXTENSION_CODE,
603    NATIVES_CODE,
604    INSPECTOR_CODE
605  };
606  
607  // JavaScript defines two kinds of 'nil'.
608  enum 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.
612  enum 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  
633  struct 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.
648  typedef 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.
653  typedef void (*InlineCacheCallback)(Code* code, Address ic);
654  
655  
656  // State for inline cache call sites. Aliased as IC::State.
657  enum 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  
674  enum CacheHolderFlag {
675    kCacheOnPrototype,
676    kCacheOnPrototypeReceiverIsDictionary,
677    kCacheOnPrototypeReceiverIsPrimitive,
678    kCacheOnReceiver
679  };
680  
681  enum WhereToStart { kStartAtReceiver, kStartAtPrototype };
682  
683  // The Store Buffer (GC).
684  typedef enum {
685    kStoreBufferFullEvent,
686    kStoreBufferStartScanningPagesEvent,
687    kStoreBufferScanningPageEvent
688  } StoreBufferEvent;
689  
690  
691  typedef 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
698  union 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  
709  union 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
720  typedef IeeeDoubleLittleEndianArchType IeeeDoubleArchType;
721  const int kIeeeDoubleMantissaWordOffset = 0;
722  const int kIeeeDoubleExponentWordOffset = 4;
723  #else
724  typedef IeeeDoubleBigEndianArchType IeeeDoubleArchType;
725  const int kIeeeDoubleMantissaWordOffset = 4;
726  const int kIeeeDoubleExponentWordOffset = 0;
727  #endif
728  
729  // AccessorCallback
730  struct 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.
764  enum 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.
813  enum 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  
hash_value(ConvertReceiverMode mode)819  inline size_t hash_value(ConvertReceiverMode mode) {
820    return bit_cast<unsigned>(mode);
821  }
822  
823  inline 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.
837  enum class TailCallMode : unsigned { kAllow, kDisallow };
838  
hash_value(TailCallMode mode)839  inline size_t hash_value(TailCallMode mode) { return bit_cast<unsigned>(mode); }
840  
841  inline 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.
854  enum class OrdinaryToPrimitiveHint { kNumber, kString };
855  
856  // Valid hints for the abstract operation ToPrimitive,
857  // implemented according to ES6, section 7.1.1.
858  enum class ToPrimitiveHint { kDefault, kNumber, kString };
859  
860  // Defines specifics about arguments object or rest parameter creation.
861  enum class CreateArgumentsType : uint8_t {
862    kMappedArguments,
863    kUnmappedArguments,
864    kRestParameter
865  };
866  
hash_value(CreateArgumentsType type)867  inline size_t hash_value(CreateArgumentsType type) {
868    return bit_cast<uint8_t>(type);
869  }
870  
871  inline 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.
886  enum SmiCheckType {
887    DONT_DO_SMI_CHECK,
888    DO_SMI_CHECK
889  };
890  
891  enum 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.
903  enum 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)
920  const uint32_t kHoleNanUpper32 = 0xFFFF7FFF;
921  const uint32_t kHoleNanLower32 = 0xFFFF7FFF;
922  #else
923  const uint32_t kHoleNanUpper32 = 0xFFF7FFFF;
924  const uint32_t kHoleNanLower32 = 0xFFF7FFFF;
925  #endif
926  
927  const uint64_t kHoleNanInt64 =
928      (static_cast<uint64_t>(kHoleNanUpper32) << 32) | kHoleNanLower32;
929  
930  
931  // ES6 section 20.1.2.6 Number.MAX_SAFE_INTEGER
932  const 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.
936  enum 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
VariableMode2String(VariableMode mode)965  inline 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  
987  enum 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  
IsDynamicVariableMode(VariableMode mode)995  inline bool IsDynamicVariableMode(VariableMode mode) {
996    return mode >= DYNAMIC && mode <= DYNAMIC_LOCAL;
997  }
998  
999  
IsDeclaredVariableMode(VariableMode mode)1000  inline bool IsDeclaredVariableMode(VariableMode mode) {
1001    STATIC_ASSERT(VAR == 0);  // Implies that mode >= VAR.
1002    return mode <= CONST;
1003  }
1004  
1005  
IsLexicalVariableMode(VariableMode mode)1006  inline bool IsLexicalVariableMode(VariableMode mode) {
1007    return mode >= LET && mode <= CONST;
1008  }
1009  
1010  enum 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).
1073  enum InitializationFlag : uint8_t { kNeedsInitialization, kCreatedInitialized };
1074  
1075  enum class HoleCheckMode { kRequired, kElided };
1076  
1077  enum MaybeAssignedFlag : uint8_t { kNotAssigned, kMaybeAssigned };
1078  
1079  // Serialized in PreparseData, so numeric values should not be changed.
1080  enum ParseErrorType { kSyntaxError = 0, kReferenceError = 1 };
1081  
1082  
1083  enum MinusZeroMode {
1084    TREAT_MINUS_ZERO_AS_ZERO,
1085    FAIL_ON_MINUS_ZERO
1086  };
1087  
1088  
1089  enum Signedness { kSigned, kUnsigned };
1090  
1091  enum 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  
IsValidFunctionKind(FunctionKind kind)1113  inline 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  
IsArrowFunction(FunctionKind kind)1133  inline bool IsArrowFunction(FunctionKind kind) {
1134    DCHECK(IsValidFunctionKind(kind));
1135    return kind & FunctionKind::kArrowFunction;
1136  }
1137  
1138  
IsGeneratorFunction(FunctionKind kind)1139  inline bool IsGeneratorFunction(FunctionKind kind) {
1140    DCHECK(IsValidFunctionKind(kind));
1141    return kind & FunctionKind::kGeneratorFunction;
1142  }
1143  
IsModule(FunctionKind kind)1144  inline bool IsModule(FunctionKind kind) {
1145    DCHECK(IsValidFunctionKind(kind));
1146    return kind & FunctionKind::kModule;
1147  }
1148  
IsAsyncFunction(FunctionKind kind)1149  inline bool IsAsyncFunction(FunctionKind kind) {
1150    DCHECK(IsValidFunctionKind(kind));
1151    return kind & FunctionKind::kAsyncFunction;
1152  }
1153  
IsResumableFunction(FunctionKind kind)1154  inline bool IsResumableFunction(FunctionKind kind) {
1155    return IsGeneratorFunction(kind) || IsAsyncFunction(kind) || IsModule(kind);
1156  }
1157  
IsConciseMethod(FunctionKind kind)1158  inline bool IsConciseMethod(FunctionKind kind) {
1159    DCHECK(IsValidFunctionKind(kind));
1160    return kind & FunctionKind::kConciseMethod;
1161  }
1162  
IsGetterFunction(FunctionKind kind)1163  inline bool IsGetterFunction(FunctionKind kind) {
1164    DCHECK(IsValidFunctionKind(kind));
1165    return kind & FunctionKind::kGetterFunction;
1166  }
1167  
IsSetterFunction(FunctionKind kind)1168  inline bool IsSetterFunction(FunctionKind kind) {
1169    DCHECK(IsValidFunctionKind(kind));
1170    return kind & FunctionKind::kSetterFunction;
1171  }
1172  
IsAccessorFunction(FunctionKind kind)1173  inline bool IsAccessorFunction(FunctionKind kind) {
1174    DCHECK(IsValidFunctionKind(kind));
1175    return kind & FunctionKind::kAccessorFunction;
1176  }
1177  
1178  
IsDefaultConstructor(FunctionKind kind)1179  inline bool IsDefaultConstructor(FunctionKind kind) {
1180    DCHECK(IsValidFunctionKind(kind));
1181    return kind & FunctionKind::kDefaultConstructor;
1182  }
1183  
1184  
IsBaseConstructor(FunctionKind kind)1185  inline bool IsBaseConstructor(FunctionKind kind) {
1186    DCHECK(IsValidFunctionKind(kind));
1187    return kind & FunctionKind::kBaseConstructor;
1188  }
1189  
IsDerivedConstructor(FunctionKind kind)1190  inline bool IsDerivedConstructor(FunctionKind kind) {
1191    DCHECK(IsValidFunctionKind(kind));
1192    return kind & FunctionKind::kDerivedConstructor;
1193  }
1194  
1195  
IsClassConstructor(FunctionKind kind)1196  inline bool IsClassConstructor(FunctionKind kind) {
1197    DCHECK(IsValidFunctionKind(kind));
1198    return kind & FunctionKind::kClassConstructor;
1199  }
1200  
1201  
IsConstructable(FunctionKind kind,LanguageMode mode)1202  inline 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  
1211  enum class InterpreterPushArgsMode : unsigned {
1212    kJSFunction,
1213    kWithFinalSpread,
1214    kOther
1215  };
1216  
hash_value(InterpreterPushArgsMode mode)1217  inline size_t hash_value(InterpreterPushArgsMode mode) {
1218    return bit_cast<unsigned>(mode);
1219  }
1220  
1221  inline 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  
ObjectHash(Address address)1235  inline 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.
1252  class 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.
1271  class 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  
1285  enum 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  
hash_value(UnicodeEncoding encoding)1291  inline size_t hash_value(UnicodeEncoding encoding) {
1292    return static_cast<uint8_t>(encoding);
1293  }
1294  
1295  inline 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  
1306  enum class IterationKind { kKeys, kValues, kEntries };
1307  
1308  inline 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.
1324  enum class DataPropertyInLiteralFlag {
1325    kNoFlags = 0,
1326    kDontEnum = 1 << 0,
1327    kSetFunctionName = 1 << 1
1328  };
1329  typedef base::Flags<DataPropertyInLiteralFlag> DataPropertyInLiteralFlags;
1330  DEFINE_OPERATORS_FOR_FLAGS(DataPropertyInLiteralFlags)
1331  
1332  enum 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.
1349  enum class ArrayIteratorKind { kArray, kTypedArray };
1350  
1351  namespace i = v8::internal;
1352  
1353  #endif  // V8_GLOBALS_H_
1354