libv8-node 20.2.0.0-x86_64-linux → 21.7.2.0-x86_64-linux

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. data/lib/libv8/node/version.rb +3 -3
  3. data/vendor/v8/include/cppgc/internal/api-constants.h +23 -4
  4. data/vendor/v8/include/cppgc/internal/caged-heap-local-data.h +16 -6
  5. data/vendor/v8/include/cppgc/internal/caged-heap.h +12 -5
  6. data/vendor/v8/include/cppgc/internal/gc-info.h +82 -91
  7. data/vendor/v8/include/cppgc/internal/member-storage.h +16 -8
  8. data/vendor/v8/include/cppgc/member.h +25 -0
  9. data/vendor/v8/include/cppgc/persistent.h +4 -0
  10. data/vendor/v8/include/cppgc/platform.h +6 -1
  11. data/vendor/v8/include/cppgc/sentinel-pointer.h +7 -0
  12. data/vendor/v8/include/cppgc/source-location.h +2 -78
  13. data/vendor/v8/include/cppgc/trace-trait.h +8 -0
  14. data/vendor/v8/include/cppgc/visitor.h +82 -4
  15. data/vendor/v8/include/libplatform/libplatform.h +7 -1
  16. data/vendor/v8/include/v8-callbacks.h +52 -8
  17. data/vendor/v8/include/v8-context.h +10 -13
  18. data/vendor/v8/include/v8-cppgc.h +5 -0
  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 -52
  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 +26 -2
  33. data/vendor/v8/include/v8-script.h +30 -7
  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. data/vendor/v8/x86_64-linux/libv8/obj/libv8_monolith.a +0 -0
  45. 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);