libv8-node 18.13.0.1-x86_64-darwin → 20.2.0.0-x86_64-darwin

Sign up to get free protection for your applications and to get access to all the features.
Files changed (70) hide show
  1. checksums.yaml +4 -4
  2. data/lib/libv8/node/version.rb +3 -3
  3. data/vendor/v8/include/cppgc/common.h +0 -1
  4. data/vendor/v8/include/cppgc/cross-thread-persistent.h +11 -10
  5. data/vendor/v8/include/cppgc/heap-consistency.h +46 -3
  6. data/vendor/v8/include/cppgc/heap-handle.h +48 -0
  7. data/vendor/v8/include/cppgc/heap-statistics.h +2 -2
  8. data/vendor/v8/include/cppgc/heap.h +3 -7
  9. data/vendor/v8/include/cppgc/internal/api-constants.h +14 -1
  10. data/vendor/v8/include/cppgc/internal/base-page-handle.h +45 -0
  11. data/vendor/v8/include/cppgc/internal/caged-heap-local-data.h +40 -8
  12. data/vendor/v8/include/cppgc/internal/caged-heap.h +61 -0
  13. data/vendor/v8/include/cppgc/internal/gc-info.h +35 -34
  14. data/vendor/v8/include/cppgc/internal/member-storage.h +248 -0
  15. data/vendor/v8/include/cppgc/internal/name-trait.h +21 -6
  16. data/vendor/v8/include/cppgc/internal/persistent-node.h +11 -13
  17. data/vendor/v8/include/cppgc/internal/pointer-policies.h +65 -8
  18. data/vendor/v8/include/cppgc/internal/write-barrier.h +153 -101
  19. data/vendor/v8/include/cppgc/liveness-broker.h +8 -7
  20. data/vendor/v8/include/cppgc/macros.h +10 -1
  21. data/vendor/v8/include/cppgc/member.h +424 -111
  22. data/vendor/v8/include/cppgc/name-provider.h +4 -4
  23. data/vendor/v8/include/cppgc/persistent.h +27 -24
  24. data/vendor/v8/include/cppgc/platform.h +7 -5
  25. data/vendor/v8/include/cppgc/sentinel-pointer.h +1 -1
  26. data/vendor/v8/include/cppgc/trace-trait.h +4 -0
  27. data/vendor/v8/include/cppgc/type-traits.h +13 -3
  28. data/vendor/v8/include/cppgc/visitor.h +104 -57
  29. data/vendor/v8/include/libplatform/v8-tracing.h +2 -2
  30. data/vendor/v8/include/v8-array-buffer.h +59 -0
  31. data/vendor/v8/include/v8-callbacks.h +32 -5
  32. data/vendor/v8/include/v8-context.h +63 -11
  33. data/vendor/v8/include/v8-cppgc.h +22 -0
  34. data/vendor/v8/include/v8-data.h +1 -1
  35. data/vendor/v8/include/v8-date.h +5 -0
  36. data/vendor/v8/include/v8-embedder-heap.h +0 -164
  37. data/vendor/v8/include/v8-exception.h +1 -1
  38. data/vendor/v8/include/v8-fast-api-calls.h +49 -31
  39. data/vendor/v8/include/v8-function-callback.h +69 -42
  40. data/vendor/v8/include/v8-function.h +9 -0
  41. data/vendor/v8/include/v8-initialization.h +23 -49
  42. data/vendor/v8/include/v8-inspector.h +32 -11
  43. data/vendor/v8/include/v8-internal.h +480 -183
  44. data/vendor/v8/include/v8-isolate.h +52 -77
  45. data/vendor/v8/include/v8-local-handle.h +86 -53
  46. data/vendor/v8/include/v8-locker.h +0 -11
  47. data/vendor/v8/include/v8-maybe.h +24 -1
  48. data/vendor/v8/include/v8-message.h +2 -4
  49. data/vendor/v8/include/v8-metrics.h +48 -40
  50. data/vendor/v8/include/v8-microtask-queue.h +6 -1
  51. data/vendor/v8/include/v8-object.h +29 -18
  52. data/vendor/v8/include/v8-persistent-handle.h +25 -18
  53. data/vendor/v8/include/v8-platform.h +133 -35
  54. data/vendor/v8/include/v8-primitive.h +27 -20
  55. data/vendor/v8/include/v8-profiler.h +133 -53
  56. data/vendor/v8/include/v8-regexp.h +2 -1
  57. data/vendor/v8/include/v8-script.h +91 -7
  58. data/vendor/v8/include/v8-snapshot.h +4 -8
  59. data/vendor/v8/include/v8-template.h +16 -77
  60. data/vendor/v8/include/v8-traced-handle.h +22 -28
  61. data/vendor/v8/include/v8-unwinder-state.h +4 -4
  62. data/vendor/v8/include/v8-util.h +11 -7
  63. data/vendor/v8/include/v8-value-serializer.h +46 -23
  64. data/vendor/v8/include/v8-value.h +31 -4
  65. data/vendor/v8/include/v8-version.h +4 -4
  66. data/vendor/v8/include/v8-wasm.h +7 -63
  67. data/vendor/v8/include/v8-weak-callback-info.h +0 -7
  68. data/vendor/v8/include/v8config.h +353 -15
  69. data/vendor/v8/x86_64-darwin/libv8/obj/libv8_monolith.a +0 -0
  70. metadata +5 -1
