v8 10.2.154 (node 18.16.0)
V8 is Google's open source JavaScript engine
Loading...
Searching...
No Matches
v8-traced-handle.h
Go to the documentation of this file.
1// Copyright 2021 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_TRACED_HANDLE_H_
6#define INCLUDE_V8_TRACED_HANDLE_H_
7
8#include <stddef.h>
9#include <stdint.h>
10#include <stdio.h>
11
12#include <atomic>
13#include <memory>
14#include <type_traits>
15#include <utility>
16
17#include "v8-internal.h" // NOLINT(build/include_directory)
18#include "v8-local-handle.h" // NOLINT(build/include_directory)
19#include "v8-weak-callback-info.h" // NOLINT(build/include_directory)
20#include "v8config.h" // NOLINT(build/include_directory)
21
22namespace v8 {
23
24class Value;
25
26namespace internal {
27
28class BasicTracedReferenceExtractor;
29
33};
34
36 internal::Isolate* isolate, internal::Address* handle,
43
44} // namespace internal
45
47 public:
52 bool IsEmpty() const { return val_ == nullptr; }
53
58 V8_INLINE void Reset();
59
64 if (IsEmpty()) return Local<Value>();
65 return Local<Value>::New(isolate, reinterpret_cast<Value*>(val_));
66 }
67
72 bool IsEmptyThreadSafe() const {
73 return this->GetSlotThreadSafe() == nullptr;
74 }
75
79 V8_INLINE void SetWrapperClassId(uint16_t class_id);
80
85 V8_INLINE uint16_t WrapperClassId() const;
86
87 protected:
91 void SetSlotThreadSafe(void* new_val) {
92 reinterpret_cast<std::atomic<void*>*>(&val_)->store(
93 new_val, std::memory_order_relaxed);
94 }
95
99 const void* GetSlotThreadSafe() const {
100 return reinterpret_cast<std::atomic<const void*> const*>(&val_)->load(
101 std::memory_order_relaxed);
102 }
103
104 V8_EXPORT void CheckValue() const;
105
106 // val_ points to a GlobalHandles node.
108
110 template <typename F>
111 friend class Local;
112 template <typename U>
113 friend bool operator==(const TracedReferenceBase&, const Local<U>&);
114 friend bool operator==(const TracedReferenceBase&,
115 const TracedReferenceBase&);
116};
117
132template <typename T>
134 public:
138 Local<T> Get(Isolate* isolate) const { return Local<T>::New(isolate, *this); }
139
140 template <class S>
142 return reinterpret_cast<BasicTracedReference<S>&>(
143 const_cast<BasicTracedReference<T>&>(*this));
144 }
145
146 T* operator->() const {
147#ifdef V8_ENABLE_CHECKS
148 CheckValue();
149#endif // V8_ENABLE_CHECKS
150 return reinterpret_cast<T*>(val_);
151 }
152 T* operator*() const {
153#ifdef V8_ENABLE_CHECKS
154 CheckValue();
155#endif // V8_ENABLE_CHECKS
156 return reinterpret_cast<T*>(val_);
157 }
158
159 private:
163 BasicTracedReference() = default;
164
165 V8_INLINE static internal::Address* New(
166 Isolate* isolate, T* that, void* slot,
168
169 friend class EmbedderHeapTracer;
170 template <typename F>
171 friend class Local;
172 friend class Object;
173 template <typename F>
174 friend class TracedReference;
175 template <typename F>
177 template <typename F>
178 friend class ReturnValue;
179};
180
192template <typename T>
194 public:
196
201
208 template <class S>
210 this->val_ = this->New(isolate, that.val_, &this->val_,
212 static_assert(std::is_base_of<T, S>::value, "type check");
213 }
214
220 // Forward to operator=.
221 *this = std::move(other);
222 }
223
228 template <typename S>
230 // Forward to operator=.
231 *this = std::move(other);
232 }
233
239 // Forward to operator=;
240 *this = other;
241 }
242
247 template <typename S>
249 // Forward to operator=;
250 *this = other;
251 }
252
257
261 template <class S>
263
268
272 template <class S>
274
279 template <class S>
280 V8_INLINE void Reset(Isolate* isolate, const Local<S>& other);
281
282 template <class S>
284 return reinterpret_cast<TracedReference<S>&>(
285 const_cast<TracedReference<T>&>(*this));
286 }
287};
288
289// --- Implementation ---
290template <class T>
291internal::Address* BasicTracedReference<T>::New(
292 Isolate* isolate, T* that, void* slot,
294 if (that == nullptr) return nullptr;
295 internal::Address* p = reinterpret_cast<internal::Address*>(that);
297 reinterpret_cast<internal::Isolate*>(isolate), p,
298 reinterpret_cast<internal::Address*>(slot), store_mode);
299}
300
302 if (IsEmpty()) return;
304 SetSlotThreadSafe(nullptr);
305}
306
308 const TracedReferenceBase& rhs) {
309 v8::internal::Address* a = reinterpret_cast<v8::internal::Address*>(lhs.val_);
310 v8::internal::Address* b = reinterpret_cast<v8::internal::Address*>(rhs.val_);
311 if (a == nullptr) return b == nullptr;
312 if (b == nullptr) return false;
313 return *a == *b;
314}
315
316template <typename U>
318 const v8::Local<U>& rhs) {
319 v8::internal::Address* a = reinterpret_cast<v8::internal::Address*>(lhs.val_);
320 v8::internal::Address* b = reinterpret_cast<v8::internal::Address*>(*rhs);
321 if (a == nullptr) return b == nullptr;
322 if (b == nullptr) return false;
323 return *a == *b;
324}
325
326template <typename U>
328 const TracedReferenceBase& rhs) {
329 return rhs == lhs;
330}
331
333 const TracedReferenceBase& rhs) {
334 return !(lhs == rhs);
335}
336
337template <typename U>
339 const v8::Local<U>& rhs) {
340 return !(lhs == rhs);
341}
342
343template <typename U>
345 const TracedReferenceBase& rhs) {
346 return !(rhs == lhs);
347}
348
349template <class T>
350template <class S>
351void TracedReference<T>::Reset(Isolate* isolate, const Local<S>& other) {
352 static_assert(std::is_base_of<T, S>::value, "type check");
353 this->Reset();
354 if (other.IsEmpty()) return;
355 this->SetSlotThreadSafe(
356 this->New(isolate, other.val_, &this->val_,
358}
359
360template <class T>
361template <class S>
363 TracedReference<S>&& rhs) noexcept {
364 static_assert(std::is_base_of<T, S>::value, "type check");
365 *this = std::move(rhs.template As<T>());
366 return *this;
367}
368
369template <class T>
370template <class S>
372 const TracedReference<S>& rhs) {
373 static_assert(std::is_base_of<T, S>::value, "type check");
374 *this = rhs.template As<T>();
375 return *this;
376}
377
378template <class T>
380 TracedReference&& rhs) noexcept {
381 if (this != &rhs) {
383 reinterpret_cast<internal::Address**>(&rhs.val_),
384 reinterpret_cast<internal::Address**>(&this->val_));
385 }
386 return *this;
387}
388
389template <class T>
391 if (this != &rhs) {
392 this->Reset();
393 if (rhs.val_ != nullptr) {
395 reinterpret_cast<const internal::Address* const*>(&rhs.val_),
396 reinterpret_cast<internal::Address**>(&this->val_));
397 }
398 }
399 return *this;
400}
401
403 using I = internal::Internals;
404 if (IsEmpty()) return;
405 internal::Address* obj = reinterpret_cast<internal::Address*>(val_);
406 uint8_t* addr = reinterpret_cast<uint8_t*>(obj) + I::kNodeClassIdOffset;
407 *reinterpret_cast<uint16_t*>(addr) = class_id;
408}
409
411 using I = internal::Internals;
412 if (IsEmpty()) return 0;
413 internal::Address* obj = reinterpret_cast<internal::Address*>(val_);
414 uint8_t* addr = reinterpret_cast<uint8_t*>(obj) + I::kNodeClassIdOffset;
415 return *reinterpret_cast<uint16_t*>(addr);
416}
417
418} // namespace v8
419
420#endif // INCLUDE_V8_TRACED_HANDLE_H_
V8_INLINE BasicTracedReference< S > & As() const
Local< T > Get(Isolate *isolate) const
V8_INLINE bool IsEmpty() const
static V8_INLINE Local< T > New(Isolate *isolate, Local< T > that)
V8_INLINE uint16_t WrapperClassId() const
V8_INLINE v8::Local< v8::Value > Get(v8::Isolate *isolate) const
const void * GetSlotThreadSafe() const
V8_EXPORT void CheckValue() const
friend class internal::BasicTracedReferenceExtractor
friend bool operator==(const TracedReferenceBase &, const Local< U > &)
internal::Address * val_
V8_INLINE void SetWrapperClassId(uint16_t class_id)
void SetSlotThreadSafe(void *new_val)
V8_INLINE void Reset(Isolate *isolate, const Local< S > &other)
V8_INLINE TracedReference(TracedReference &&other) noexcept
V8_INLINE TracedReference & operator=(TracedReference< S > &&rhs) noexcept
V8_INLINE TracedReference & operator=(const TracedReference< S > &rhs)
V8_INLINE TracedReference(const TracedReference &other)
V8_INLINE TracedReference< S > & As() const
TracedReference(Isolate *isolate, Local< S > that)
V8_INLINE TracedReference(TracedReference< S > &&other) noexcept
V8_INLINE TracedReference(const TracedReference< S > &other)
V8_INLINE TracedReference & operator=(TracedReference &&rhs) noexcept
V8_EXPORT void CopyTracedReference(const internal::Address *const *from, internal::Address **to)
uintptr_t Address
Definition v8-internal.h:29
V8_EXPORT void MoveTracedReference(internal::Address **from, internal::Address **to)
V8_EXPORT void DisposeTracedReference(internal::Address *global_handle)
V8_EXPORT internal::Address * GlobalizeTracedReference(internal::Isolate *isolate, internal::Address *handle, internal::Address *slot, GlobalHandleStoreMode store_mode)
V8_INLINE bool operator==(const TracedReferenceBase &lhs, const TracedReferenceBase &rhs)
V8_INLINE bool operator!=(const TracedReferenceBase &lhs, const TracedReferenceBase &rhs)
#define V8_EXPORT
Definition v8config.h:578
#define V8_INLINE
Definition v8config.h:425