libv8-node 20.12.1.0-arm64-darwin → 21.7.2.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 (44) 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/internal/api-constants.h +23 -4
  5. data/vendor/v8/include/cppgc/internal/caged-heap-local-data.h +16 -6
  6. data/vendor/v8/include/cppgc/internal/caged-heap.h +12 -5
  7. data/vendor/v8/include/cppgc/internal/gc-info.h +82 -91
  8. data/vendor/v8/include/cppgc/internal/member-storage.h +16 -8
  9. data/vendor/v8/include/cppgc/member.h +25 -0
  10. data/vendor/v8/include/cppgc/persistent.h +4 -0
  11. data/vendor/v8/include/cppgc/platform.h +6 -1
  12. data/vendor/v8/include/cppgc/sentinel-pointer.h +7 -0
  13. data/vendor/v8/include/cppgc/source-location.h +2 -78
  14. data/vendor/v8/include/cppgc/trace-trait.h +8 -0
  15. data/vendor/v8/include/cppgc/visitor.h +82 -4
  16. data/vendor/v8/include/libplatform/libplatform.h +7 -1
  17. data/vendor/v8/include/v8-callbacks.h +52 -8
  18. data/vendor/v8/include/v8-context.h +10 -13
  19. data/vendor/v8/include/v8-embedder-heap.h +12 -0
  20. data/vendor/v8/include/v8-fast-api-calls.h +23 -5
  21. data/vendor/v8/include/v8-function-callback.h +11 -15
  22. data/vendor/v8/include/v8-function.h +6 -0
  23. data/vendor/v8/include/v8-handle-base.h +185 -0
  24. data/vendor/v8/include/v8-inspector.h +31 -1
  25. data/vendor/v8/include/v8-internal.h +109 -77
  26. data/vendor/v8/include/v8-isolate.h +130 -89
  27. data/vendor/v8/include/v8-local-handle.h +134 -89
  28. data/vendor/v8/include/v8-object.h +71 -69
  29. data/vendor/v8/include/v8-persistent-handle.h +65 -89
  30. data/vendor/v8/include/v8-platform.h +140 -9
  31. data/vendor/v8/include/v8-primitive.h +12 -8
  32. data/vendor/v8/include/v8-profiler.h +16 -2
  33. data/vendor/v8/include/v8-script.h +27 -3
  34. data/vendor/v8/include/v8-snapshot.h +4 -1
  35. data/vendor/v8/include/v8-source-location.h +92 -0
  36. data/vendor/v8/include/v8-statistics.h +36 -1
  37. data/vendor/v8/include/v8-traced-handle.h +37 -54
  38. data/vendor/v8/include/v8-unwinder.h +1 -1
  39. data/vendor/v8/include/v8-util.h +15 -13
  40. data/vendor/v8/include/v8-value-serializer.h +14 -0
  41. data/vendor/v8/include/v8-value.h +14 -0
  42. data/vendor/v8/include/v8-version.h +3 -3
  43. data/vendor/v8/include/v8config.h +19 -10
  44. metadata +4 -2
@@ -26,7 +26,7 @@ class PersistentValueMap;
26
26
  class Value;
27
27
 
28
28
  namespace api_internal {
29
- V8_EXPORT Value* Eternalize(v8::Isolate* isolate, Value* handle);
29
+ V8_EXPORT internal::Address* Eternalize(v8::Isolate* isolate, Value* handle);
30
30
  V8_EXPORT internal::Address* CopyGlobalReference(internal::Address* from);
31
31
  V8_EXPORT void DisposeGlobal(internal::Address* global_handle);
32
32
  V8_EXPORT void MakeWeak(internal::Address** location_addr);
@@ -34,7 +34,7 @@ V8_EXPORT void* ClearWeak(internal::Address* location);
34
34
  V8_EXPORT void AnnotateStrongRetainer(internal::Address* location,
35
35
  const char* label);
36
36
  V8_EXPORT internal::Address* GlobalizeReference(internal::Isolate* isolate,
37
- internal::Address* handle);
37
+ internal::Address value);
38
38
  V8_EXPORT void MoveGlobalReference(internal::Address** from,
39
39
  internal::Address** to);
40
40
  } // namespace api_internal
