libv8-node 21.7.2.0-aarch64-linux-musl → 24.12.0.0-aarch64-linux-musl

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 (88) hide show
  1. checksums.yaml +4 -4
  2. data/ext/libv8-node/location.rb +3 -5
  3. data/ext/libv8-node/paths.rb +2 -0
  4. data/lib/libv8/node/version.rb +7 -4
  5. data/lib/libv8/node.rb +2 -0
  6. data/lib/libv8-node.rb +2 -0
  7. data/vendor/v8/aarch64-linux-musl/libv8/obj/libv8_monolith.a +0 -0
  8. data/vendor/v8/include/cppgc/allocation.h +11 -13
  9. data/vendor/v8/include/cppgc/default-platform.h +3 -2
  10. data/vendor/v8/include/cppgc/garbage-collected.h +8 -0
  11. data/vendor/v8/include/cppgc/heap-consistency.h +1 -1
  12. data/vendor/v8/include/cppgc/heap-statistics.h +2 -0
  13. data/vendor/v8/include/cppgc/internal/api-constants.h +2 -14
  14. data/vendor/v8/include/cppgc/internal/base-page-handle.h +2 -4
  15. data/vendor/v8/include/cppgc/internal/caged-heap-local-data.h +0 -4
  16. data/vendor/v8/include/cppgc/internal/caged-heap.h +0 -4
  17. data/vendor/v8/include/cppgc/internal/compiler-specific.h +9 -1
  18. data/vendor/v8/include/cppgc/internal/conditional-stack-allocated.h +41 -0
  19. data/vendor/v8/include/cppgc/internal/gc-info.h +12 -10
  20. data/vendor/v8/include/cppgc/internal/logging.h +3 -3
  21. data/vendor/v8/include/cppgc/internal/member-storage.h +69 -20
  22. data/vendor/v8/include/cppgc/internal/name-trait.h +5 -1
  23. data/vendor/v8/include/cppgc/internal/persistent-node.h +8 -3
  24. data/vendor/v8/include/cppgc/internal/pointer-policies.h +48 -11
  25. data/vendor/v8/include/cppgc/macros.h +21 -0
  26. data/vendor/v8/include/cppgc/member.h +70 -36
  27. data/vendor/v8/include/cppgc/name-provider.h +10 -0
  28. data/vendor/v8/include/cppgc/platform.h +11 -0
  29. data/vendor/v8/include/cppgc/type-traits.h +26 -4
  30. data/vendor/v8/include/cppgc/visitor.h +25 -1
  31. data/vendor/v8/include/libplatform/libplatform-export.h +2 -2
  32. data/vendor/v8/include/libplatform/v8-tracing.h +0 -1
  33. data/vendor/v8/include/v8-array-buffer.h +149 -46
  34. data/vendor/v8/include/v8-callbacks.h +100 -43
  35. data/vendor/v8/include/v8-container.h +54 -0
  36. data/vendor/v8/include/v8-context.h +92 -30
  37. data/vendor/v8/include/v8-cppgc.h +5 -56
  38. data/vendor/v8/include/v8-data.h +5 -0
  39. data/vendor/v8/include/v8-date.h +9 -0
  40. data/vendor/v8/include/v8-debug.h +11 -0
  41. data/vendor/v8/include/v8-embedder-heap.h +8 -20
  42. data/vendor/v8/include/v8-embedder-state-scope.h +2 -1
  43. data/vendor/v8/include/v8-exception.h +87 -9
  44. data/vendor/v8/include/v8-external-memory-accounter.h +60 -0
  45. data/vendor/v8/include/v8-fast-api-calls.h +67 -223
  46. data/vendor/v8/include/v8-forward.h +1 -0
  47. data/vendor/v8/include/v8-function-callback.h +296 -75
  48. data/vendor/v8/include/v8-function.h +11 -3
  49. data/vendor/v8/include/v8-handle-base.h +52 -82
  50. data/vendor/v8/include/v8-initialization.h +26 -1
  51. data/vendor/v8/include/v8-inspector.h +26 -27
  52. data/vendor/v8/include/v8-internal.h +960 -230
  53. data/vendor/v8/include/v8-isolate.h +347 -226
  54. data/vendor/v8/include/v8-local-handle.h +307 -55
  55. data/vendor/v8/include/v8-maybe.h +2 -1
  56. data/vendor/v8/include/v8-memory-span.h +284 -4
  57. data/vendor/v8/include/v8-message.h +11 -5
  58. data/vendor/v8/include/v8-metrics.h +15 -0
  59. data/vendor/v8/include/v8-microtask-queue.h +0 -5
  60. data/vendor/v8/include/v8-object.h +314 -41
  61. data/vendor/v8/include/v8-persistent-handle.h +29 -39
  62. data/vendor/v8/include/v8-platform.h +135 -77
  63. data/vendor/v8/include/v8-primitive.h +223 -5
  64. data/vendor/v8/include/v8-profiler.h +51 -2
  65. data/vendor/v8/include/v8-promise.h +2 -2
  66. data/vendor/v8/include/v8-proxy.h +0 -1
  67. data/vendor/v8/include/v8-regexp.h +0 -1
  68. data/vendor/v8/include/v8-sandbox.h +173 -0
  69. data/vendor/v8/include/v8-script.h +125 -27
  70. data/vendor/v8/include/v8-snapshot.h +130 -23
  71. data/vendor/v8/include/v8-source-location.h +6 -1
  72. data/vendor/v8/include/v8-statistics.h +10 -24
  73. data/vendor/v8/include/v8-template.h +320 -193
  74. data/vendor/v8/include/v8-trace-categories.h +23 -0
  75. data/vendor/v8/include/v8-traced-handle.h +99 -76
  76. data/vendor/v8/include/v8-typed-array.h +111 -7
  77. data/vendor/v8/include/v8-unwinder-state.h +2 -3
  78. data/vendor/v8/include/v8-unwinder.h +2 -1
  79. data/vendor/v8/include/v8-util.h +10 -125
  80. data/vendor/v8/include/v8-value-serializer-version.h +3 -3
  81. data/vendor/v8/include/v8-value.h +113 -6
  82. data/vendor/v8/include/v8-version.h +3 -3
  83. data/vendor/v8/include/v8-wasm.h +27 -0
  84. data/vendor/v8/include/v8-weak-callback-info.h +20 -12
  85. data/vendor/v8/include/v8.h +3 -3
  86. data/vendor/v8/include/v8config.h +116 -53
  87. metadata +55 -12
  88. data/vendor/v8/include/cppgc/ephemeron-pair.h +0 -30
