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