@@ -70,7 +70,7 @@ class V8_EXPORT ScriptOrigin {
70
70
  bool resource_is_opaque = false, bool is_wasm = false,
71
71
  bool is_module = false,
72
72
  Local<Data> host_defined_options = Local<Data>())
73
- : isolate_(isolate),
73
+ : v8_isolate_(isolate),
74
74
  resource_name_(resource_name),
75
75
  resource_line_offset_(resource_line_offset),
76
76
  resource_column_offset_(resource_column_offset),
@@ -87,14 +87,12 @@ class V8_EXPORT ScriptOrigin {
87
87
  V8_INLINE int ColumnOffset() const;
88
88
  V8_INLINE int ScriptId() const;
89
89
  V8_INLINE Local<Value> SourceMapUrl() const;
90
- V8_DEPRECATE_SOON("Use GetHostDefinedOptions")
91
- Local<PrimitiveArray> HostDefinedOptions() const;
92
90
  V8_INLINE Local<Data> GetHostDefinedOptions() const;
93
91
  V8_INLINE ScriptOriginOptions Options() const { return options_; }
94
92
 
95
93
  private:
96
94
  void VerifyHostDefinedOptions() const;
97
- Isolate* isolate_;
95
+ Isolate* v8_isolate_;
98
96
  Local<Value> resource_name_;
99
97
  int resource_line_offset_;
100
98
  int resource_column_offset_;
@@ -12,6 +12,7 @@
12
12
 
13
13
  #include "v8-internal.h" // NOLINT(build/include_directory)
14
14
  #include "v8-local-handle.h" // NOLINT(build/include_directory)
15
+ #include "v8config.h" // NOLINT(build/include_directory)
15
16
 
16
17
  namespace v8 {
17
18
 
@@ -96,16 +97,42 @@ struct GarbageCollectionYoungCycle {
96
97
  };
97
98
 
98
99
  struct WasmModuleDecoded {
100
+ WasmModuleDecoded() = default;
101
+ WasmModuleDecoded(bool async, bool streamed, bool success,
102
+ size_t module_size_in_bytes, size_t function_count,
103
+ int64_t wall_clock_duration_in_us)
104
+ : async(async),
105
+ streamed(streamed),
106
+ success(success),
107
+ module_size_in_bytes(module_size_in_bytes),
108
+ function_count(function_count),
109
+ wall_clock_duration_in_us(wall_clock_duration_in_us) {}
110
+
99
111
  bool async = false;
100
112
  bool streamed = false;
101
113
  bool success = false;
102
114
  size_t module_size_in_bytes = 0;
103
115
  size_t function_count = 0;
104
116
  int64_t wall_clock_duration_in_us = -1;
105
- int64_t cpu_duration_in_us = -1;
106
117
  };
107
118
 
108
119
  struct WasmModuleCompiled {
120
+ WasmModuleCompiled() = default;
121
+
122
+ WasmModuleCompiled(bool async, bool streamed, bool cached, bool deserialized,
123
+ bool lazy, bool success, size_t code_size_in_bytes,
124
+ size_t liftoff_bailout_count,
125
+ int64_t wall_clock_duration_in_us)
126
+ : async(async),
127
+ streamed(streamed),
128
+ cached(cached),
129
+ deserialized(deserialized),
130
+ lazy(lazy),
131
+ success(success),
132
+ code_size_in_bytes(code_size_in_bytes),
133
+ liftoff_bailout_count(liftoff_bailout_count),
134
+ wall_clock_duration_in_us(wall_clock_duration_in_us) {}
135
+
109
136
  bool async = false;
110
137
  bool streamed = false;
111
138
  bool cached = false;
@@ -115,7 +142,6 @@ struct WasmModuleCompiled {
115
142
  size_t code_size_in_bytes = 0;
116
143
  size_t liftoff_bailout_count = 0;
117
144
  int64_t wall_clock_duration_in_us = -1;
118
- int64_t cpu_duration_in_us = -1;
119
145
  };
120
146
 
121
147
  struct WasmModuleInstantiated {
@@ -125,31 +151,10 @@ struct WasmModuleInstantiated {
125
151
  int64_t wall_clock_duration_in_us = -1;
126
152
  };
127
153
 
128
- struct WasmModuleTieredUp {
129
- bool lazy = false;
130
- size_t code_size_in_bytes = 0;
131
- int64_t wall_clock_duration_in_us = -1;
132
- int64_t cpu_duration_in_us = -1;
133
- };
134
-
135
154
  struct WasmModulesPerIsolate {
136
155
  size_t count = 0;
137
156
  };
138
157
 
139
- #define V8_MAIN_THREAD_METRICS_EVENTS(V) \
140
- V(GarbageCollectionFullCycle) \
141
- V(GarbageCollectionFullMainThreadIncrementalMark) \
142
- V(GarbageCollectionFullMainThreadBatchedIncrementalMark) \
143
- V(GarbageCollectionFullMainThreadIncrementalSweep) \
144
- V(GarbageCollectionFullMainThreadBatchedIncrementalSweep) \
145
- V(GarbageCollectionYoungCycle) \
146
- V(WasmModuleDecoded) \
147
- V(WasmModuleCompiled) \
148
- V(WasmModuleInstantiated) \
149
- V(WasmModuleTieredUp)
150
-
151
- #define V8_THREAD_SAFE_METRICS_EVENTS(V) V(WasmModulesPerIsolate)
152
-
153
158
  /**
154
159
  * This class serves as a base class for recording event-based metrics in V8.
155
160
  * There a two kinds of metrics, those which are expected to be thread-safe and
@@ -159,19 +164,6 @@ struct WasmModulesPerIsolate {
159
164
  * background thread, it will be delayed and executed by the foreground task
160
165
  * runner.
161
166
  *
162
- * The thread-safe events are listed in the V8_THREAD_SAFE_METRICS_EVENTS
163
- * macro above while the main thread event are listed in
164
- * V8_MAIN_THREAD_METRICS_EVENTS above. For the former, a virtual method
165
- * AddMainThreadEvent(const E& event, v8::Context::Token token) will be
166
- * generated and for the latter AddThreadSafeEvent(const E& event).
167
- *
168
- * Thread-safe events are not allowed to access the context and therefore do
169
- * not carry a context ID with them. These IDs can be generated using
170
- * Recorder::GetContextId() and the ID will be valid throughout the lifetime
171
- * of the isolate. It is not guaranteed that the ID will still resolve to
172
- * a valid context using Recorder::GetContext() at the time the metric is
173
- * recorded. In this case, an empty handle will be returned.
174
- *
175
167
  * The embedder is expected to call v8::Isolate::SetMetricsRecorder()
176
168
  * providing its implementation and have the virtual methods overwritten
177
169
  * for the events it cares about.
@@ -202,14 +194,30 @@ class V8_EXPORT Recorder {
202
194
 
203
195
  virtual ~Recorder() = default;
204
196
 
197
+ // Main thread events. Those are only triggered on the main thread, and hence
198
+ // can access the context.
205
199
  #define ADD_MAIN_THREAD_EVENT(E) \
206
- virtual void AddMainThreadEvent(const E& event, ContextId context_id) {}
207
- V8_MAIN_THREAD_METRICS_EVENTS(ADD_MAIN_THREAD_EVENT)
200
+ virtual void AddMainThreadEvent(const E&, ContextId) {}
201
+ ADD_MAIN_THREAD_EVENT(GarbageCollectionFullCycle)
202
+ ADD_MAIN_THREAD_EVENT(GarbageCollectionFullMainThreadIncrementalMark)
203
+ ADD_MAIN_THREAD_EVENT(GarbageCollectionFullMainThreadBatchedIncrementalMark)
204
+ ADD_MAIN_THREAD_EVENT(GarbageCollectionFullMainThreadIncrementalSweep)
205
+ ADD_MAIN_THREAD_EVENT(GarbageCollectionFullMainThreadBatchedIncrementalSweep)
206
+ ADD_MAIN_THREAD_EVENT(GarbageCollectionYoungCycle)
207
+ ADD_MAIN_THREAD_EVENT(WasmModuleDecoded)
208
+ ADD_MAIN_THREAD_EVENT(WasmModuleCompiled)
209
+ ADD_MAIN_THREAD_EVENT(WasmModuleInstantiated)
208
210
  #undef ADD_MAIN_THREAD_EVENT
209
211
 
212
+ // Thread-safe events are not allowed to access the context and therefore do
213
+ // not carry a context ID with them. These IDs can be generated using
214
+ // Recorder::GetContextId() and the ID will be valid throughout the lifetime
215
+ // of the isolate. It is not guaranteed that the ID will still resolve to
216
+ // a valid context using Recorder::GetContext() at the time the metric is
217
+ // recorded. In this case, an empty handle will be returned.
210
218
  #define ADD_THREAD_SAFE_EVENT(E) \
211
- virtual void AddThreadSafeEvent(const E& event) {}
212
- V8_THREAD_SAFE_METRICS_EVENTS(ADD_THREAD_SAFE_EVENT)
219
+ virtual void AddThreadSafeEvent(const E&) {}
220
+ ADD_THREAD_SAFE_EVENT(WasmModulesPerIsolate)
213
221
  #undef ADD_THREAD_SAFE_EVENT
214
222
 
215
223
  virtual void NotifyIsolateDisposal() {}
@@ -118,7 +118,12 @@ class V8_EXPORT V8_NODISCARD MicrotasksScope {
118
118
  public:
119
119
  enum Type { kRunMicrotasks, kDoNotRunMicrotasks };
120
120
 
121
+ V8_DEPRECATE_SOON(
122
+ "May be incorrect if context was created with non-default microtask "
123
+ "queue")
121
124
  MicrotasksScope(Isolate* isolate, Type type);
125
+
126
+ MicrotasksScope(Local<Context> context, Type type);
122
127
  MicrotasksScope(Isolate* isolate, MicrotaskQueue* microtask_queue, Type type);
123
128
  ~MicrotasksScope();
124
129
 
@@ -142,7 +147,7 @@ class V8_EXPORT V8_NODISCARD MicrotasksScope {
142
147
  MicrotasksScope& operator=(const MicrotasksScope&) = delete;
143
148
 
144
149
  private:
145
- internal::Isolate* const isolate_;
150
+ internal::Isolate* const i_isolate_;
146
151
  internal::MicrotaskQueue* const microtask_queue_;
147
152
  bool run_;
148
153
  };
@@ -594,8 +594,6 @@ class V8_EXPORT Object : public Value {
594
594
  /**
595
595
  * Returns the context in which the object was created.
596
596
  */
597
- V8_DEPRECATED("Use MaybeLocal<Context> GetCreationContext()")
598
- Local<Context> CreationContext();
599
597
  MaybeLocal<Context> GetCreationContext();
600
598
 
601
599
  /**
@@ -604,15 +602,24 @@ class V8_EXPORT Object : public Value {
604
602
  Local<Context> GetCreationContextChecked();
605
603
 
606
604
  /** Same as above, but works for Persistents */
607
- V8_DEPRECATED(
608
- "Use MaybeLocal<Context> GetCreationContext(const "
609
- "PersistentBase<Object>& object)")
610
- static Local<Context> CreationContext(const PersistentBase<Object>& object);
611
605
  V8_INLINE static MaybeLocal<Context> GetCreationContext(
612
606
  const PersistentBase<Object>& object) {
613
607
  return object.val_->GetCreationContext();
614
608
  }
615
609
 
610
+ /**
611
+ * Gets the context in which the object was created (see GetCreationContext())
612
+ * and if it's available reads respective embedder field value.
613
+ * If the context can't be obtained nullptr is returned.
614
+ * Basically it's a shortcut for
615
+ * obj->GetCreationContext().GetAlignedPointerFromEmbedderData(index)
616
+ * which doesn't create a handle for Context object on the way and doesn't
617
+ * try to expand the embedder data attached to the context.
618
+ * In case the Local<Context> is already available because of other reasons,
619
+ * it's fine to keep using Context::GetAlignedPointerFromEmbedderData().
620
+ */
621
+ void* GetAlignedPointerFromEmbedderDataInCreationContext(int index);
622
+
616
623
  /**
617
624
  * Checks whether a callback is set by the
618
625
  * ObjectTemplate::SetCallAsFunctionHandler method.
@@ -713,22 +720,27 @@ Local<Value> Object::GetInternalField(int index) {
713
720
  #ifndef V8_ENABLE_CHECKS
714
721
  using A = internal::Address;
715
722
  using I = internal::Internals;
716
- A obj = *reinterpret_cast<A*>(this);
723
+ A obj = internal::ValueHelper::ValueAsAddress(this);
717
724
  // Fast path: If the object is a plain JSObject, which is the common case, we
718
725
  // know where to find the internal fields and can return the value directly.
719
726
  int instance_type = I::GetInstanceType(obj);
720
- if (v8::internal::CanHaveInternalField(instance_type)) {
727
+ if (I::CanHaveInternalField(instance_type)) {
721
728
  int offset = I::kJSObjectHeaderSize + (I::kEmbedderDataSlotSize * index);
722
729
  A value = I::ReadRawField<A>(obj, offset);
723
730
  #ifdef V8_COMPRESS_POINTERS
724
731
  // We read the full pointer value and then decompress it in order to avoid
725
732
  // dealing with potential endiannes issues.
726
- value = I::DecompressTaggedAnyField(obj, static_cast<uint32_t>(value));
733
+ value = I::DecompressTaggedField(obj, static_cast<uint32_t>(value));
727
734
  #endif
735
+
736
+ #ifdef V8_ENABLE_CONSERVATIVE_STACK_SCANNING
737
+ return Local<Value>(reinterpret_cast<Value*>(value));
738
+ #else
728
739
  internal::Isolate* isolate =
729
740
  internal::IsolateFromNeverReadOnlySpaceObject(obj);
730
741
  A* result = HandleScope::CreateHandle(isolate, value);
731
742
  return Local<Value>(reinterpret_cast<Value*>(result));
743
+ #endif
732
744
  }
733
745
  #endif
734
746
  return SlowGetInternalField(index);
@@ -738,18 +750,17 @@ void* Object::GetAlignedPointerFromInternalField(int index) {
738
750
  #if !defined(V8_ENABLE_CHECKS)
739
751
  using A = internal::Address;
740
752
  using I = internal::Internals;
741
- A obj = *reinterpret_cast<A*>(this);
753
+ A obj = internal::ValueHelper::ValueAsAddress(this);
742
754
  // Fast path: If the object is a plain JSObject, which is the common case, we
743
755
  // know where to find the internal fields and can return the value directly.
744
756
  auto instance_type = I::GetInstanceType(obj);
745
- if (v8::internal::CanHaveInternalField(instance_type)) {
746
- int offset = I::kJSObjectHeaderSize + (I::kEmbedderDataSlotSize * index);
747
- #ifdef V8_SANDBOXED_EXTERNAL_POINTERS
748
- offset += I::kEmbedderDataSlotRawPayloadOffset;
749
- #endif
750
- internal::Isolate* isolate = I::GetIsolateForSandbox(obj);
751
- A value = I::ReadExternalPointerField(
752
- isolate, obj, offset, internal::kEmbedderDataSlotPayloadTag);
757
+ if (I::CanHaveInternalField(instance_type)) {
758
+ int offset = I::kJSObjectHeaderSize + (I::kEmbedderDataSlotSize * index) +
759
+ I::kEmbedderDataSlotExternalPointerOffset;
760
+ Isolate* isolate = I::GetIsolateForSandbox(obj);
761
+ A value =
762
+ I::ReadExternalPointerField<internal::kEmbedderDataSlotPayloadTag>(
763
+ isolate, obj, offset);
753
764
  return reinterpret_cast<void*>(value);
754
765
  }
755
766
  #endif
@@ -55,7 +55,7 @@ class Eternal {
55
55
  V8_INLINE Local<T> Get(Isolate* isolate) const {
56
56
  // The eternal handle will never go away, so as with the roots, we don't
57
57
  // even need to open a handle.
58
- return Local<T>(val_);
58
+ return Local<T>(internal::ValueHelper::SlotAsValue<T>(val_));
59
59
  }
60
60
 
61
61
  V8_INLINE bool IsEmpty() const { return val_ == nullptr; }
@@ -68,6 +68,10 @@ class Eternal {
68
68
  }
69
69
 
70
70
  private:
71
+ V8_INLINE internal::Address address() const {
72
+ return *reinterpret_cast<internal::Address*>(val_);
73
+ }
74
+
71
75
  T* val_;
72
76
  };
73
77
 
@@ -122,20 +126,12 @@ class PersistentBase {
122
126
 
123
127
  template <class S>
124
128
  V8_INLINE bool operator==(const PersistentBase<S>& that) const {
125
- internal::Address* a = reinterpret_cast<internal::Address*>(this->val_);
126
- internal::Address* b = reinterpret_cast<internal::Address*>(that.val_);
127
- if (a == nullptr) return b == nullptr;
128
- if (b == nullptr) return false;
129
- return *a == *b;
129
+ return internal::HandleHelper::EqualHandles(*this, that);
130
130
  }
131
131
 
132
132
  template <class S>
133
133
  V8_INLINE bool operator==(const Local<S>& that) const {
134
- internal::Address* a = reinterpret_cast<internal::Address*>(this->val_);
135
- internal::Address* b = reinterpret_cast<internal::Address*>(that.val_);
136
- if (a == nullptr) return b == nullptr;
137
- if (b == nullptr) return false;
138
- return *a == *b;
134
+ return internal::HandleHelper::EqualHandles(*this, that);
139
135
  }
140
136
 
141
137
  template <class S>
@@ -169,8 +165,6 @@ class PersistentBase {
169
165
  * Turns this handle into a weak phantom handle without finalization callback.
170
166
  * The handle will be reset automatically when the garbage collector detects
171
167
  * that the object is no longer reachable.
172
- * A related function Isolate::NumberOfPhantomHandleResetsSinceLastCall
173
- * returns how many phantom handles were reset by the garbage collector.
174
168
  */
175
169
  V8_INLINE void SetWeak();
176
170
 
@@ -223,8 +217,15 @@ class PersistentBase {
223
217
  template <class F1, class F2>
224
218
  friend class PersistentValueVector;
225
219
  friend class Object;
220
+ friend class internal::HandleHelper;
226
221
 
227
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
+ }
227
+
228
+ V8_INLINE static T* New(Isolate* isolate, Local<T> that);
228
229
  V8_INLINE static T* New(Isolate* isolate, T* that);
229
230
 
230
231
  T* val_;
@@ -284,11 +285,13 @@ class Persistent : public PersistentBase<T> {
284
285
  * When the Local is non-empty, a new storage cell is created
285
286
  * pointing to the same object, and no flags are set.
286
287
  */
288
+
287
289
  template <class S>
288
290
  V8_INLINE Persistent(Isolate* isolate, Local<S> that)
289
- : PersistentBase<T>(PersistentBase<T>::New(isolate, *that)) {
291
+ : PersistentBase<T>(PersistentBase<T>::New(isolate, that)) {
290
292
  static_assert(std::is_base_of<T, S>::value, "type check");
291
293
  }
294
+
292
295
  /**
293
296
  * Construct a Persistent from a Persistent.
294
297
  * When the Persistent is non-empty, a new storage cell is created
@@ -358,7 +361,6 @@ class Persistent : public PersistentBase<T> {
358
361
  friend class ReturnValue;
359
362
 
360
363
  explicit V8_INLINE Persistent(T* that) : PersistentBase<T>(that) {}
361
- V8_INLINE T* operator*() const { return this->val_; }
362
364
  template <class S, class M2>
363
365
  V8_INLINE void Copy(const Persistent<S, M2>& that);
364
366
  };
@@ -383,7 +385,7 @@ class Global : public PersistentBase<T> {
383
385
  */
384
386
  template <class S>
385
387
  V8_INLINE Global(Isolate* isolate, Local<S> that)
386
- : PersistentBase<T>(PersistentBase<T>::New(isolate, *that)) {
388
+ : PersistentBase<T>(PersistentBase<T>::New(isolate, that)) {
387
389
  static_assert(std::is_base_of<T, S>::value, "type check");
388
390
  }
389
391
 
@@ -427,7 +429,6 @@ class Global : public PersistentBase<T> {
427
429
  private:
428
430
  template <class F>
429
431
  friend class ReturnValue;
430
- V8_INLINE T* operator*() const { return this->val_; }
431
432
  };
432
433
 
433
434
  // UniquePersistent is an alias for Global for historical reason.
@@ -444,6 +445,12 @@ class V8_EXPORT PersistentHandleVisitor {
444
445
  uint16_t class_id) {}
445
446
  };
446
447
 
448
+ 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
+
447
454
  template <class T>
448
455
  T* PersistentBase<T>::New(Isolate* isolate, T* that) {
449
456
  if (that == nullptr) return nullptr;
@@ -488,7 +495,7 @@ void PersistentBase<T>::Reset(Isolate* isolate, const Local<S>& other) {
488
495
  static_assert(std::is_base_of<T, S>::value, "type check");
489
496
  Reset();
490
497
  if (other.IsEmpty()) return;
491
- this->val_ = New(isolate, other.val_);
498
+ this->val_ = New(isolate, internal::ValueHelper::ValueAsSlot(*other));
492
499
  }
493
500
 
494
501
  /**