@@ -44,35 +44,28 @@ V8_EXPORT void MoveGlobalReference(internal::Address** from,
44
44
  * isolate.
45
45
  */
46
46
  template <class T>
47
- class Eternal {
47
+ class Eternal : public IndirectHandleBase {
48
48
  public:
49
- V8_INLINE Eternal() : val_(nullptr) {}
49
+ V8_INLINE Eternal() = default;
50
+
50
51
  template <class S>
51
- V8_INLINE Eternal(Isolate* isolate, Local<S> handle) : val_(nullptr) {
52
+ V8_INLINE Eternal(Isolate* isolate, Local<S> handle) {
52
53
  Set(isolate, handle);
53
54
  }
55
+
54
56
  // Can only be safely called if already set.
55
57
  V8_INLINE Local<T> Get(Isolate* isolate) const {
56
58
  // The eternal handle will never go away, so as with the roots, we don't
57
59
  // even need to open a handle.
58
- return Local<T>(internal::ValueHelper::SlotAsValue<T>(val_));
60
+ return Local<T>::FromSlot(slot());
59
61
  }
60
62
 
61
- V8_INLINE bool IsEmpty() const { return val_ == nullptr; }
62
-
63
63
  template <class S>
64
64
  void Set(Isolate* isolate, Local<S> handle) {
65
65
  static_assert(std::is_base_of<T, S>::value, "type check");
66
- val_ = reinterpret_cast<T*>(
67
- api_internal::Eternalize(isolate, reinterpret_cast<Value*>(*handle)));
68
- }
69
-
70
- private:
71
- V8_INLINE internal::Address address() const {
72
- return *reinterpret_cast<internal::Address*>(val_);
66
+ slot() =
67
+ api_internal::Eternalize(isolate, *handle.template UnsafeAs<Value>());
73
68
  }
74
-
75
- T* val_;
76
69
  };
77
70
 
78
71
  namespace api_internal {
@@ -95,7 +88,7 @@ V8_EXPORT void MakeWeak(internal::Address* location, void* data,
95
88
  *
96
89
  */
97
90
  template <class T>
98
- class PersistentBase {
91
+ class PersistentBase : public IndirectHandleBase {
99
92
  public:
100
93
  /**
101
94
  * If non-empty, destroy the underlying storage cell
@@ -117,9 +110,6 @@ class PersistentBase {
117
110
  template <class S>
118
111
  V8_INLINE void Reset(Isolate* isolate, const PersistentBase<S>& other);
119
112
 
120
- V8_INLINE bool IsEmpty() const { return val_ == nullptr; }
121
- V8_INLINE void Empty() { val_ = 0; }
122
-
123
113
  V8_INLINE Local<T> Get(Isolate* isolate) const {
124
114
  return Local<T>::New(isolate, *this);
125
115
  }
@@ -217,18 +207,14 @@ class PersistentBase {
217
207
  template <class F1, class F2>
218
208
  friend class PersistentValueVector;
219
209
  friend class Object;
220
- friend class internal::HandleHelper;
210
+ friend class internal::ValueHelper;
221
211
 
222
- explicit V8_INLINE PersistentBase(T* val) : val_(val) {}
223
- V8_INLINE T* operator*() const { return this->val_; }
224
- V8_INLINE internal::Address address() const {
225
- return *reinterpret_cast<internal::Address*>(val_);
226
- }
212
+ V8_INLINE PersistentBase() = default;
227
213
 
228
- V8_INLINE static T* New(Isolate* isolate, Local<T> that);
229
- V8_INLINE static T* New(Isolate* isolate, T* that);
214
+ V8_INLINE explicit PersistentBase(internal::Address* location)
215
+ : IndirectHandleBase(location) {}
230
216
 
231
- T* val_;
217
+ V8_INLINE static internal::Address* New(Isolate* isolate, T* that);
232
218
  };
233
219
 
234
220
  /**
@@ -279,16 +265,17 @@ class Persistent : public PersistentBase<T> {
279
265
  /**
280
266
  * A Persistent with no storage cell.
281
267
  */
282
- V8_INLINE Persistent() : PersistentBase<T>(nullptr) {}
268
+ V8_INLINE Persistent() = default;
269
+
283
270
  /**
284
271
  * Construct a Persistent from a Local.
285
272
  * When the Local is non-empty, a new storage cell is created
286
273
  * pointing to the same object, and no flags are set.
287
274
  */
288
-
289
275
  template <class S>
290
276
  V8_INLINE Persistent(Isolate* isolate, Local<S> that)
291
- : PersistentBase<T>(PersistentBase<T>::New(isolate, that)) {
277
+ : PersistentBase<T>(
278
+ PersistentBase<T>::New(isolate, that.template value<S>())) {
292
279
  static_assert(std::is_base_of<T, S>::value, "type check");
293
280
  }
294
281
 
@@ -299,20 +286,22 @@ class Persistent : public PersistentBase<T> {
299
286
  */
300
287
  template <class S, class M2>
301
288
  V8_INLINE Persistent(Isolate* isolate, const Persistent<S, M2>& that)
302
- : PersistentBase<T>(PersistentBase<T>::New(isolate, *that)) {
289
+ : PersistentBase<T>(
290
+ PersistentBase<T>::New(isolate, that.template value<S>())) {
303
291
  static_assert(std::is_base_of<T, S>::value, "type check");
304
292
  }
293
+
305
294
  /**
306
295
  * The copy constructors and assignment operator create a Persistent
307
296
  * exactly as the Persistent constructor, but the Copy function from the
308
297
  * traits class is called, allowing the setting of flags based on the
309
298
  * copied Persistent.
310
299
  */
311
- V8_INLINE Persistent(const Persistent& that) : PersistentBase<T>(nullptr) {
300
+ V8_INLINE Persistent(const Persistent& that) : PersistentBase<T>() {
312
301
  Copy(that);
313
302
  }
314
303
  template <class S, class M2>
315
- V8_INLINE Persistent(const Persistent<S, M2>& that) : PersistentBase<T>(0) {
304
+ V8_INLINE Persistent(const Persistent<S, M2>& that) : PersistentBase<T>() {
316
305
  Copy(that);
317
306
  }
318
307
  V8_INLINE Persistent& operator=(const Persistent& that) {
@@ -324,6 +313,7 @@ class Persistent : public PersistentBase<T> {
324
313
  Copy(that);
325
314
  return *this;
326
315
  }
316
+
327
317
  /**
328
318
  * The destructor will dispose the Persistent based on the
329
319
  * kResetInDestructor flags in the traits class. Since not calling dispose
@@ -334,20 +324,21 @@ class Persistent : public PersistentBase<T> {
334
324
  }
335
325
 
336
326
  // TODO(dcarney): this is pretty useless, fix or remove
337
- template <class S>
338
- V8_INLINE static Persistent<T>& Cast(const Persistent<S>& that) {
327
+ template <class S, class M2>
328
+ V8_INLINE static Persistent<T, M>& Cast(const Persistent<S, M2>& that) {
339
329
  #ifdef V8_ENABLE_CHECKS
340
330
  // If we're going to perform the type check then we have to check
341
331
  // that the handle isn't empty before doing the checked cast.
342
- if (!that.IsEmpty()) T::Cast(*that);
332
+ if (!that.IsEmpty()) T::Cast(that.template value<S>());
343
333
  #endif
344
- return reinterpret_cast<Persistent<T>&>(const_cast<Persistent<S>&>(that));
334
+ return reinterpret_cast<Persistent<T, M>&>(
335
+ const_cast<Persistent<S, M2>&>(that));
345
336
  }
346
337
 
347
338
  // TODO(dcarney): this is pretty useless, fix or remove
348
- template <class S>
349
- V8_INLINE Persistent<S>& As() const {
350
- return Persistent<S>::Cast(*this);
339
+ template <class S, class M2>
340
+ V8_INLINE Persistent<S, M2>& As() const {
341
+ return Persistent<S, M2>::Cast(*this);
351
342
  }
352
343
 
353
344
  private:
@@ -360,7 +351,6 @@ class Persistent : public PersistentBase<T> {
360
351
  template <class F>
361
352
  friend class ReturnValue;
362
353
 
363
- explicit V8_INLINE Persistent(T* that) : PersistentBase<T>(that) {}
364
354
  template <class S, class M2>
365
355
  V8_INLINE void Copy(const Persistent<S, M2>& that);
366
356
  };
@@ -376,7 +366,7 @@ class Global : public PersistentBase<T> {
376
366
  /**
377
367
  * A Global with no storage cell.
378
368
  */
379
- V8_INLINE Global() : PersistentBase<T>(nullptr) {}
369
+ V8_INLINE Global() = default;
380
370
 
381
371
  /**
382
372
  * Construct a Global from a Local.
@@ -385,7 +375,8 @@ class Global : public PersistentBase<T> {
385
375
  */
386
376
  template <class S>
387
377
  V8_INLINE Global(Isolate* isolate, Local<S> that)
388
- : PersistentBase<T>(PersistentBase<T>::New(isolate, that)) {
378
+ : PersistentBase<T>(
379
+ PersistentBase<T>::New(isolate, that.template value<S>())) {
389
380
  static_assert(std::is_base_of<T, S>::value, "type check");
390
381
  }
391
382
 
@@ -396,7 +387,8 @@ class Global : public PersistentBase<T> {
396
387
  */
397
388
  template <class S>
398
389
  V8_INLINE Global(Isolate* isolate, const PersistentBase<S>& that)
399
- : PersistentBase<T>(PersistentBase<T>::New(isolate, that.val_)) {
390
+ : PersistentBase<T>(
391
+ PersistentBase<T>::New(isolate, that.template value<S>())) {
400
392
  static_assert(std::is_base_of<T, S>::value, "type check");
401
393
  }
402
394
 
@@ -446,17 +438,11 @@ class V8_EXPORT PersistentHandleVisitor {
446
438
  };
447
439
 
448
440
  template <class T>
449
- T* PersistentBase<T>::New(Isolate* isolate, Local<T> that) {
450
- return PersistentBase<T>::New(isolate,
451
- internal::ValueHelper::ValueAsSlot(*that));
452
- }
453
-
454
- template <class T>
455
- T* PersistentBase<T>::New(Isolate* isolate, T* that) {
456
- if (that == nullptr) return nullptr;
457
- internal::Address* p = reinterpret_cast<internal::Address*>(that);
458
- return reinterpret_cast<T*>(api_internal::GlobalizeReference(
459
- reinterpret_cast<internal::Isolate*>(isolate), p));
441
+ internal::Address* PersistentBase<T>::New(Isolate* isolate, T* that) {
442
+ if (internal::ValueHelper::IsEmpty(that)) return nullptr;
443
+ return api_internal::GlobalizeReference(
444
+ reinterpret_cast<internal::Isolate*>(isolate),
445
+ internal::ValueHelper::ValueAsAddress(that));
460
446
  }
461
447
 
462
448
  template <class T, class M>
@@ -465,8 +451,7 @@ void Persistent<T, M>::Copy(const Persistent<S, M2>& that) {
465
451
  static_assert(std::is_base_of<T, S>::value, "type check");
466
452
  this->Reset();
467
453
  if (that.IsEmpty()) return;
468
- internal::Address* p = reinterpret_cast<internal::Address*>(that.val_);
469
- this->val_ = reinterpret_cast<T*>(api_internal::CopyGlobalReference(p));
454
+ this->slot() = api_internal::CopyGlobalReference(that.slot());
470
455
  M::Copy(that, this);
471
456
  }
472
457
 
@@ -474,15 +459,14 @@ template <class T>
474
459
  bool PersistentBase<T>::IsWeak() const {
475
460
  using I = internal::Internals;
476
461
  if (this->IsEmpty()) return false;
477
- return I::GetNodeState(reinterpret_cast<internal::Address*>(this->val_)) ==
478
- I::kNodeStateIsWeakValue;
462
+ return I::GetNodeState(this->slot()) == I::kNodeStateIsWeakValue;
479
463
  }
480
464
 
481
465
  template <class T>
482
466
  void PersistentBase<T>::Reset() {
483
467
  if (this->IsEmpty()) return;
484
- api_internal::DisposeGlobal(reinterpret_cast<internal::Address*>(this->val_));
485
- val_ = nullptr;
468
+ api_internal::DisposeGlobal(this->slot());
469
+ this->Clear();
486
470
  }
487
471
 
488
472
  /**
@@ -495,7 +479,7 @@ void PersistentBase<T>::Reset(Isolate* isolate, const Local<S>& other) {
495
479
  static_assert(std::is_base_of<T, S>::value, "type check");
496
480
  Reset();
497
481
  if (other.IsEmpty()) return;
498
- this->val_ = New(isolate, internal::ValueHelper::ValueAsSlot(*other));
482
+ this->slot() = New(isolate, *other);
499
483
  }
500
484
 
501
485
  /**
@@ -509,7 +493,7 @@ void PersistentBase<T>::Reset(Isolate* isolate,
509
493
  static_assert(std::is_base_of<T, S>::value, "type check");
510
494
  Reset();
511
495
  if (other.IsEmpty()) return;
512
- this->val_ = New(isolate, other.val_);
496
+ this->slot() = New(isolate, other.template value<S>());
513
497
  }
514
498
 
515
499
  template <class T>
@@ -522,8 +506,8 @@ V8_INLINE void PersistentBase<T>::SetWeak(
522
506
  #pragma GCC diagnostic push
523
507
  #pragma GCC diagnostic ignored "-Wcast-function-type"
524
508
  #endif
525
- api_internal::MakeWeak(reinterpret_cast<internal::Address*>(this->val_),
526
- parameter, reinterpret_cast<Callback>(callback), type);
509
+ api_internal::MakeWeak(this->slot(), parameter,
510
+ reinterpret_cast<Callback>(callback), type);
527
511
  #if (__GNUC__ >= 8) && !defined(__clang__)
528
512
  #pragma GCC diagnostic pop
529
513
  #endif
@@ -531,28 +515,25 @@ V8_INLINE void PersistentBase<T>::SetWeak(
531
515
 
532
516
  template <class T>
533
517
  void PersistentBase<T>::SetWeak() {
534
- api_internal::MakeWeak(reinterpret_cast<internal::Address**>(&this->val_));
518
+ api_internal::MakeWeak(&this->slot());
535
519
  }
536
520
 
537
521
  template <class T>
538
522
  template <typename P>
539
523
  P* PersistentBase<T>::ClearWeak() {
540
- return reinterpret_cast<P*>(api_internal::ClearWeak(
541
- reinterpret_cast<internal::Address*>(this->val_)));
524
+ return reinterpret_cast<P*>(api_internal::ClearWeak(this->slot()));
542
525
  }
543
526
 
544
527
  template <class T>
545
528
  void PersistentBase<T>::AnnotateStrongRetainer(const char* label) {
546
- api_internal::AnnotateStrongRetainer(
547
- reinterpret_cast<internal::Address*>(this->val_), label);
529
+ api_internal::AnnotateStrongRetainer(this->slot(), label);
548
530
  }
549
531
 
550
532
  template <class T>
551
533
  void PersistentBase<T>::SetWrapperClassId(uint16_t class_id) {
552
534
  using I = internal::Internals;
553
535
  if (this->IsEmpty()) return;
554
- internal::Address* obj = reinterpret_cast<internal::Address*>(this->val_);
555
- uint8_t* addr = reinterpret_cast<uint8_t*>(obj) + I::kNodeClassIdOffset;
536
+ uint8_t* addr = reinterpret_cast<uint8_t*>(slot()) + I::kNodeClassIdOffset;
556
537
  *reinterpret_cast<uint16_t*>(addr) = class_id;
557
538
  }
558
539
 
@@ -560,18 +541,15 @@ template <class T>
560
541
  uint16_t PersistentBase<T>::WrapperClassId() const {
561
542
  using I = internal::Internals;
562
543
  if (this->IsEmpty()) return 0;
563
- internal::Address* obj = reinterpret_cast<internal::Address*>(this->val_);
564
- uint8_t* addr = reinterpret_cast<uint8_t*>(obj) + I::kNodeClassIdOffset;
544
+ uint8_t* addr = reinterpret_cast<uint8_t*>(slot()) + I::kNodeClassIdOffset;
565
545
  return *reinterpret_cast<uint16_t*>(addr);
566
546
  }
567
547
 
568
548
  template <class T>
569
- Global<T>::Global(Global&& other) : PersistentBase<T>(other.val_) {
570
- if (other.val_ != nullptr) {
571
- api_internal::MoveGlobalReference(
572
- reinterpret_cast<internal::Address**>(&other.val_),
573
- reinterpret_cast<internal::Address**>(&this->val_));
574
- other.val_ = nullptr;
549
+ Global<T>::Global(Global&& other) : PersistentBase<T>(other.slot()) {
550
+ if (!other.IsEmpty()) {
551
+ api_internal::MoveGlobalReference(&other.slot(), &this->slot());
552
+ other.Clear();
575
553
  }
576
554
  }
577
555
 
@@ -581,12 +559,10 @@ Global<T>& Global<T>::operator=(Global<S>&& rhs) {
581
559
  static_assert(std::is_base_of<T, S>::value, "type check");
582
560
  if (this != &rhs) {
583
561
  this->Reset();
584
- if (rhs.val_ != nullptr) {
585
- this->val_ = rhs.val_;
586
- api_internal::MoveGlobalReference(
587
- reinterpret_cast<internal::Address**>(&rhs.val_),
588
- reinterpret_cast<internal::Address**>(&this->val_));
589
- rhs.val_ = nullptr;
562
+ if (!rhs.IsEmpty()) {
563
+ this->slot() = rhs.slot();
564
+ api_internal::MoveGlobalReference(&rhs.slot(), &this->slot());
565
+ rhs.Clear();
590
566
  }
591
567
  }
592
568
  return *this;
@@ -13,6 +13,7 @@
13
13
  #include <memory>
14
14
  #include <string>
15
15
 
16
+ #include "v8-source-location.h" // NOLINT(build/include_directory)
16
17
  #include "v8config.h" // NOLINT(build/include_directory)
17
18
 
18
19
  namespace v8 {
@@ -39,6 +40,7 @@ enum class TaskPriority : uint8_t {
39
40
  * possible.
40
41
  */
41
42
  kUserBlocking,
43
+ kMaxPriority = kUserBlocking
42
44
  };
43
45
 
44
46
  /**
@@ -261,8 +263,12 @@ class JobTask {
261
263
  * Controls the maximum number of threads calling Run() concurrently, given
262
264
  * the number of threads currently assigned to this job and executing Run().
263
265
  * Run() is only invoked if the number of threads previously running Run() was
264
- * less than the value returned. Since GetMaxConcurrency() is a leaf function,
265
- * it must not call back any JobHandle methods.
266
+ * less than the value returned. In general, this should return the latest
267
+ * number of incomplete work items (smallest unit of work) left to process,
268
+ * including items that are currently in progress. |worker_count| is the
269
+ * number of threads currently assigned to this job which some callers may
270
+ * need to determine their return value. Since GetMaxConcurrency() is a leaf
271
+ * function, it must not call back any JobHandle methods.
266
272
  */
267
273
  virtual size_t GetMaxConcurrency(size_t worker_count) const = 0;
268
274
  };
@@ -566,6 +572,42 @@ class PageAllocator {
566
572
  virtual bool CanAllocateSharedPages() { return false; }
567
573
  };
568
574
 
575
+ /**
576
+ * An allocator that uses per-thread permissions to protect the memory.
577
+ *
578
+ * The implementation is platform/hardware specific, e.g. using pkeys on x64.
579
+ *
580
+ * INTERNAL ONLY: This interface has not been stabilised and may change
581
+ * without notice from one release to another without being deprecated first.
582
+ */
583
+ class ThreadIsolatedAllocator {
584
+ public:
585
+ virtual ~ThreadIsolatedAllocator() = default;
586
+
587
+ virtual void* Allocate(size_t size) = 0;
588
+
589
+ virtual void Free(void* object) = 0;
590
+
591
+ enum class Type {
592
+ kPkey,
593
+ };
594
+
595
+ virtual Type Type() const = 0;
596
+
597
+ /**
598
+ * Return the pkey used to implement the thread isolation if Type == kPkey.
599
+ */
600
+ virtual int Pkey() const { return -1; }
601
+
602
+ /**
603
+ * Per-thread permissions can be reset on signal handler entry. Even reading
604
+ * ThreadIsolated memory will segfault in that case.
605
+ * Call this function on signal handler entry to ensure that read permissions
606
+ * are restored.
607
+ */
608
+ static void SetDefaultPermissionsForSignalHandler();
609
+ };
610
+
569
611
  // Opaque type representing a handle to a shared memory region.
570
612
  using PlatformSharedMemoryHandle = intptr_t;
571
613
  static constexpr PlatformSharedMemoryHandle kInvalidSharedMemoryHandle = -1;
@@ -969,6 +1011,16 @@ class Platform {
969
1011
  */
970
1012
  virtual PageAllocator* GetPageAllocator() = 0;
971
1013
 
1014
+ /**
1015
+ * Allows the embedder to provide an allocator that uses per-thread memory
1016
+ * permissions to protect allocations.
1017
+ * Returning nullptr will cause V8 to disable protections that rely on this
1018
+ * feature.
1019
+ */
1020
+ virtual ThreadIsolatedAllocator* GetThreadIsolatedAllocator() {
1021
+ return nullptr;
1022
+ }
1023
+
972
1024
  /**
973
1025
  * Allows the embedder to specify a custom allocator used for zones.
974
1026
  */
@@ -1000,40 +1052,80 @@ class Platform {
1000
1052
  * Returns a TaskRunner which can be used to post a task on the foreground.
1001
1053
  * The TaskRunner's NonNestableTasksEnabled() must be true. This function
1002
1054
  * should only be called from a foreground thread.
1055
+ * TODO(chromium:1448758): Deprecate once |GetForegroundTaskRunner(Isolate*,
1056
+ * TaskPriority)| is ready.
1003
1057
  */
1004
1058
  virtual std::shared_ptr<v8::TaskRunner> GetForegroundTaskRunner(
1005
- Isolate* isolate) = 0;
1059
+ Isolate* isolate) {
1060
+ return GetForegroundTaskRunner(isolate, TaskPriority::kUserBlocking);
1061
+ }
1006
1062
 
1007
1063
  /**
1008
- * Schedules a task to be invoked on a worker thread.
1064
+ * Returns a TaskRunner with a specific |priority| which can be used to post a
1065
+ * task on the foreground thread. The TaskRunner's NonNestableTasksEnabled()
1066
+ * must be true. This function should only be called from a foreground thread.
1067
+ * TODO(chromium:1448758): Make pure virtual once embedders implement it.
1009
1068
  */
1010
- virtual void CallOnWorkerThread(std::unique_ptr<Task> task) = 0;
1069
+ virtual std::shared_ptr<v8::TaskRunner> GetForegroundTaskRunner(
1070
+ Isolate* isolate, TaskPriority priority) {
1071
+ return nullptr;
1072
+ }
1073
+
1074
+ /**
1075
+ * Schedules a task to be invoked on a worker thread.
1076
+ * Embedders should override PostTaskOnWorkerThreadImpl() instead of
1077
+ * CallOnWorkerThread().
1078
+ * TODO(chromium:1424158): Make non-virtual once embedders are migrated to
1079
+ * PostTaskOnWorkerThreadImpl().
1080
+ */
1081
+ virtual void CallOnWorkerThread(std::unique_ptr<Task> task) {
1082
+ PostTaskOnWorkerThreadImpl(TaskPriority::kUserVisible, std::move(task),
1083
+ SourceLocation::Current());
1084
+ }
1011
1085
 
1012
1086
  /**
1013
1087
  * Schedules a task that blocks the main thread to be invoked with
1014
1088
  * high-priority on a worker thread.
1089
+ * Embedders should override PostTaskOnWorkerThreadImpl() instead of
1090
+ * CallBlockingTaskOnWorkerThread().
1091
+ * TODO(chromium:1424158): Make non-virtual once embedders are migrated to
1092
+ * PostTaskOnWorkerThreadImpl().
1015
1093
  */
1016
1094
  virtual void CallBlockingTaskOnWorkerThread(std::unique_ptr<Task> task) {
1017
1095
  // Embedders may optionally override this to process these tasks in a high
1018
1096
  // priority pool.
1019
- CallOnWorkerThread(std::move(task));
1097
+ PostTaskOnWorkerThreadImpl(TaskPriority::kUserBlocking, std::move(task),
1098
+ SourceLocation::Current());
1020
1099
  }
1021
1100
 
1022
1101
  /**
1023
1102
  * Schedules a task to be invoked with low-priority on a worker thread.
1103
+ * Embedders should override PostTaskOnWorkerThreadImpl() instead of
1104
+ * CallLowPriorityTaskOnWorkerThread().
1105
+ * TODO(chromium:1424158): Make non-virtual once embedders are migrated to
1106
+ * PostTaskOnWorkerThreadImpl().
1024
1107
  */
1025
1108
  virtual void CallLowPriorityTaskOnWorkerThread(std::unique_ptr<Task> task) {
1026
1109
  // Embedders may optionally override this to process these tasks in a low
1027
1110
  // priority pool.
1028
- CallOnWorkerThread(std::move(task));
1111
+ PostTaskOnWorkerThreadImpl(TaskPriority::kBestEffort, std::move(task),
1112
+ SourceLocation::Current());
1029
1113
  }
1030
1114
 
1031
1115
  /**
1032
1116
  * Schedules a task to be invoked on a worker thread after |delay_in_seconds|
1033
1117
  * expires.
1118
+ * Embedders should override PostDelayedTaskOnWorkerThreadImpl() instead of
1119
+ * CallDelayedOnWorkerThread().
1120
+ * TODO(chromium:1424158): Make non-virtual once embedders are migrated to
1121
+ * PostDelayedTaskOnWorkerThreadImpl().
1034
1122
  */
1035
1123
  virtual void CallDelayedOnWorkerThread(std::unique_ptr<Task> task,
1036
- double delay_in_seconds) = 0;
1124
+ double delay_in_seconds) {
1125
+ PostDelayedTaskOnWorkerThreadImpl(TaskPriority::kUserVisible,
1126
+ std::move(task), delay_in_seconds,
1127
+ SourceLocation::Current());
1128
+ }
1037
1129
 
1038
1130
  /**
1039
1131
  * Returns true if idle tasks are enabled for the given |isolate|.
@@ -1083,6 +1175,9 @@ class Platform {
1083
1175
  * thread (A=>B/B=>A deadlock) and [2] JobTask::Run or
1084
1176
  * JobTask::GetMaxConcurrency may be invoked synchronously from JobHandle
1085
1177
  * (B=>JobHandle::foo=>B deadlock).
1178
+ * Embedders should override CreateJobImpl() instead of PostJob().
1179
+ * TODO(chromium:1424158): Make non-virtual once embedders are migrated to
1180
+ * CreateJobImpl().
1086
1181
  */
1087
1182
  virtual std::unique_ptr<JobHandle> PostJob(
1088
1183
  TaskPriority priority, std::unique_ptr<JobTask> job_task) {
@@ -1103,9 +1198,16 @@ class Platform {
1103
1198
  * return v8::platform::NewDefaultJobHandle(
1104
1199
  * this, priority, std::move(job_task), NumberOfWorkerThreads());
1105
1200
  * }
1201
+ *
1202
+ * Embedders should override CreateJobImpl() instead of CreateJob().
1203
+ * TODO(chromium:1424158): Make non-virtual once embedders are migrated to
1204
+ * CreateJobImpl().
1106
1205
  */
1107
1206
  virtual std::unique_ptr<JobHandle> CreateJob(
1108
- TaskPriority priority, std::unique_ptr<JobTask> job_task) = 0;
1207
+ TaskPriority priority, std::unique_ptr<JobTask> job_task) {
1208
+ return CreateJobImpl(priority, std::move(job_task),
1209
+ SourceLocation::Current());
1210
+ }
1109
1211
 
1110
1212
  /**
1111
1213
  * Instantiates a ScopedBlockingCall to annotate a scope that may/will block.
@@ -1183,6 +1285,35 @@ class Platform {
1183
1285
  * nothing special needed.
1184
1286
  */
1185
1287
  V8_EXPORT static double SystemClockTimeMillis();
1288
+
1289
+ /**
1290
+ * Creates and returns a JobHandle associated with a Job.
1291
+ * TODO(chromium:1424158): Make pure virtual once embedders implement it.
1292
+ */
1293
+ virtual std::unique_ptr<JobHandle> CreateJobImpl(
1294
+ TaskPriority priority, std::unique_ptr<JobTask> job_task,
1295
+ const SourceLocation& location) {
1296
+ return nullptr;
1297
+ }
1298
+
1299
+ /**
1300
+ * Schedules a task with |priority| to be invoked on a worker thread.
1301
+ * TODO(chromium:1424158): Make pure virtual once embedders implement it.
1302
+ */
1303
+ virtual void PostTaskOnWorkerThreadImpl(TaskPriority priority,
1304
+ std::unique_ptr<Task> task,
1305
+ const SourceLocation& location) {
1306
+ CallOnWorkerThread(std::move(task));
1307
+ }
1308
+
1309
+ /**
1310
+ * Schedules a task with |priority| to be invoked on a worker thread after
1311
+ * |delay_in_seconds| expires.
1312
+ * TODO(chromium:1424158): Make pure virtual once embedders implement it.
1313
+ */
1314
+ virtual void PostDelayedTaskOnWorkerThreadImpl(
1315
+ TaskPriority priority, std::unique_ptr<Task> task,
1316
+ double delay_in_seconds, const SourceLocation& location) {}
1186
1317
  };
1187
1318
 
1188
1319
  } // namespace v8
@@ -490,12 +490,6 @@ class V8_EXPORT String : public Name {
490
490
  */
491
491
  bool MakeExternal(ExternalOneByteStringResource* resource);
492
492
 
493
- /**
494
- * Returns true if this string can be made external.
495
- */
496
- V8_DEPRECATE_SOON("Use the version that takes an encoding as argument.")
497
- bool CanMakeExternal() const;
498
-
499
493
  /**
500
494
  * Returns true if this string can be made external, given the encoding for
501
495
  * the external string resource.
@@ -644,10 +638,20 @@ class V8_EXPORT Symbol : public Name {
644
638
  static void CheckCast(Data* that);
645
639
  };
646
640
 
641
+ /**
642
+ * A JavaScript numeric value (either Number or BigInt).
643
+ * https://tc39.es/ecma262/#sec-numeric-types
644
+ */
645
+ class V8_EXPORT Numeric : public Primitive {
646
+ private:
647
+ Numeric();
648
+ static void CheckCast(v8::Data* that);
649
+ };
650
+
647
651
  /**
648
652
  * A JavaScript number value (ECMA-262, 4.3.20)
649
653
  */
650
- class V8_EXPORT Number : public Primitive {
654
+ class V8_EXPORT Number : public Numeric {
651
655
  public:
652
656
  double Value() const;
653
657
  static Local<Number> New(Isolate* isolate, double value);
@@ -722,7 +726,7 @@ class V8_EXPORT Uint32 : public Integer {
722
726
  /**
723
727
  * A JavaScript BigInt value (https://tc39.github.io/proposal-bigint)
724
728
  */
725
- class V8_EXPORT BigInt : public Primitive {
729
+ class V8_EXPORT BigInt : public Numeric {
726
730
  public:
727
731
  static Local<BigInt> New(Isolate* isolate, int64_t value);
728
732
  static Local<BigInt> NewFromUnsigned(Isolate* isolate, uint64_t value);