libv8-node 22.7.0.4-arm64-darwin → 23.6.1.0-arm64-darwin

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. checksums.yaml +4 -4
  2. data/lib/libv8/node/version.rb +3 -3
  3. data/vendor/v8/arm64-darwin/libv8/obj/libv8_monolith.a +0 -0
  4. data/vendor/v8/include/cppgc/allocation.h +10 -11
  5. data/vendor/v8/include/cppgc/garbage-collected.h +8 -0
  6. data/vendor/v8/include/cppgc/heap-statistics.h +2 -0
  7. data/vendor/v8/include/cppgc/internal/api-constants.h +6 -1
  8. data/vendor/v8/include/cppgc/internal/compiler-specific.h +9 -1
  9. data/vendor/v8/include/cppgc/internal/gc-info.h +12 -10
  10. data/vendor/v8/include/cppgc/internal/member-storage.h +6 -0
  11. data/vendor/v8/include/cppgc/internal/name-trait.h +5 -1
  12. data/vendor/v8/include/cppgc/name-provider.h +7 -0
  13. data/vendor/v8/include/v8-array-buffer.h +44 -24
  14. data/vendor/v8/include/v8-callbacks.h +10 -5
  15. data/vendor/v8/include/v8-context.h +41 -9
  16. data/vendor/v8/include/v8-cppgc.h +3 -55
  17. data/vendor/v8/include/v8-date.h +9 -0
  18. data/vendor/v8/include/v8-embedder-heap.h +4 -1
  19. data/vendor/v8/include/v8-exception.h +70 -0
  20. data/vendor/v8/include/v8-fast-api-calls.h +31 -38
  21. data/vendor/v8/include/v8-function-callback.h +203 -62
  22. data/vendor/v8/include/v8-function.h +4 -3
  23. data/vendor/v8/include/v8-handle-base.h +2 -2
  24. data/vendor/v8/include/v8-initialization.h +18 -1
  25. data/vendor/v8/include/v8-inspector.h +6 -3
  26. data/vendor/v8/include/v8-internal.h +303 -58
  27. data/vendor/v8/include/v8-isolate.h +58 -39
  28. data/vendor/v8/include/v8-local-handle.h +18 -19
  29. data/vendor/v8/include/v8-message.h +0 -21
  30. data/vendor/v8/include/v8-metrics.h +4 -0
  31. data/vendor/v8/include/v8-microtask-queue.h +0 -5
  32. data/vendor/v8/include/v8-object.h +284 -35
  33. data/vendor/v8/include/v8-persistent-handle.h +0 -19
  34. data/vendor/v8/include/v8-platform.h +21 -35
  35. data/vendor/v8/include/v8-primitive.h +92 -1
  36. data/vendor/v8/include/v8-profiler.h +38 -1
  37. data/vendor/v8/include/v8-promise.h +2 -2
  38. data/vendor/v8/include/v8-sandbox.h +173 -0
  39. data/vendor/v8/include/v8-script.h +44 -14
  40. data/vendor/v8/include/v8-snapshot.h +38 -2
  41. data/vendor/v8/include/v8-template.h +105 -263
  42. data/vendor/v8/include/v8-traced-handle.h +4 -15
  43. data/vendor/v8/include/v8-unwinder.h +2 -1
  44. data/vendor/v8/include/v8-util.h +1 -117
  45. data/vendor/v8/include/v8-value.h +3 -2
  46. data/vendor/v8/include/v8-version.h +3 -3
  47. data/vendor/v8/include/v8-wasm.h +3 -0
  48. data/vendor/v8/include/v8config.h +51 -7
  49. metadata +4 -3
@@ -11,7 +11,9 @@
11
11
 
12
12
  #include <atomic>
13
13
  #include <iterator>
14
+ #include <limits>
14
15
  #include <memory>
16
+ #include <optional>
15
17
  #include <type_traits>
16
18
 
17
19
  #include "v8config.h" // NOLINT(build/include_directory)
@@ -87,7 +89,10 @@ struct SmiTagging<4> {
87
89
  // Truncate and shift down (requires >> to be sign extending).
88
90
  return static_cast<int32_t>(static_cast<uint32_t>(value)) >> shift_bits;
89
91
  }
