Warning, file /include/node/v8-traced-handle.h was not indexed
or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001
0002
0003
0004
0005 #ifndef INCLUDE_V8_TRACED_HANDLE_H_
0006 #define INCLUDE_V8_TRACED_HANDLE_H_
0007
0008 #include <stddef.h>
0009 #include <stdint.h>
0010 #include <stdio.h>
0011
0012 #include <atomic>
0013 #include <memory>
0014 #include <type_traits>
0015 #include <utility>
0016
0017 #include "v8-internal.h" // NOLINT(build/include_directory)
0018 #include "v8-local-handle.h" // NOLINT(build/include_directory)
0019 #include "v8-weak-callback-info.h" // NOLINT(build/include_directory)
0020 #include "v8config.h" // NOLINT(build/include_directory)
0021
0022 namespace v8 {
0023
0024 class Value;
0025
0026 namespace internal {
0027
0028 class BasicTracedReferenceExtractor;
0029
0030 enum class TracedReferenceStoreMode {
0031 kInitializingStore,
0032 kAssigningStore,
0033 };
0034
0035 enum class TracedReferenceHandling {
0036 kDefault,
0037 kDroppable
0038 };
0039
0040 V8_EXPORT Address* GlobalizeTracedReference(
0041 Isolate* isolate, Address value, Address* slot,
0042 TracedReferenceStoreMode store_mode,
0043 TracedReferenceHandling reference_handling);
0044 V8_EXPORT void MoveTracedReference(Address** from, Address** to);
0045 V8_EXPORT void CopyTracedReference(const Address* const* from, Address** to);
0046 V8_EXPORT void DisposeTracedReference(Address* global_handle);
0047
0048 }
0049
0050
0051
0052
0053
0054 class TracedReferenceBase : public api_internal::IndirectHandleBase {
0055 public:
0056 static_assert(sizeof(std::atomic<internal::Address*>) ==
0057 sizeof(internal::Address*));
0058
0059
0060
0061
0062
0063 V8_INLINE void Reset();
0064
0065
0066
0067
0068 V8_INLINE Local<Data> Get(Isolate* isolate) const {
0069 if (IsEmpty()) return Local<Data>();
0070 return Local<Data>::New(isolate, this->value<Data>());
0071 }
0072
0073
0074
0075
0076
0077 bool IsEmptyThreadSafe() const { return GetSlotThreadSafe() == nullptr; }
0078
0079 protected:
0080 V8_INLINE TracedReferenceBase() = default;
0081
0082
0083
0084
0085 void SetSlotThreadSafe(internal::Address* new_val) {
0086 reinterpret_cast<std::atomic<internal::Address*>*>(&slot())->store(
0087 new_val, std::memory_order_relaxed);
0088 }
0089
0090
0091
0092
0093 const internal::Address* GetSlotThreadSafe() const {
0094 return reinterpret_cast<const std::atomic<internal::Address*>*>(&slot())
0095 ->load(std::memory_order_relaxed);
0096 }
0097
0098 V8_EXPORT void CheckValue() const;
0099
0100 friend class internal::BasicTracedReferenceExtractor;
0101 template <typename F>
0102 friend class Local;
0103 template <typename U>
0104 friend bool operator==(const TracedReferenceBase&, const Local<U>&);
0105 friend bool operator==(const TracedReferenceBase&,
0106 const TracedReferenceBase&);
0107 };
0108
0109
0110
0111
0112
0113
0114
0115
0116
0117
0118
0119
0120
0121
0122
0123 template <typename T>
0124 class BasicTracedReference : public TracedReferenceBase {
0125 public:
0126
0127
0128
0129 Local<T> Get(Isolate* isolate) const { return Local<T>::New(isolate, *this); }
0130
0131 template <class S>
0132 V8_INLINE BasicTracedReference<S>& As() const {
0133 return reinterpret_cast<BasicTracedReference<S>&>(
0134 const_cast<BasicTracedReference<T>&>(*this));
0135 }
0136
0137 private:
0138
0139
0140
0141 BasicTracedReference() = default;
0142
0143 V8_INLINE static internal::Address* NewFromNonEmptyValue(
0144 Isolate* isolate, T* that, internal::Address** slot,
0145 internal::TracedReferenceStoreMode store_mode,
0146 internal::TracedReferenceHandling reference_handling);
0147
0148 template <typename F>
0149 friend class Local;
0150 friend class Object;
0151 template <typename F>
0152 friend class TracedReference;
0153 template <typename F>
0154 friend class BasicTracedReference;
0155 template <typename F>
0156 friend class ReturnValue;
0157 };
0158
0159
0160
0161
0162
0163
0164 template <typename T>
0165 class TracedReference : public BasicTracedReference<T> {
0166 public:
0167 struct IsDroppable {};
0168
0169 using BasicTracedReference<T>::Reset;
0170
0171
0172
0173
0174 V8_INLINE TracedReference() = default;
0175
0176
0177
0178
0179
0180
0181
0182 template <class S>
0183 TracedReference(Isolate* isolate, Local<S> that) : BasicTracedReference<T>() {
0184 static_assert(std::is_base_of<T, S>::value, "type check");
0185 if (V8_UNLIKELY(that.IsEmpty())) {
0186 return;
0187 }
0188 this->slot() = this->NewFromNonEmptyValue(
0189 isolate, *that, &this->slot(),
0190 internal::TracedReferenceStoreMode::kInitializingStore,
0191 internal::TracedReferenceHandling::kDefault);
0192 }
0193
0194
0195
0196
0197
0198
0199
0200
0201
0202 template <class S>
0203 TracedReference(Isolate* isolate, Local<S> that, IsDroppable)
0204 : BasicTracedReference<T>() {
0205 static_assert(std::is_base_of<T, S>::value, "type check");
0206 if (V8_UNLIKELY(that.IsEmpty())) {
0207 return;
0208 }
0209 this->slot() = this->NewFromNonEmptyValue(
0210 isolate, *that, &this->slot(),
0211 internal::TracedReferenceStoreMode::kInitializingStore,
0212 internal::TracedReferenceHandling::kDroppable);
0213 }
0214
0215
0216
0217
0218
0219 V8_INLINE TracedReference(TracedReference&& other) noexcept {
0220
0221 *this = std::move(other);
0222 }
0223
0224
0225
0226
0227
0228 template <typename S>
0229 V8_INLINE TracedReference(TracedReference<S>&& other) noexcept {
0230
0231 *this = std::move(other);
0232 }
0233
0234
0235
0236
0237
0238 V8_INLINE TracedReference(const TracedReference& other) {
0239
0240 *this = other;
0241 }
0242
0243
0244
0245
0246
0247 template <typename S>
0248 V8_INLINE TracedReference(const TracedReference<S>& other) {
0249
0250 *this = other;
0251 }
0252
0253
0254
0255
0256 V8_INLINE TracedReference& operator=(TracedReference&& rhs) noexcept;
0257
0258
0259
0260
0261 template <class S>
0262 V8_INLINE TracedReference& operator=(TracedReference<S>&& rhs) noexcept;
0263
0264
0265
0266
0267 V8_INLINE TracedReference& operator=(const TracedReference& rhs);
0268
0269
0270
0271
0272 template <class S>
0273 V8_INLINE TracedReference& operator=(const TracedReference<S>& rhs);
0274
0275
0276
0277
0278
0279 template <class S>
0280 V8_INLINE void Reset(Isolate* isolate, const Local<S>& other);
0281
0282
0283
0284
0285
0286 template <class S>
0287 V8_INLINE void Reset(Isolate* isolate, const Local<S>& other, IsDroppable);
0288
0289 template <class S>
0290 V8_INLINE TracedReference<S>& As() const {
0291 return reinterpret_cast<TracedReference<S>&>(
0292 const_cast<TracedReference<T>&>(*this));
0293 }
0294 };
0295
0296
0297 template <class T>
0298 internal::Address* BasicTracedReference<T>::NewFromNonEmptyValue(
0299 Isolate* isolate, T* that, internal::Address** slot,
0300 internal::TracedReferenceStoreMode store_mode,
0301 internal::TracedReferenceHandling reference_handling) {
0302 return internal::GlobalizeTracedReference(
0303 reinterpret_cast<internal::Isolate*>(isolate),
0304 internal::ValueHelper::ValueAsAddress(that),
0305 reinterpret_cast<internal::Address*>(slot), store_mode,
0306 reference_handling);
0307 }
0308
0309 void TracedReferenceBase::Reset() {
0310 if (V8_UNLIKELY(IsEmpty())) {
0311 return;
0312 }
0313 internal::DisposeTracedReference(slot());
0314 SetSlotThreadSafe(nullptr);
0315 }
0316
0317 V8_INLINE bool operator==(const TracedReferenceBase& lhs,
0318 const TracedReferenceBase& rhs) {
0319 return internal::HandleHelper::EqualHandles(lhs, rhs);
0320 }
0321
0322 template <typename U>
0323 V8_INLINE bool operator==(const TracedReferenceBase& lhs,
0324 const v8::Local<U>& rhs) {
0325 return internal::HandleHelper::EqualHandles(lhs, rhs);
0326 }
0327
0328 template <typename U>
0329 V8_INLINE bool operator==(const v8::Local<U>& lhs,
0330 const TracedReferenceBase& rhs) {
0331 return rhs == lhs;
0332 }
0333
0334 V8_INLINE bool operator!=(const TracedReferenceBase& lhs,
0335 const TracedReferenceBase& rhs) {
0336 return !(lhs == rhs);
0337 }
0338
0339 template <typename U>
0340 V8_INLINE bool operator!=(const TracedReferenceBase& lhs,
0341 const v8::Local<U>& rhs) {
0342 return !(lhs == rhs);
0343 }
0344
0345 template <typename U>
0346 V8_INLINE bool operator!=(const v8::Local<U>& lhs,
0347 const TracedReferenceBase& rhs) {
0348 return !(rhs == lhs);
0349 }
0350
0351 template <class T>
0352 template <class S>
0353 void TracedReference<T>::Reset(Isolate* isolate, const Local<S>& other) {
0354 static_assert(std::is_base_of<T, S>::value, "type check");
0355 this->Reset();
0356 if (V8_UNLIKELY(other.IsEmpty())) {
0357 return;
0358 }
0359 this->SetSlotThreadSafe(this->NewFromNonEmptyValue(
0360 isolate, *other, &this->slot(),
0361 internal::TracedReferenceStoreMode::kAssigningStore,
0362 internal::TracedReferenceHandling::kDefault));
0363 }
0364
0365 template <class T>
0366 template <class S>
0367 void TracedReference<T>::Reset(Isolate* isolate, const Local<S>& other,
0368 IsDroppable) {
0369 static_assert(std::is_base_of<T, S>::value, "type check");
0370 this->Reset();
0371 if (V8_UNLIKELY(other.IsEmpty())) {
0372 return;
0373 }
0374 this->SetSlotThreadSafe(this->NewFromNonEmptyValue(
0375 isolate, *other, &this->slot(),
0376 internal::TracedReferenceStoreMode::kAssigningStore,
0377 internal::TracedReferenceHandling::kDroppable));
0378 }
0379
0380 template <class T>
0381 template <class S>
0382 TracedReference<T>& TracedReference<T>::operator=(
0383 TracedReference<S>&& rhs) noexcept {
0384 static_assert(std::is_base_of<T, S>::value, "type check");
0385 *this = std::move(rhs.template As<T>());
0386 return *this;
0387 }
0388
0389 template <class T>
0390 template <class S>
0391 TracedReference<T>& TracedReference<T>::operator=(
0392 const TracedReference<S>& rhs) {
0393 static_assert(std::is_base_of<T, S>::value, "type check");
0394 *this = rhs.template As<T>();
0395 return *this;
0396 }
0397
0398 template <class T>
0399 TracedReference<T>& TracedReference<T>::operator=(
0400 TracedReference&& rhs) noexcept {
0401 if (this != &rhs) {
0402 internal::MoveTracedReference(&rhs.slot(), &this->slot());
0403 }
0404 return *this;
0405 }
0406
0407 template <class T>
0408 TracedReference<T>& TracedReference<T>::operator=(const TracedReference& rhs) {
0409 if (this != &rhs) {
0410 this->Reset();
0411 if (!rhs.IsEmpty()) {
0412 internal::CopyTracedReference(&rhs.slot(), &this->slot());
0413 }
0414 }
0415 return *this;
0416 }
0417
0418 }
0419
0420 #endif