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