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