90
- V8_INLINE static constexpr bool IsValidSmi(intptr_t value) {
92
+
93
+ template <class T, typename std::enable_if_t<std::is_integral_v<T> &&
94
+ std::is_signed_v<T>>* = nullptr>
95
+ V8_INLINE static constexpr bool IsValidSmi(T value) {
91
96
  // Is value in range [kSmiMinValue, kSmiMaxValue].
92
97
  // Use unsigned operations in order to avoid undefined behaviour in case of
93
98
  // signed integer overflow.
@@ -96,6 +101,28 @@ struct SmiTagging<4> {
96
101
  (static_cast<uintptr_t>(kSmiMaxValue) -
97
102
  static_cast<uintptr_t>(kSmiMinValue));
98
103
  }
104
+
105
+ template <class T,
106
+ typename std::enable_if_t<std::is_integral_v<T> &&
107
+ std::is_unsigned_v<T>>* = nullptr>
108
+ V8_INLINE static constexpr bool IsValidSmi(T value) {
109
+ static_assert(kSmiMaxValue <= std::numeric_limits<uintptr_t>::max());
110
+ return value <= static_cast<uintptr_t>(kSmiMaxValue);
111
+ }
112
+
113
+ // Same as the `intptr_t` version but works with int64_t on 32-bit builds
114
+ // without slowing down anything else.
115
+ V8_INLINE static constexpr bool IsValidSmi(int64_t value) {
116
+ return (static_cast<uint64_t>(value) -
117
+ static_cast<uint64_t>(kSmiMinValue)) <=
118
+ (static_cast<uint64_t>(kSmiMaxValue) -
119
+ static_cast<uint64_t>(kSmiMinValue));
120
+ }
121
+
122
+ V8_INLINE static constexpr bool IsValidSmi(uint64_t value) {
123
+ static_assert(kSmiMaxValue <= std::numeric_limits<uint64_t>::max());
124
+ return value <= static_cast<uint64_t>(kSmiMaxValue);
125
+ }
99
126
  };
100
127
 
101
128
  // Smi constants for systems where tagged pointer is a 64-bit value.
@@ -112,10 +139,21 @@ struct SmiTagging<8> {
112
139
  // Shift down and throw away top 32 bits.
113
140
  return static_cast<int>(static_cast<intptr_t>(value) >> shift_bits);
114
141
  }
115
- V8_INLINE static constexpr bool IsValidSmi(intptr_t value) {
142
+
143
+ template <class T, typename std::enable_if_t<std::is_integral_v<T> &&
144
+ std::is_signed_v<T>>* = nullptr>
145
+ V8_INLINE static constexpr bool IsValidSmi(T value) {
116
146
  // To be representable as a long smi, the value must be a 32-bit integer.
117
147
  return (value == static_cast<int32_t>(value));
118
148
  }
149
+
150
+ template <class T,
151
+ typename std::enable_if_t<std::is_integral_v<T> &&
152
+ std::is_unsigned_v<T>>* = nullptr>
153
+ V8_INLINE static constexpr bool IsValidSmi(T value) {
154
+ return (static_cast<uintptr_t>(value) ==
155
+ static_cast<uintptr_t>(static_cast<int32_t>(value)));
156
+ }
119
157
  };
120
158
 
121
159
  #ifdef V8_COMPRESS_POINTERS
@@ -253,15 +291,15 @@ static_assert(1ULL << (64 - kBoundedSizeShift) ==
253
291
  // size allows omitting bounds checks on table accesses if the indices are
254
292
  // guaranteed (e.g. through shifting) to be below the maximum index. This
255
293
  // value must be a power of two.
256
- constexpr size_t kExternalPointerTableReservationSize = 512 * MB;
294
+ constexpr size_t kExternalPointerTableReservationSize = 256 * MB;
257
295
 
258
296
  // The external pointer table indices stored in HeapObjects as external
259
297
  // pointers are shifted to the left by this amount to guarantee that they are
260
298
  // smaller than the maximum table size.
261
- constexpr uint32_t kExternalPointerIndexShift = 6;
299
+ constexpr uint32_t kExternalPointerIndexShift = 7;
262
300
  #else
263
- constexpr size_t kExternalPointerTableReservationSize = 1024 * MB;
264
- constexpr uint32_t kExternalPointerIndexShift = 5;
301
+ constexpr size_t kExternalPointerTableReservationSize = 512 * MB;
302
+ constexpr uint32_t kExternalPointerIndexShift = 6;
265
303
  #endif // V8_TARGET_OS_ANDROID
266
304
 
267
305
  // The maximum number of entries in an external pointer table.
@@ -301,6 +339,95 @@ using ExternalPointer_t = Address;
301
339
  constexpr ExternalPointer_t kNullExternalPointer = 0;
302
340
  constexpr ExternalPointerHandle kNullExternalPointerHandle = 0;
303
341
 
342
+ // See `ExternalPointerHandle` for the main documentation. The difference to
343
+ // `ExternalPointerHandle` is that the handle does not represent an arbitrary
344
+ // external pointer but always refers to an object managed by `CppHeap`. The
345
+ // handles are using in combination with a dedicated table for `CppHeap`
346
+ // references.
347
+ using CppHeapPointerHandle = uint32_t;
348
+
349
+ // The actual pointer to objects located on the `CppHeap`. When pointer
350
+ // compression is enabled these pointers are stored as `CppHeapPointerHandle`.
351
+ // In non-compressed configurations the pointers are simply stored as raw
352
+ // pointers.
353
+ #ifdef V8_COMPRESS_POINTERS
354
+ using CppHeapPointer_t = CppHeapPointerHandle;
355
+ #else
356
+ using CppHeapPointer_t = Address;
357
+ #endif
358
+
359
+ constexpr CppHeapPointer_t kNullCppHeapPointer = 0;
360
+ constexpr CppHeapPointerHandle kNullCppHeapPointerHandle = 0;
361
+
362
+ constexpr uint64_t kCppHeapPointerMarkBit = 1ULL;
363
+ constexpr uint64_t kCppHeapPointerTagShift = 1;
364
+ constexpr uint64_t kCppHeapPointerPayloadShift = 16;
365
+
366
+ #ifdef V8_COMPRESS_POINTERS
367
+ // CppHeapPointers use a dedicated pointer table. These constants control the
368
+ // size and layout of the table. See the corresponding constants for the
369
+ // external pointer table for further details.
370
+ constexpr size_t kCppHeapPointerTableReservationSize =
371
+ kExternalPointerTableReservationSize;
372
+ constexpr uint32_t kCppHeapPointerIndexShift = kExternalPointerIndexShift;
373
+
374
+ constexpr int kCppHeapPointerTableEntrySize = 8;
375
+ constexpr int kCppHeapPointerTableEntrySizeLog2 = 3;
376
+ constexpr size_t kMaxCppHeapPointers =
377
+ kCppHeapPointerTableReservationSize / kCppHeapPointerTableEntrySize;
378
+ static_assert((1 << (32 - kCppHeapPointerIndexShift)) == kMaxCppHeapPointers,
379
+ "kCppHeapPointerTableReservationSize and "
380
+ "kCppHeapPointerIndexShift don't match");
381
+
382
+ #else // !V8_COMPRESS_POINTERS
383
+
384
+ // Needed for the V8.SandboxedCppHeapPointersCount histogram.
385
+ constexpr size_t kMaxCppHeapPointers = 0;
386
+
387
+ #endif // V8_COMPRESS_POINTERS
388
+
389
+ // See `ExternalPointerHandle` for the main documentation. The difference to
390
+ // `ExternalPointerHandle` is that the handle always refers to a
391
+ // (external pointer, size) tuple. The handles are used in combination with a
392
+ // dedicated external buffer table (EBT).
393
+ using ExternalBufferHandle = uint32_t;
394
+
395
+ // ExternalBuffer point to buffer located outside the sandbox. When the V8
396
+ // sandbox is enabled, these are stored on heap as ExternalBufferHandles,
397
+ // otherwise they are simply raw pointers.
398
+ #ifdef V8_ENABLE_SANDBOX
399
+ using ExternalBuffer_t = ExternalBufferHandle;
400
+ #else
401
+ using ExternalBuffer_t = Address;
402
+ #endif
403
+
404
+ #ifdef V8_TARGET_OS_ANDROID
405
+ // The size of the virtual memory reservation for the external buffer table.
406
+ // As with the external pointer table, a maximum table size in combination with
407
+ // shifted indices allows omitting bounds checks.
408
+ constexpr size_t kExternalBufferTableReservationSize = 64 * MB;
409
+
410
+ // The external buffer handles are stores shifted to the left by this amount
411
+ // to guarantee that they are smaller than the maximum table size.
412
+ constexpr uint32_t kExternalBufferHandleShift = 10;
413
+ #else
414
+ constexpr size_t kExternalBufferTableReservationSize = 128 * MB;
415
+ constexpr uint32_t kExternalBufferHandleShift = 9;
416
+ #endif // V8_TARGET_OS_ANDROID
417
+
418
+ // A null handle always references an entry that contains nullptr.
419
+ constexpr ExternalBufferHandle kNullExternalBufferHandle = 0;
420
+
421
+ // The maximum number of entries in an external buffer table.
422
+ constexpr int kExternalBufferTableEntrySize = 16;
423
+ constexpr int kExternalBufferTableEntrySizeLog2 = 4;
424
+ constexpr size_t kMaxExternalBufferPointers =
425
+ kExternalBufferTableReservationSize / kExternalBufferTableEntrySize;
426
+ static_assert((1 << (32 - kExternalBufferHandleShift)) ==
427
+ kMaxExternalBufferPointers,
428
+ "kExternalBufferTableReservationSize and "
429
+ "kExternalBufferHandleShift don't match");
430
+
304
431
  //
305
432
  // External Pointers.
306
433
  //
@@ -365,7 +492,7 @@ constexpr ExternalPointerHandle kNullExternalPointerHandle = 0;
365
492
  // extension (MTE) which would use bits [56, 60).
366
493
  //
367
494
  // External pointer tables are also available even when the sandbox is off but
368
- // pointer compression is on. In that case, the mechanism can be used to easy
495
+ // pointer compression is on. In that case, the mechanism can be used to ease
369
496
  // alignment requirements as it turns unaligned 64-bit raw pointers into
370
497
  // aligned 32-bit indices. To "opt-in" to the external pointer table mechanism
371
498
  // for this purpose, instead of using the ExternalPointer accessors one needs to
@@ -380,7 +507,7 @@ constexpr uint64_t kExternalPointerTagShift = 48;
380
507
  // These are sorted so that tags can be grouped together and it can efficiently
381
508
  // be checked if a tag belongs to a given group. See for example the
382
509
  // IsSharedExternalPointerType routine.
383
- constexpr uint64_t kAllExternalPointerTypeTags[] = {
510
+ constexpr uint64_t kAllTagsForAndBasedTypeChecking[] = {
384
511
  0b00001111, 0b00010111, 0b00011011, 0b00011101, 0b00011110, 0b00100111,
385
512
  0b00101011, 0b00101101, 0b00101110, 0b00110011, 0b00110101, 0b00110110,
386
513
  0b00111001, 0b00111010, 0b00111100, 0b01000111, 0b01001011, 0b01001101,
@@ -394,8 +521,8 @@ constexpr uint64_t kAllExternalPointerTypeTags[] = {
394
521
  0b11001100, 0b11010001, 0b11010010, 0b11010100, 0b11011000, 0b11100001,
395
522
  0b11100010, 0b11100100, 0b11101000, 0b11110000};
396
523
 
397
- #define TAG(i) \
398
- ((kAllExternalPointerTypeTags[i] << kExternalPointerTagShift) | \
524
+ #define TAG(i) \
525
+ ((kAllTagsForAndBasedTypeChecking[i] << kExternalPointerTagShift) | \
399
526
  kExternalPointerMarkBit)
400
527
 
401
528
  // clang-format off
@@ -414,26 +541,73 @@ constexpr uint64_t kAllExternalPointerTypeTags[] = {
414
541
  V(kExternalStringResourceTag, TAG(1)) \
415
542
  V(kExternalStringResourceDataTag, TAG(2)) \
416
543
  V(kLastSharedTag, TAG(2))
544
+ // Leave some space in the tag range here for future shared tags.
417
545
 
418
546
  // External pointers using these tags are kept in a per-Isolate external
419
547
  // pointer table and can only be accessed when this Isolate is active.
420
548
  #define PER_ISOLATE_EXTERNAL_POINTER_TAGS(V) \
421
- V(kForeignForeignAddressTag, TAG(10)) \
422
- V(kNativeContextMicrotaskQueueTag, TAG(11)) \
423
- V(kEmbedderDataSlotPayloadTag, TAG(12)) \
549
+ V(kNativeContextMicrotaskQueueTag, TAG(5)) \
550
+ V(kEmbedderDataSlotPayloadTag, TAG(6)) \
424
551
  /* This tag essentially stands for a `void*` pointer in the V8 API, and */ \
425
552
  /* it is the Embedder's responsibility to ensure type safety (against */ \
426
553
  /* substitution) and lifetime validity of these objects. */ \
427
- V(kExternalObjectValueTag, TAG(13)) \
428
- V(kFunctionTemplateInfoCallbackTag, TAG(14)) \
429
- V(kAccessorInfoGetterTag, TAG(15)) \
430
- V(kAccessorInfoSetterTag, TAG(16)) \
431
- V(kWasmInternalFunctionCallTargetTag, TAG(17)) \
432
- V(kWasmTypeInfoNativeTypeTag, TAG(18)) \
433
- V(kWasmExportedFunctionDataSignatureTag, TAG(19)) \
434
- V(kWasmContinuationJmpbufTag, TAG(20)) \
435
- V(kWasmIndirectFunctionTargetTag, TAG(21)) \
436
- V(kArrayBufferExtensionTag, TAG(22))
554
+ V(kExternalObjectValueTag, TAG(7)) \
555
+ V(kFunctionTemplateInfoCallbackTag, TAG(8)) \
556
+ V(kAccessorInfoGetterTag, TAG(9)) \
557
+ V(kAccessorInfoSetterTag, TAG(10)) \
558
+ V(kWasmInternalFunctionCallTargetTag, TAG(11)) \
559
+ V(kWasmTypeInfoNativeTypeTag, TAG(12)) \
560
+ V(kWasmExportedFunctionDataSignatureTag, TAG(13)) \
561
+ V(kWasmContinuationJmpbufTag, TAG(14)) \
562
+ V(kWasmStackMemoryTag, TAG(15)) \
563
+ V(kWasmIndirectFunctionTargetTag, TAG(16)) \
564
+ /* Foreigns */ \
565
+ V(kGenericForeignTag, TAG(20)) \
566
+ V(kApiNamedPropertyQueryCallbackTag, TAG(21)) \
567
+ V(kApiNamedPropertyGetterCallbackTag, TAG(22)) \
568
+ V(kApiNamedPropertySetterCallbackTag, TAG(23)) \
569
+ V(kApiNamedPropertyDescriptorCallbackTag, TAG(24)) \
570
+ V(kApiNamedPropertyDefinerCallbackTag, TAG(25)) \
571
+ V(kApiNamedPropertyDeleterCallbackTag, TAG(26)) \
572
+ V(kApiIndexedPropertyQueryCallbackTag, TAG(27)) \
573
+ V(kApiIndexedPropertyGetterCallbackTag, TAG(28)) \
574
+ V(kApiIndexedPropertySetterCallbackTag, TAG(29)) \
575
+ V(kApiIndexedPropertyDescriptorCallbackTag, TAG(30)) \
576
+ V(kApiIndexedPropertyDefinerCallbackTag, TAG(31)) \
577
+ V(kApiIndexedPropertyDeleterCallbackTag, TAG(32)) \
578
+ V(kApiIndexedPropertyEnumeratorCallbackTag, TAG(33)) \
579
+ V(kApiAccessCheckCallbackTag, TAG(34)) \
580
+ V(kApiAbortScriptExecutionCallbackTag, TAG(35)) \
581
+ V(kSyntheticModuleTag, TAG(36)) \
582
+ V(kMicrotaskCallbackTag, TAG(37)) \
583
+ V(kMicrotaskCallbackDataTag, TAG(38)) \
584
+ V(kCFunctionTag, TAG(39)) \
585
+ V(kCFunctionInfoTag, TAG(40)) \
586
+ V(kMessageListenerTag, TAG(41)) \
587
+ V(kWaiterQueueForeignTag, TAG(42)) \
588
+ /* Managed */ \
589
+ V(kFirstManagedResourceTag, TAG(50)) \
590
+ V(kGenericManagedTag, TAG(50)) \
591
+ V(kWasmWasmStreamingTag, TAG(51)) \
592
+ V(kWasmFuncDataTag, TAG(52)) \
593
+ V(kWasmManagedDataTag, TAG(53)) \
594
+ V(kWasmNativeModuleTag, TAG(54)) \
595
+ V(kIcuBreakIteratorTag, TAG(55)) \
596
+ V(kIcuUnicodeStringTag, TAG(56)) \
597
+ V(kIcuListFormatterTag, TAG(57)) \
598
+ V(kIcuLocaleTag, TAG(58)) \
599
+ V(kIcuSimpleDateFormatTag, TAG(59)) \
600
+ V(kIcuDateIntervalFormatTag, TAG(60)) \
601
+ V(kIcuRelativeDateTimeFormatterTag, TAG(61)) \
602
+ V(kIcuLocalizedNumberFormatterTag, TAG(62)) \
603
+ V(kIcuPluralRulesTag, TAG(63)) \
604
+ V(kIcuCollatorTag, TAG(64)) \
605
+ V(kDisplayNamesInternalTag, TAG(65)) \
606
+ /* External resources whose lifetime is tied to */ \
607
+ /* their entry in the external pointer table but */ \
608
+ /* which are not referenced via a Managed */ \
609
+ V(kArrayBufferExtensionTag, TAG(66)) \
610
+ V(kLastManagedResourceTag, TAG(66)) \
437
611
 
438
612
  // All external pointer tags.
439
613
  #define ALL_EXTERNAL_POINTER_TAGS(V) \
@@ -449,12 +623,18 @@ enum ExternalPointerTag : uint64_t {
449
623
  kExternalPointerNullTag = MAKE_TAG(1, 0b00000000),
450
624
  // External pointer tag that will match any external pointer. Use with care!
451
625
  kAnyExternalPointerTag = MAKE_TAG(1, 0b11111111),
626
+ // External pointer tag that will match any external pointer in a Foreign.
627
+ // Use with care! If desired, this could be made more fine-granular.
628
+ kAnyForeignTag = kAnyExternalPointerTag,
452
629
  // The free entry tag has all type bits set so every type check with a
453
630
  // different type fails. It also doesn't have the mark bit set as free
454
631
  // entries are (by definition) not alive.
455
632
  kExternalPointerFreeEntryTag = MAKE_TAG(0, 0b11111111),
456
633
  // Evacuation entries are used during external pointer table compaction.
457
- kExternalPointerEvacuationEntryTag = MAKE_TAG(1, 0b11100111),
634
+ kExternalPointerEvacuationEntryTag = MAKE_TAG(1, 0b11111110),
635
+ // Tag for zapped/invalidated entries. Those are considered to no longer be
636
+ // in use and so have the marking bit cleared.
637
+ kExternalPointerZappedEntryTag = MAKE_TAG(0, 0b11111101),
458
638
 
459
639
  ALL_EXTERNAL_POINTER_TAGS(EXTERNAL_POINTER_TAG_ENUM)
460
640
  };
@@ -481,6 +661,15 @@ V8_INLINE static constexpr bool IsMaybeReadOnlyExternalPointerType(
481
661
  tag == kFunctionTemplateInfoCallbackTag;
482
662
  }
483
663
 
664
+ // True if the external pointer references an external object whose lifetime is
665
+ // tied to the entry in the external pointer table.
666
+ // In this case, the entry in the ExternalPointerTable always points to an
667
+ // object derived from ExternalPointerTable::ManagedResource.
668
+ V8_INLINE static constexpr bool IsManagedExternalPointerType(
669
+ ExternalPointerTag tag) {
670
+ return tag >= kFirstManagedResourceTag && tag <= kLastManagedResourceTag;
671
+ }
672
+
484
673
  // Sanity checks.
485
674
  #define CHECK_SHARED_EXTERNAL_POINTER_TAGS(Tag, ...) \
486
675
  static_assert(IsSharedExternalPointerType(Tag));
@@ -576,11 +765,11 @@ using CodePointerHandle = IndirectPointerHandle;
576
765
  // The size of the virtual memory reservation for the code pointer table.
577
766
  // As with the other tables, a maximum table size in combination with shifted
578
767
  // indices allows omitting bounds checks.
579
- constexpr size_t kCodePointerTableReservationSize = 16 * MB;
768
+ constexpr size_t kCodePointerTableReservationSize = 128 * MB;
580
769
 
581
770
  // Code pointer handles are shifted by a different amount than indirect pointer
582
771
  // handles as the tables have a different maximum size.
583
- constexpr uint32_t kCodePointerHandleShift = 12;
772
+ constexpr uint32_t kCodePointerHandleShift = 9;
584
773
 
585
774
  // A null handle always references an entry that contains nullptr.
586
775
  constexpr CodePointerHandle kNullCodePointerHandle = kNullIndirectPointerHandle;
@@ -616,6 +805,29 @@ constexpr bool kAllCodeObjectsLiveInTrustedSpace =
616
805
  kRuntimeGeneratedCodeObjectsLiveInTrustedSpace &&
617
806
  kBuiltinCodeObjectsLiveInTrustedSpace;
618
807
 
808
+ //
809
+ // JavaScript Dispatch Table
810
+ //
811
+ // A JSDispatchHandle represents a 32-bit index into a JSDispatchTable.
812
+ using JSDispatchHandle = uint32_t;
813
+
814
+ constexpr JSDispatchHandle kNullJSDispatchHandle = 0;
815
+
816
+ // The size of the virtual memory reservation for the JSDispatchTable.
817
+ // As with the other tables, a maximum table size in combination with shifted
818
+ // indices allows omitting bounds checks.
819
+ constexpr size_t kJSDispatchTableReservationSize = 128 * MB;
820
+ constexpr uint32_t kJSDispatchHandleShift = 9;
821
+
822
+ // The maximum number of entries in a JSDispatchTable.
823
+ constexpr int kJSDispatchTableEntrySize = 16;
824
+ constexpr int kJSDispatchTableEntrySizeLog2 = 4;
825
+ constexpr size_t kMaxJSDispatchEntries =
826
+ kJSDispatchTableReservationSize / kJSDispatchTableEntrySize;
827
+ static_assert((1 << (32 - kJSDispatchHandleShift)) == kMaxJSDispatchEntries,
828
+ "kJSDispatchTableReservationSize and kJSDispatchEntryHandleShift "
829
+ "don't match");
830
+
619
831
  // {obj} must be the raw tagged pointer representation of a HeapObject
620
832
  // that's guaranteed to never be in ReadOnlySpace.
621
833
  V8_EXPORT internal::Isolate* IsolateFromNeverReadOnlySpaceObject(Address obj);
@@ -647,6 +859,13 @@ class Internals {
647
859
 
648
860
  static const int kOddballKindOffset = 4 * kApiTaggedSize + kApiDoubleSize;
649
861
  static const int kJSObjectHeaderSize = 3 * kApiTaggedSize;
862
+ #ifdef V8_COMPRESS_POINTERS
863
+ static const int kJSAPIObjectWithEmbedderSlotsHeaderSize =
864
+ kJSObjectHeaderSize + kApiInt32Size;
865
+ #else // !V8_COMPRESS_POINTERS
866
+ static const int kJSAPIObjectWithEmbedderSlotsHeaderSize =
867
+ kJSObjectHeaderSize + kApiTaggedSize;
868
+ #endif // !V8_COMPRESS_POINTERS
650
869
  static const int kFixedArrayHeaderSize = 2 * kApiTaggedSize;
651
870
  static const int kEmbedderDataArrayHeaderSize = 2 * kApiTaggedSize;
652
871
  static const int kEmbedderDataSlotSize = kApiSystemPointerSize;
@@ -676,6 +895,7 @@ class Internals {
676
895
  // ExternalPointerTable and TrustedPointerTable layout guarantees.
677
896
  static const int kExternalPointerTableBasePointerOffset = 0;
678
897
  static const int kExternalPointerTableSize = 2 * kApiSystemPointerSize;
898
+ static const int kExternalBufferTableSize = 2 * kApiSystemPointerSize;
679
899
  static const int kTrustedPointerTableSize = 2 * kApiSystemPointerSize;
680
900
  static const int kTrustedPointerTableBasePointerOffset = 0;
681
901
 
@@ -719,16 +939,18 @@ class Internals {
719
939
  kIsolateEmbedderDataOffset + kNumIsolateDataSlots * kApiSystemPointerSize;
720
940
  static const int kIsolateSharedExternalPointerTableAddressOffset =
721
941
  kIsolateExternalPointerTableOffset + kExternalPointerTableSize;
942
+ static const int kIsolateCppHeapPointerTableOffset =
943
+ kIsolateSharedExternalPointerTableAddressOffset + kApiSystemPointerSize;
722
944
  #ifdef V8_ENABLE_SANDBOX
723
945
  static const int kIsolateTrustedCageBaseOffset =
724
- kIsolateSharedExternalPointerTableAddressOffset + kApiSystemPointerSize;
946
+ kIsolateCppHeapPointerTableOffset + kExternalPointerTableSize;
725
947
  static const int kIsolateTrustedPointerTableOffset =
726
948
  kIsolateTrustedCageBaseOffset + kApiSystemPointerSize;
727
949
  static const int kIsolateApiCallbackThunkArgumentOffset =
728
950
  kIsolateTrustedPointerTableOffset + kTrustedPointerTableSize;
729
951
  #else
730
952
  static const int kIsolateApiCallbackThunkArgumentOffset =
731
- kIsolateSharedExternalPointerTableAddressOffset + kApiSystemPointerSize;
953
+ kIsolateCppHeapPointerTableOffset + kExternalPointerTableSize;
732
954
  #endif // V8_ENABLE_SANDBOX
733
955
  #else
734
956
  static const int kIsolateApiCallbackThunkArgumentOffset =
@@ -736,13 +958,12 @@ class Internals {
736
958
  #endif // V8_COMPRESS_POINTERS
737
959
  static const int kContinuationPreservedEmbedderDataOffset =
738
960
  kIsolateApiCallbackThunkArgumentOffset + kApiSystemPointerSize;
739
-
740
- static const int kWasm64OOBOffsetAlignmentPaddingSize = 0;
741
- static const int kWasm64OOBOffsetOffset =
742
- kContinuationPreservedEmbedderDataOffset + kApiSystemPointerSize +
743
- kWasm64OOBOffsetAlignmentPaddingSize;
744
961
  static const int kIsolateRootsOffset =
745
- kWasm64OOBOffsetOffset + sizeof(int64_t);
962
+ kContinuationPreservedEmbedderDataOffset + kApiSystemPointerSize;
963
+
964
+ // Assert scopes
965
+ static const int kDisallowGarbageCollectionAlign = alignof(uint32_t);
966
+ static const int kDisallowGarbageCollectionSize = sizeof(uint32_t);
746
967
 
747
968
  #if V8_STATIC_ROOTS_BOOL
748
969
 
@@ -753,7 +974,7 @@ class Internals {
753
974
  V(TrueValue, 0xc9) \
754
975
  V(FalseValue, 0xad) \
755
976
  V(EmptyString, 0xa1) \
756
- V(TheHoleValue, 0x719)
977
+ V(TheHoleValue, 0x791)
757
978
 
758
979
  using Tagged_t = uint32_t;
759
980
  struct StaticReadOnlyRoot {
@@ -761,8 +982,9 @@ class Internals {
761
982
  EXPORTED_STATIC_ROOTS_PTR_LIST(DEF_ROOT)
762
983
  #undef DEF_ROOT
763
984
 
764
- static constexpr Tagged_t kFirstStringMap = 0xe5;
765
- static constexpr Tagged_t kLastStringMap = 0x47d;
985
+ // Use 0 for kStringMapLowerBound since string maps are the first maps.
986
+ static constexpr Tagged_t kStringMapLowerBound = 0;
987
+ static constexpr Tagged_t kStringMapUpperBound = 0x47d;
766
988
 
767
989
  #define PLUSONE(...) +1
768
990
  static constexpr size_t kNumberOfExportedStaticRoots =
@@ -802,8 +1024,8 @@ class Internals {
802
1024
 
803
1025
  // Constants used by PropertyCallbackInfo to check if we should throw when an
804
1026
  // error occurs.
805
- static const int kThrowOnError = 0;
806
- static const int kDontThrow = 1;
1027
+ static const int kDontThrow = 0;
1028
+ static const int kThrowOnError = 1;
807
1029
  static const int kInferShouldThrowMode = 2;
808
1030
 
809
1031
  // Soft limit for AdjustAmountofExternalAllocatedMemory. Trigger an
@@ -836,14 +1058,36 @@ class Internals {
836
1058
  return PlatformSmiTagging::SmiToInt(value);
837
1059
  }
838
1060
 
1061
+ V8_INLINE static constexpr Address AddressToSmi(Address value) {
1062
+ return (value << (kSmiTagSize + PlatformSmiTagging::kSmiShiftSize)) |
1063
+ kSmiTag;
1064
+ }
1065
+
839
1066
  V8_INLINE static constexpr Address IntToSmi(int value) {
840
- return internal::IntToSmi(value);
1067
+ return AddressToSmi(static_cast<Address>(value));
1068
+ }
1069
+
1070
+ template <typename T,
1071
+ typename std::enable_if_t<std::is_integral_v<T>>* = nullptr>
1072
+ V8_INLINE static constexpr Address IntegralToSmi(T value) {
1073
+ return AddressToSmi(static_cast<Address>(value));
841
1074
  }
842
1075
 
843
- V8_INLINE static constexpr bool IsValidSmi(intptr_t value) {
1076
+ template <typename T,
1077
+ typename std::enable_if_t<std::is_integral_v<T>>* = nullptr>
1078
+ V8_INLINE static constexpr bool IsValidSmi(T value) {
844
1079
  return PlatformSmiTagging::IsValidSmi(value);
845
1080
  }
846
1081
 
1082
+ template <typename T,
1083
+ typename std::enable_if_t<std::is_integral_v<T>>* = nullptr>
1084
+ static constexpr std::optional<Address> TryIntegralToSmi(T value) {
1085
+ if (V8_LIKELY(PlatformSmiTagging::IsValidSmi(value))) {
1086
+ return {AddressToSmi(static_cast<Address>(value))};
1087
+ }
1088
+ return {};
1089
+ }
1090
+
847
1091
  #if V8_STATIC_ROOTS_BOOL
848
1092
  V8_INLINE static bool is_identical(Address obj, Tagged_t constant) {
849
1093
  return static_cast<Tagged_t>(obj) == constant;
@@ -1116,7 +1360,7 @@ class V8_EXPORT StrongRootAllocatorBase {
1116
1360
 
1117
1361
  protected:
1118
1362
  explicit StrongRootAllocatorBase(Heap* heap) : heap_(heap) {}
1119
- explicit StrongRootAllocatorBase(v8::Isolate* isolate);
1363
+ explicit StrongRootAllocatorBase(Isolate* isolate);
1120
1364
 
1121
1365
  // Allocate/deallocate a range of n elements of type internal::Address.
1122
1366
  Address* allocate_impl(size_t n);
@@ -1132,17 +1376,15 @@ class V8_EXPORT StrongRootAllocatorBase {
1132
1376
  // and internal::StrongRootAllocator<v8::Local<T>> register the allocated range
1133
1377
  // as strong roots.
1134
1378
  template <typename T>
1135
- class StrongRootAllocator : public StrongRootAllocatorBase,
1136
- private std::allocator<T> {
1379
+ class StrongRootAllocator : private std::allocator<T> {
1137
1380
  public:
1138
1381
  using value_type = T;
1139
1382
 
1140
- explicit StrongRootAllocator(Heap* heap) : StrongRootAllocatorBase(heap) {}
1141
- explicit StrongRootAllocator(v8::Isolate* isolate)
1142
- : StrongRootAllocatorBase(isolate) {}
1383
+ explicit StrongRootAllocator(Heap* heap) {}
1384
+ explicit StrongRootAllocator(Isolate* isolate) {}
1385
+ explicit StrongRootAllocator(v8::Isolate* isolate) {}
1143
1386
  template <typename U>
1144
- StrongRootAllocator(const StrongRootAllocator<U>& other) noexcept
1145
- : StrongRootAllocatorBase(other) {}
1387
+ StrongRootAllocator(const StrongRootAllocator<U>& other) noexcept {}
1146
1388
 
1147
1389
  using std::allocator<T>::allocate;
1148
1390
  using std::allocator<T>::deallocate;
@@ -1311,12 +1553,12 @@ constexpr WrappedIterator<Iterator> operator+(
1311
1553
  // whether direct local support is enabled.
1312
1554
  class ValueHelper final {
1313
1555
  public:
1314
- #ifdef V8_ENABLE_DIRECT_LOCAL
1556
+ #ifdef V8_ENABLE_DIRECT_HANDLE
1315
1557
  static constexpr Address kTaggedNullAddress = 1;
1316
1558
  static constexpr Address kEmpty = kTaggedNullAddress;
1317
1559
  #else
1318
1560
  static constexpr Address kEmpty = kNullAddress;
1319
- #endif // V8_ENABLE_DIRECT_LOCAL
1561
+ #endif // V8_ENABLE_DIRECT_HANDLE
1320
1562
 
1321
1563
  template <typename T>
1322
1564
  V8_INLINE static bool IsEmpty(T* value) {
@@ -1332,7 +1574,7 @@ class ValueHelper final {
1332
1574
  return handle.template value<T>();
1333
1575
  }
1334
1576
 
1335
- #ifdef V8_ENABLE_DIRECT_LOCAL
1577
+ #ifdef V8_ENABLE_DIRECT_HANDLE
1336
1578
 
1337
1579
  template <typename T>
1338
1580
  V8_INLINE static Address ValueAsAddress(const T* value) {
@@ -1347,7 +1589,7 @@ class ValueHelper final {
1347
1589
  return *reinterpret_cast<T**>(slot);
1348
1590
  }
1349
1591
 
1350
- #else // !V8_ENABLE_DIRECT_LOCAL
1592
+ #else // !V8_ENABLE_DIRECT_HANDLE
1351
1593
 
1352
1594
  template <typename T>
1353
1595
  V8_INLINE static Address ValueAsAddress(const T* value) {
@@ -1359,7 +1601,7 @@ class ValueHelper final {
1359
1601
  return reinterpret_cast<T*>(slot);
1360
1602
  }
1361
1603
 
1362
- #endif // V8_ENABLE_DIRECT_LOCAL
1604
+ #endif // V8_ENABLE_DIRECT_HANDLE
1363
1605
  };
1364
1606
 
1365
1607
  /**
@@ -1383,14 +1625,17 @@ class HandleHelper final {
1383
1625
  if (rhs.IsEmpty()) return false;
1384
1626
  return lhs.ptr() == rhs.ptr();
1385
1627
  }
1386
-
1387
- static V8_EXPORT bool IsOnStack(const void* ptr);
1388
- static V8_EXPORT void VerifyOnStack(const void* ptr);
1389
- static V8_EXPORT void VerifyOnMainThread();
1390
1628
  };
1391
1629
 
1392
1630
  V8_EXPORT void VerifyHandleIsNonEmpty(bool is_empty);
1393
1631
 
1632
+ // These functions are here just to match friend declarations in
1633
+ // XxxCallbackInfo classes allowing these functions to access the internals
1634
+ // of the info objects. These functions are supposed to be called by debugger
1635
+ // macros.
1636
+ void PrintFunctionCallbackInfo(void* function_callback_info);
1637
+ void PrintPropertyCallbackInfo(void* property_callback_info);
1638
+
1394
1639
  } // namespace internal
1395
1640
  } // namespace v8
1396
1641