@@ -140,8 +140,14 @@ class V8_EXPORT String : public Name {
140
140
  * Returns the number of bytes in the UTF-8 encoded
141
141
  * representation of this string.
142
142
  */
143
+ V8_DEPRECATED("Use Utf8LengthV2 instead.")
143
144
  int Utf8Length(Isolate* isolate) const;
144
145
 
146
+ /**
147
+ * Returns the number of bytes needed for the Utf8 encoding of this string.
148
+ */
149
+ size_t Utf8LengthV2(Isolate* isolate) const;
150
+
145
151
  /**
146
152
  * Returns whether this string is known to contain only one byte data,
147
153
  * i.e. ISO-8859-1 code points.
@@ -194,15 +200,72 @@ class V8_EXPORT String : public Name {
194
200
  };
195
201
 
196
202
  // 16-bit character codes.
203
+ V8_DEPRECATED("Use WriteV2 instead.")
197
204
  int Write(Isolate* isolate, uint16_t* buffer, int start = 0, int length = -1,
198
205
  int options = NO_OPTIONS) const;
199
206
  // One byte characters.
207
+ V8_DEPRECATED("Use WriteOneByteV2 instead.")
200
208
  int WriteOneByte(Isolate* isolate, uint8_t* buffer, int start = 0,
201
209
  int length = -1, int options = NO_OPTIONS) const;
202
210
  // UTF-8 encoded characters.
211
+ V8_DEPRECATED("Use WriteUtf8V2 instead.")
203
212
  int WriteUtf8(Isolate* isolate, char* buffer, int length = -1,
204
213
  int* nchars_ref = nullptr, int options = NO_OPTIONS) const;
205
214
 
215
+ struct WriteFlags {
216
+ enum {
217
+ kNone = 0,
218
+ // Indicates that the output string should be null-terminated. In that
219
+ // case, the output buffer must include sufficient space for the
220
+ // additional null character.
221
+ kNullTerminate = 1,
222
+ // Used by WriteUtf8 to replace orphan surrogate code units with the
223
+ // unicode replacement character. Needs to be set to guarantee valid UTF-8
224
+ // output.
225
+ kReplaceInvalidUtf8 = 2
226
+ };
227
+ };
228
+
229
+ /**
230
+ * Write the contents of the string to an external buffer.
231
+ *
232
+ * Copies length characters into the output buffer starting at offset. The
233
+ * output buffer must have sufficient space for all characters and the null
234
+ * terminator if null termination is requested through the flags.
235
+ *
236
+ * \param offset The position within the string at which copying begins.
237
+ * \param length The number of characters to copy from the string.
238
+ * \param buffer The buffer into which the string will be copied.
239
+ * \param flags Various flags that influence the behavior of this operation.
240
+ */
241
+ void WriteV2(Isolate* isolate, uint32_t offset, uint32_t length,
242
+ uint16_t* buffer, int flags = WriteFlags::kNone) const;
243
+ void WriteOneByteV2(Isolate* isolate, uint32_t offset, uint32_t length,
244
+ uint8_t* buffer, int flags = WriteFlags::kNone) const;
245
+
246
+ /**
247
+ * Encode the contents of the string as Utf8 into an external buffer.
248
+ *
249
+ * Encodes the characters of this string as Utf8 and writes them into the
250
+ * output buffer until either all characters were encoded or the buffer is
251
+ * full. Will not write partial UTF-8 sequences, preferring to stop before
252
+ * the end of the buffer. If null termination is requested, the output buffer
253
+ * will always be null terminated even if not all characters fit. In that
254
+ * case, the capacity must be at least one. The required size of the output
255
+ * buffer can be determined using Utf8Length().
256
+ *
257
+ * \param buffer The buffer into which the string will be written.
258
+ * \param capacity The number of bytes available in the output buffer.
259
+ * \param flags Various flags that influence the behavior of this operation.
260
+ * \param processed_characters_return The number of processed characters from
261
+ * the buffer.
262
+ * \return The number of bytes copied to the buffer including the null
263
+ * terminator (if written).
264
+ */
265
+ size_t WriteUtf8V2(Isolate* isolate, char* buffer, size_t capacity,
266
+ int flags = WriteFlags::kNone,
267
+ size_t* processed_characters_return = nullptr) const;
268
+
206
269
  /**
207
270
  * A zero length string.
208
271
  */
@@ -223,6 +286,12 @@ class V8_EXPORT String : public Name {
223
286
  */
224
287
  bool IsExternalOneByte() const;
225
288
 
289
+ /**
290
+ * Returns the internalized string. See `NewStringType::kInternalized` for
291
+ * details on internalized strings.
292
+ */
293
+ Local<String> InternalizeString(Isolate* isolate);
294
+
226
295
  class V8_EXPORT ExternalStringResourceBase {
227
296
  public:
228
297
  virtual ~ExternalStringResourceBase() = default;
@@ -234,6 +303,44 @@ class V8_EXPORT String : public Name {
234
303
  */
235
304
  virtual bool IsCacheable() const { return true; }
236
305
 
306
+ /**
307
+ * Internally V8 will call this Unaccount method when the external string
308
+ * resource should be unaccounted for. This method can be overridden in
309
+ * subclasses to control how allocated external bytes are accounted.
310
+ */
311
+ virtual void Unaccount(Isolate* isolate) {}
312
+
313
+ /**
314
+ * Returns an estimate of the memory occupied by this external string, to be
315
+ * used by V8 when producing a heap snapshot. If this function returns
316
+ * kDefaultMemoryEstimate, then V8 will estimate the external size based on
317
+ * the string length. This function should return only memory that is
318
+ * uniquely owned by this resource. If the resource has shared ownership of
319
+ * a secondary allocation, it can report that memory by implementing
320
+ * EstimateSharedMemoryUsage.
321
+ */
322
+ virtual size_t EstimateMemoryUsage() const {
323
+ return kDefaultMemoryEstimate;
324
+ }
325
+ static constexpr size_t kDefaultMemoryEstimate = static_cast<size_t>(-1);
326
+
327
+ class V8_EXPORT SharedMemoryUsageRecorder {
328
+ public:
329
+ /**
330
+ * Record that a shared allocation at the given location has the given
331
+ * size.
332
+ */
333
+ virtual void RecordSharedMemoryUsage(const void* location,
334
+ size_t size) = 0;
335
+ };
336
+
337
+ /**
338
+ * Estimates memory that this string resource may share with other string
339
+ * resources, to be used by V8 when producing a heap snapshot.
340
+ */
341
+ virtual void EstimateSharedMemoryUsage(
342
+ SharedMemoryUsageRecorder* recorder) const {}
343
+
237
344
  // Disallow copying and assigning.
238
345
  ExternalStringResourceBase(const ExternalStringResourceBase&) = delete;
239
346
  void operator=(const ExternalStringResourceBase&) = delete;
@@ -382,6 +489,8 @@ class V8_EXPORT String : public Name {
382
489
  * regardless of the encoding, otherwise return NULL. The encoding of the
383
490
  * string is returned in encoding_out.
384
491
  */
492
+ V8_INLINE ExternalStringResourceBase* GetExternalStringResourceBase(
493
+ v8::Isolate* isolate, Encoding* encoding_out) const;
385
494
  V8_INLINE ExternalStringResourceBase* GetExternalStringResourceBase(
386
495
  Encoding* encoding_out) const;
387
496
 
@@ -466,8 +575,20 @@ class V8_EXPORT String : public Name {
466
575
  * The string is not modified if the operation fails. See NewExternal for
467
576
  * information on the lifetime of the resource.
468
577
  */
578
+ V8_DEPRECATE_SOON("Use the version with the isolate argument instead.")
469
579
  bool MakeExternal(ExternalStringResource* resource);
470
580
 
581
+ /**
582
+ * Associate an external string resource with this string by transforming it
583
+ * in place so that existing references to this string in the JavaScript heap
584
+ * will use the external string resource. The external string resource's
585
+ * character contents need to be equivalent to this string.
586
+ * Returns true if the string has been changed to be an external string.
587
+ * The string is not modified if the operation fails. See NewExternal for
588
+ * information on the lifetime of the resource.
589
+ */
590
+ bool MakeExternal(Isolate* isolate, ExternalStringResource* resource);
591
+
471
592
  /**
472
593
  * Creates a new external string using the one-byte data defined in the given
473
594
  * resource. When the external string is no longer live on V8's heap the
@@ -488,8 +609,20 @@ class V8_EXPORT String : public Name {
488
609
  * The string is not modified if the operation fails. See NewExternal for
489
610
  * information on the lifetime of the resource.
490
611
  */
612
+ V8_DEPRECATE_SOON("Use the version with the isolate argument instead.")
491
613
  bool MakeExternal(ExternalOneByteStringResource* resource);
492
614
 
615
+ /**
616
+ * Associate an external string resource with this string by transforming it
617
+ * in place so that existing references to this string in the JavaScript heap
618
+ * will use the external string resource. The external string resource's
619
+ * character contents need to be equivalent to this string.
620
+ * Returns true if the string has been changed to be an external string.
621
+ * The string is not modified if the operation fails. See NewExternal for
622
+ * information on the lifetime of the resource.
623
+ */
624
+ bool MakeExternal(Isolate* isolate, ExternalOneByteStringResource* resource);
625
+
493
626
  /**
494
627
  * Returns true if this string can be made external, given the encoding for
495
628
  * the external string resource.
@@ -507,14 +640,19 @@ class V8_EXPORT String : public Name {
507
640
  * (e.g. due to an exception in the toString() method of the object)
508
641
  * then the length() method returns 0 and the * operator returns
509
642
  * NULL.
643
+ *
644
+ * WARNING: This will unconditionally copy the contents of the JavaScript
645
+ * string, and should be avoided in situations where performance is a concern.
646
+ * Consider using WriteUtf8() instead.
510
647
  */
511
648
  class V8_EXPORT Utf8Value {
512
649
  public:
513
- Utf8Value(Isolate* isolate, Local<v8::Value> obj);
650
+ Utf8Value(Isolate* isolate, Local<v8::Value> obj,
651
+ WriteOptions options = REPLACE_INVALID_UTF8);
514
652
  ~Utf8Value();
515
653
  char* operator*() { return str_; }
516
654
  const char* operator*() const { return str_; }
517
- int length() const { return length_; }
655
+ size_t length() const { return length_; }
518
656
 
519
657
  // Disallow copying and assigning.
520
658
  Utf8Value(const Utf8Value&) = delete;
@@ -522,22 +660,29 @@ class V8_EXPORT String : public Name {
522
660
 
523
661
  private:
524
662
  char* str_;
525
- int length_;
663
+ size_t length_;
526
664
  };
527
665
 
528
666
  /**
529
667
  * Converts an object to a two-byte (UTF-16-encoded) string.
668
+ *
530
669
  * If conversion to a string fails (eg. due to an exception in the toString()
531
670
  * method of the object) then the length() method returns 0 and the * operator
532
671
  * returns NULL.
672
+ *
673
+ * WARNING: This will unconditionally copy the contents of the JavaScript
674
+ * string, and should be avoided in situations where performance is a concern.
533
675
  */
534
676
  class V8_EXPORT Value {
535
677
  public:
678
+ V8_DEPRECATE_SOON(
679
+ "Prefer using String::ValueView if you can, or string->Write to a "
680
+ "buffer if you cannot.")
536
681
  Value(Isolate* isolate, Local<v8::Value> obj);
537
682
  ~Value();
538
683
  uint16_t* operator*() { return str_; }
539
684
  const uint16_t* operator*() const { return str_; }
540
- int length() const { return length_; }
685
+ uint32_t length() const { return length_; }
541
686
 
542
687
  // Disallow copying and assigning.
543
688
  Value(const Value&) = delete;
@@ -545,7 +690,56 @@ class V8_EXPORT String : public Name {
545
690
 
546
691
  private:
547
692
  uint16_t* str_;
548
- int length_;
693
+ uint32_t length_;
694
+ };
695
+
696
+ /**
697
+ * Returns a view onto a string's contents.
698
+ *
699
+ * WARNING: This does not copy the string's contents, and will therefore be
700
+ * invalidated if the GC can move the string while the ValueView is alive. It
701
+ * is therefore required that no GC or allocation can happen while there is an
702
+ * active ValueView. This requirement may be relaxed in the future.
703
+ *
704
+ * V8 strings are either encoded as one-byte or two-bytes per character.
705
+ */
706
+ class V8_EXPORT ValueView {
707
+ public:
708
+ ValueView(Isolate* isolate, Local<v8::String> str);
709
+ ~ValueView();
710
+ const uint8_t* data8() const {
711
+ #if V8_ENABLE_CHECKS
712
+ CheckOneByte(true);
713
+ #endif
714
+ return data8_;
715
+ }
716
+ const uint16_t* data16() const {
717
+ #if V8_ENABLE_CHECKS
718
+ CheckOneByte(false);
719
+ #endif
720
+ return data16_;
721
+ }
722
+ uint32_t length() const { return length_; }
723
+ bool is_one_byte() const { return is_one_byte_; }
724
+
725
+ // Disallow copying and assigning.
726
+ ValueView(const ValueView&) = delete;
727
+ void operator=(const ValueView&) = delete;
728
+
729
+ private:
730
+ void CheckOneByte(bool is_one_byte) const;
731
+
732
+ Local<v8::String> flat_str_;
733
+ union {
734
+ const uint8_t* data8_;
735
+ const uint16_t* data16_;
736
+ };
737
+ uint32_t length_;
738
+ bool is_one_byte_;
739
+ // Avoid exposing the internal DisallowGarbageCollection scope.
740
+ alignas(internal::Internals::
741
+ kDisallowGarbageCollectionAlign) char no_gc_debug_scope_
742
+ [internal::Internals::kDisallowGarbageCollectionSize];
549
743
  };
550
744
 
551
745
  private:
@@ -625,6 +819,8 @@ class V8_EXPORT Symbol : public Name {
625
819
  static Local<Symbol> GetToPrimitive(Isolate* isolate);
626
820
  static Local<Symbol> GetToStringTag(Isolate* isolate);
627
821
  static Local<Symbol> GetUnscopables(Isolate* isolate);
822
+ static Local<Symbol> GetDispose(Isolate* isolate);
823
+ static Local<Symbol> GetAsyncDispose(Isolate* isolate);
628
824
 
629
825
  V8_INLINE static Symbol* Cast(Data* data) {
630
826
  #ifdef V8_ENABLE_CHECKS
@@ -811,6 +1007,28 @@ String::ExternalStringResource* String::GetExternalStringResource() const {
811
1007
  return result;
812
1008
  }
813
1009
 
1010
+ String::ExternalStringResourceBase* String::GetExternalStringResourceBase(
1011
+ v8::Isolate* isolate, String::Encoding* encoding_out) const {
1012
+ using A = internal::Address;
1013
+ using I = internal::Internals;
1014
+ A obj = internal::ValueHelper::ValueAsAddress(this);
1015
+ int type = I::GetInstanceType(obj) & I::kStringRepresentationAndEncodingMask;
1016
+ *encoding_out = static_cast<Encoding>(type & I::kStringEncodingMask);
1017
+ ExternalStringResourceBase* resource;
1018
+ if (type == I::kExternalOneByteRepresentationTag ||
1019
+ type == I::kExternalTwoByteRepresentationTag) {
1020
+ A value = I::ReadExternalPointerField<internal::kExternalStringResourceTag>(
1021
+ isolate, obj, I::kStringResourceOffset);
1022
+ resource = reinterpret_cast<ExternalStringResourceBase*>(value);
1023
+ } else {
1024
+ resource = GetExternalStringResourceBaseSlow(encoding_out);
1025
+ }
1026
+ #ifdef V8_ENABLE_CHECKS
1027
+ VerifyExternalStringResourceBase(resource, *encoding_out);
1028
+ #endif
1029
+ return resource;
1030
+ }
1031
+
814
1032
  String::ExternalStringResourceBase* String::GetExternalStringResourceBase(
815
1033
  String::Encoding* encoding_out) const {
816
1034
  using A = internal::Address;
@@ -418,8 +418,11 @@ class V8_EXPORT CpuProfiler {
418
418
  * Synchronously collect current stack sample in all profilers attached to
419
419
  * the |isolate|. The call does not affect number of ticks recorded for
420
420
  * the current top node.
421
+ * |trace_id| is an optional identifier set to the collected sample.
422
+ * this is useful to associate the sample with a trace event.
421
423
  */
422
- static void CollectSample(Isolate* isolate);
424
+ static void CollectSample(
425
+ Isolate* isolate, const std::optional<uint64_t> trace_id = std::nullopt);
423
426
 
424
427
  /**
425
428
  * Disposes the CPU profiler object.
@@ -899,9 +902,28 @@ class V8_EXPORT EmbedderGraph {
899
902
  /**
900
903
  * Returns a node corresponding to the given V8 value. Ownership is not
901
904
  * transferred. The result pointer is valid while the graph is alive.
905
+ *
906
+ * For now the variant that takes v8::Data is not marked as abstract for
907
+ * compatibility, but embedders who subclass EmbedderGraph are expected to
908
+ * implement it. Then in the implementation of the variant that takes
909
+ * v8::Value, they can simply forward the call to the one that takes
910
+ * v8::Local<v8::Data>.
902
911
  */
903
912
  virtual Node* V8Node(const v8::Local<v8::Value>& value) = 0;
904
913
 
914
+ /**
915
+ * Returns a node corresponding to the given V8 value. Ownership is not
916
+ * transferred. The result pointer is valid while the graph is alive.
917
+ *
918
+ * For API compatibility, this default implementation just checks that the
919
+ * data is a v8::Value and forward it to the variant that takes v8::Value,
920
+ * which is currently required to be implemented. In the future we'll remove
921
+ * the v8::Value variant, and make this variant that takes v8::Data abstract
922
+ * instead. If the embedder subclasses v8::EmbedderGraph and also use
923
+ * v8::TracedReference<v8::Data>, they must override this variant.
924
+ */
925
+ virtual Node* V8Node(const v8::Local<v8::Data>& value);
926
+
905
927
  /**
906
928
  * Adds the given node to the graph and takes ownership of the node.
907
929
  * Returns a raw pointer to the node that is valid while the graph is alive.
@@ -918,6 +940,15 @@ class V8_EXPORT EmbedderGraph {
918
940
  */
919
941
  virtual void AddEdge(Node* from, Node* to, const char* name = nullptr) = 0;
920
942
 
943
+ /**
944
+ * Adds a count of bytes that are not associated with any particular Node.
945
+ * An embedder may use this to represent the size of nodes which were omitted
946
+ * from this EmbedderGraph despite being retained by the graph, or other
947
+ * overhead costs. This number will contribute to the total size in a heap
948
+ * snapshot, without being represented in the object graph.
949
+ */
950
+ virtual void AddNativeSize(size_t size) {}
951
+
921
952
  virtual ~EmbedderGraph() = default;
922
953
  };
923
954
 
@@ -956,7 +987,7 @@ class V8_EXPORT HeapProfiler {
956
987
 
957
988
  /**
958
989
  * Callback function invoked during heap snapshot generation to retrieve
959
- * the detachedness state of an object referenced by a TracedReference.
990
+ * the detachedness state of a JS object referenced by a TracedReference.
960
991
  *
961
992
  * The callback takes Local<Value> as parameter to allow the embedder to
962
993
  * unpack the TracedReference into a Local and reuse that Local for different
@@ -1090,6 +1121,12 @@ class V8_EXPORT HeapProfiler {
1090
1121
  ObjectNameResolver* global_object_name_resolver = nullptr,
1091
1122
  bool hide_internals = true, bool capture_numeric_value = false);
1092
1123
 
1124
+ /**
1125
+ * Obtains list of Detached JS Wrapper Objects. This functon calls garbage
1126
+ * collection, then iterates over traced handles in the isolate
1127
+ */
1128
+ std::vector<v8::Local<v8::Value>> GetDetachedJSWrapperObjects();
1129
+
1093
1130
  /**
1094
1131
  * Starts tracking of heap objects population statistics. After calling
1095
1132
  * this method, all heap objects relocations done by the garbage collector
@@ -1179,6 +1216,18 @@ class V8_EXPORT HeapProfiler {
1179
1216
 
1180
1217
  void SetGetDetachednessCallback(GetDetachednessCallback callback, void* data);
1181
1218
 
1219
+ /**
1220
+ * Returns whether the heap profiler is currently taking a snapshot.
1221
+ */
1222
+ bool IsTakingSnapshot();
1223
+
1224
+ /**
1225
+ * Allocates a copy of the provided string within the heap snapshot generator
1226
+ * and returns a pointer to the copy. May only be called during heap snapshot
1227
+ * generation.
1228
+ */
1229
+ const char* CopyNameForHeapSnapshot(const char* name);
1230
+
1182
1231
  /**
1183
1232
  * Default value of persistent handle class ID. Must not be used to
1184
1233
  * define a class. Can be used to reset a class of a persistent
@@ -14,7 +14,7 @@ namespace v8 {
14
14
  class Context;
15
15
 
16
16
  #ifndef V8_PROMISE_INTERNAL_FIELD_COUNT
17
- // The number of required internal fields can be defined by embedder.
17
+ // Defined using gn arg `v8_promise_internal_field_count`.
18
18
  #define V8_PROMISE_INTERNAL_FIELD_COUNT 0
19
19
  #endif
20
20
 
@@ -115,7 +115,7 @@ class V8_EXPORT Promise : public Object {
115
115
  return static_cast<Promise*>(value);
116
116
  }
117
117
 
118
- static const int kEmbedderFieldCount = V8_PROMISE_INTERNAL_FIELD_COUNT;
118
+ static constexpr int kEmbedderFieldCount = V8_PROMISE_INTERNAL_FIELD_COUNT;
119
119
 
120
120
  private:
121
121
  Promise();
@@ -1,4 +1,3 @@
1
-
2
1
  // Copyright 2021 the V8 project authors. All rights reserved.
3
2
  // Use of this source code is governed by a BSD-style license that can be
4
3
  // found in the LICENSE file.
@@ -1,4 +1,3 @@
1
-
2
1
  // Copyright 2021 the V8 project authors. All rights reserved.
3
2
  // Use of this source code is governed by a BSD-style license that can be
4
3
  // found in the LICENSE file.
@@ -0,0 +1,173 @@
1
+ // Copyright 2024 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 INCLUDE_V8_SANDBOX_H_
6
+ #define INCLUDE_V8_SANDBOX_H_
7
+
8
+ #include <cstdint>
9
+
10
+ #include "v8-internal.h" // NOLINT(build/include_directory)
11
+ #include "v8config.h" // NOLINT(build/include_directory)
12
+
13
+ namespace v8 {
14
+
15
+ /**
16
+ * A pointer tag used for wrapping and unwrapping `CppHeap` pointers as used
17
+ * with JS API wrapper objects that rely on `v8::Object::Wrap()` and
18
+ * `v8::Object::Unwrap()`.
19
+ *
20
+ * The CppHeapPointers use a range-based type checking scheme, where on access
21
+ * to a pointer, the actual type of the pointer is checked to be within a
22
+ * specified range of types. This allows supporting type hierarchies, where a
23
+ * type check for a supertype must succeed for any subtype.
24
+ *
25
+ * The tag is currently in practice limited to 15 bits since it needs to fit
26
+ * together with a marking bit into the unused parts of a pointer.
27
+ */
28
+ enum class CppHeapPointerTag : uint16_t {
29
+ kFirstTag = 0,
30
+ kNullTag = 0,
31
+
32
+ /**
33
+ * The lower type ids are reserved for the embedder to assign. For that, the
34
+ * main requirement is that all (transitive) child classes of a given parent
35
+ * class have type ids in the same range, and that there are no unrelated
36
+ * types in that range. For example, given the following type hierarchy:
37
+ *
38
+ * A F
39
+ * / \
40
+ * B E
41
+ * / \
42
+ * C D
43
+ *
44
+ * a potential type id assignment that satistifes these requirements is
45
+ * {C: 0, D: 1, B: 2, A: 3, E: 4, F: 5}. With that, the type check for type A
46
+ * would check for the range [0, 4], while the check for B would check range
47
+ * [0, 2], and for F it would simply check [5, 5].
48
+ *
49
+ * In addition, there is an option for performance tweaks: if the size of the
50
+ * type range corresponding to a supertype is a power of two and starts at a
51
+ * power of two (e.g. [0x100, 0x13f]), then the compiler can often optimize
52
+ * the type check to use even fewer instructions (essentially replace a AND +
53
+ * SUB with a single AND).
54
+ */
55
+
56
+ kDefaultTag = 0x7000,
57
+
58
+ kZappedEntryTag = 0x7ffd,
59
+ kEvacuationEntryTag = 0x7ffe,
60
+ kFreeEntryTag = 0x7fff,
61
+ // The tags are limited to 15 bits, so the last tag is 0x7fff.
62
+ kLastTag = 0x7fff,
63
+ };
64
+
65
+ // Convenience struct to represent tag ranges. This is used for type checks
66
+ // against supertypes, which cover a range of types (their subtypes).
67
+ // Both the lower- and the upper bound are inclusive. In other words, this
68
+ // struct represents the range [lower_bound, upper_bound].
69
+ // TODO(saelo): reuse internal::TagRange here.
70
+ struct CppHeapPointerTagRange {
71
+ constexpr CppHeapPointerTagRange(CppHeapPointerTag lower,
72
+ CppHeapPointerTag upper)
73
+ : lower_bound(lower), upper_bound(upper) {}
74
+ CppHeapPointerTag lower_bound;
75
+ CppHeapPointerTag upper_bound;
76
+
77
+ // Check whether the tag of the given CppHeapPointerTable entry is within
78
+ // this range. This method encodes implementation details of the
79
+ // CppHeapPointerTable, which is necessary as it is used by
80
+ // ReadCppHeapPointerField below.
81
+ // Returns true if the check is successful and the tag of the given entry is
82
+ // within this range, false otherwise.
83
+ bool CheckTagOf(uint64_t entry) {
84
+ // Note: the cast to uint32_t is important here. Otherwise, the uint16_t's
85
+ // would be promoted to int in the range check below, which would result in
86
+ // undefined behavior (signed integer undeflow) if the actual value is less
87
+ // than the lower bound. Then, the compiler would take advantage of the
88
+ // undefined behavior and turn the range check into a simple
89
+ // `actual_tag <= last_tag` comparison, which is incorrect.
90
+ uint32_t actual_tag = static_cast<uint16_t>(entry);
91
+ // The actual_tag is shifted to the left by one and contains the marking
92
+ // bit in the LSB. To ignore that during the type check, simply add one to
93
+ // the (shifted) range.
94
+ constexpr int kTagShift = internal::kCppHeapPointerTagShift;
95
+ uint32_t first_tag = static_cast<uint32_t>(lower_bound) << kTagShift;
96
+ uint32_t last_tag = (static_cast<uint32_t>(upper_bound) << kTagShift) + 1;
97
+ return actual_tag >= first_tag && actual_tag <= last_tag;
98
+ }
99
+ };
100
+
101
+ constexpr CppHeapPointerTagRange kAnyCppHeapPointer(
102
+ CppHeapPointerTag::kFirstTag, CppHeapPointerTag::kLastTag);
103
+
104
+ class SandboxHardwareSupport {
105
+ public:
106
+ /**
107
+ * Initialize sandbox hardware support. This needs to be called before
108
+ * creating any thread that might access sandbox memory since it sets up
109
+ * hardware permissions to the memory that will be inherited on clone.
110
+ */
111
+ V8_EXPORT static void InitializeBeforeThreadCreation();
112
+ };
113
+
114
+ namespace internal {
115
+
116
+ #ifdef V8_COMPRESS_POINTERS
117
+ V8_INLINE static Address* GetCppHeapPointerTableBase(v8::Isolate* isolate) {
118
+ Address addr = reinterpret_cast<Address>(isolate) +
119
+ Internals::kIsolateCppHeapPointerTableOffset +
120
+ Internals::kExternalPointerTableBasePointerOffset;
121
+ return *reinterpret_cast<Address**>(addr);
122
+ }
123
+ #endif // V8_COMPRESS_POINTERS
124
+
125
+ template <typename T>
126
+ V8_INLINE static T* ReadCppHeapPointerField(v8::Isolate* isolate,
127
+ Address heap_object_ptr, int offset,
128
+ CppHeapPointerTagRange tag_range) {
129
+ #ifdef V8_COMPRESS_POINTERS
130
+ // See src/sandbox/cppheap-pointer-table-inl.h. Logic duplicated here so
131
+ // it can be inlined and doesn't require an additional call.
132
+ const CppHeapPointerHandle handle =
133
+ Internals::ReadRawField<CppHeapPointerHandle>(heap_object_ptr, offset);
134
+ const uint32_t index = handle >> kExternalPointerIndexShift;
135
+ const Address* table = GetCppHeapPointerTableBase(isolate);
136
+ const std::atomic<Address>* ptr =
137
+ reinterpret_cast<const std::atomic<Address>*>(&table[index]);
138
+ Address entry = std::atomic_load_explicit(ptr, std::memory_order_relaxed);
139
+
140
+ Address pointer = entry;
141
+ if (V8_LIKELY(tag_range.CheckTagOf(entry))) {
142
+ pointer = entry >> kCppHeapPointerPayloadShift;
143
+ } else {
144
+ // If the type check failed, we simply return nullptr here. That way:
145
+ // 1. The null handle always results in nullptr being returned here, which
146
+ // is a desired property. Otherwise, we would need an explicit check for
147
+ // the null handle above, and therefore an additional branch. This
148
+ // works because the 0th entry of the table always contains nullptr
149
+ // tagged with the null tag (i.e. an all-zeros entry). As such,
150
+ // regardless of whether the type check succeeds, the result will
151
+ // always be nullptr.
152
+ // 2. The returned pointer is guaranteed to crash even on platforms with
153
+ // top byte ignore (TBI), such as Arm64. The alternative would be to
154
+ // simply return the original entry with the left-shifted payload.
155
+ // However, due to TBI, an access to that may not always result in a
156
+ // crash (specifically, if the second most significant byte happens to
157
+ // be zero). In addition, there shouldn't be a difference on Arm64
158
+ // between returning nullptr or the original entry, since it will
159
+ // simply compile to a `csel x0, x8, xzr, lo` instead of a
160
+ // `csel x0, x10, x8, lo` instruction.
161
+ pointer = 0;
162
+ }
163
+ return reinterpret_cast<T*>(pointer);
164
+ #else // !V8_COMPRESS_POINTERS
165
+ return reinterpret_cast<T*>(
166
+ Internals::ReadRawField<Address>(heap_object_ptr, offset));
167
+ #endif // !V8_COMPRESS_POINTERS
168
+ }
169
+
170
+ } // namespace internal
171
+ } // namespace v8
172
+
173
+ #endif // INCLUDE_V8_SANDBOX_H_