You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
797 lines
28 KiB
797 lines
28 KiB
5 years ago
|
diff -up chromium-78.0.3904.70/v8/include/v8.h.implement-tracedreference chromium-78.0.3904.70/v8/include/v8.h
|
||
|
--- chromium-78.0.3904.70/v8/include/v8.h.implement-tracedreference 2019-10-24 08:58:26.185640117 -0400
|
||
|
+++ chromium-78.0.3904.70/v8/include/v8.h 2019-10-24 09:18:33.719546481 -0400
|
||
|
@@ -96,6 +96,10 @@ template <class T>
|
||
|
class Global;
|
||
|
template <class T>
|
||
|
class TracedGlobal;
|
||
|
+template <class T>
|
||
|
+class TracedReference;
|
||
|
+template <class T>
|
||
|
+class TracedReferenceBase;
|
||
|
template<class K, class V, class T> class PersistentValueMap;
|
||
|
template <class K, class V, class T>
|
||
|
class PersistentValueMapBase;
|
||
|
@@ -281,7 +285,8 @@ class Local {
|
||
|
V8_INLINE static Local<T> New(Isolate* isolate, Local<T> that);
|
||
|
V8_INLINE static Local<T> New(Isolate* isolate,
|
||
|
const PersistentBase<T>& that);
|
||
|
- V8_INLINE static Local<T> New(Isolate* isolate, const TracedGlobal<T>& that);
|
||
|
+ V8_INLINE static Local<T> New(Isolate* isolate,
|
||
|
+ const TracedReferenceBase<T>& that);
|
||
|
|
||
|
private:
|
||
|
friend class Utils;
|
||
|
@@ -311,7 +316,13 @@ class Local {
|
||
|
template <class F>
|
||
|
friend class ReturnValue;
|
||
|
template <class F>
|
||
|
+ friend class Traced;
|
||
|
+ template <class F>
|
||
|
friend class TracedGlobal;
|
||
|
+ template <class F>
|
||
|
+ friend class TracedReferenceBase;
|
||
|
+ template <class F>
|
||
|
+ friend class TracedReference;
|
||
|
|
||
|
explicit V8_INLINE Local(T* that) : val_(that) {}
|
||
|
V8_INLINE static Local<T> New(Isolate* isolate, T* that);
|
||
|
@@ -792,22 +803,10 @@ template <class T>
|
||
|
using UniquePersistent = Global<T>;
|
||
|
|
||
|
/**
|
||
|
- * Trait specifying behavior of |TracedGlobal<T>|.
|
||
|
+ * Deprecated. Use |TracedReference<T>| instead.
|
||
|
*/
|
||
|
template <typename T>
|
||
|
-struct TracedGlobalTrait {
|
||
|
- /**
|
||
|
- * Specifies whether |TracedGlobal<T>| should clear its handle on destruction.
|
||
|
- *
|
||
|
- * V8 will *not* clear the embedder-side memory of the handle. The embedder is
|
||
|
- * expected to report all |TracedGlobal<T>| handles through
|
||
|
- * |EmbedderHeapTracer| upon garabge collection.
|
||
|
- *
|
||
|
- * See |EmbedderHeapTracer::IsRootForNonTracingGC| for handling with
|
||
|
- * non-tracing GCs in V8.
|
||
|
- */
|
||
|
- static constexpr bool kRequiresExplicitDestruction = true;
|
||
|
-};
|
||
|
+struct TracedGlobalTrait {};
|
||
|
|
||
|
/**
|
||
|
* A traced handle with copy and move semantics. The handle is to be used
|
||
|
@@ -820,15 +819,131 @@ struct TracedGlobalTrait {
|
||
|
* |v8::EmbedderHeapTracer::IsRootForNonTracingGC()| whether the handle should
|
||
|
* be treated as root or not.
|
||
|
*
|
||
|
- * For destruction semantics see |TracedGlobalTrait<T>|.
|
||
|
+ * Note that the base class cannot be instantiated itself. Choose from
|
||
|
+ * - TracedGlobal
|
||
|
+ * - TracedReference
|
||
|
*/
|
||
|
template <typename T>
|
||
|
-class TracedGlobal {
|
||
|
+class TracedReferenceBase {
|
||
|
public:
|
||
|
/**
|
||
|
+ * Returns true if this TracedReferenceBase is empty, i.e., has not been
|
||
|
+ * assigned an object.
|
||
|
+ */
|
||
|
+ bool IsEmpty() const { return val_ == nullptr; }
|
||
|
+
|
||
|
+ /**
|
||
|
+ * If non-empty, destroy the underlying storage cell. |IsEmpty| will return
|
||
|
+ * true after this call.
|
||
|
+ */
|
||
|
+ V8_INLINE void Reset();
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Construct a Local<T> from this handle.
|
||
|
+ */
|
||
|
+ Local<T> Get(Isolate* isolate) const { return Local<T>::New(isolate, *this); }
|
||
|
+
|
||
|
+ template <class S>
|
||
|
+ V8_INLINE bool operator==(const TracedReferenceBase<S>& that) const {
|
||
|
+ internal::Address* a = reinterpret_cast<internal::Address*>(val_);
|
||
|
+ internal::Address* b = reinterpret_cast<internal::Address*>(that.val_);
|
||
|
+ if (a == nullptr) return b == nullptr;
|
||
|
+ if (b == nullptr) return false;
|
||
|
+ return *a == *b;
|
||
|
+ }
|
||
|
+
|
||
|
+ template <class S>
|
||
|
+ V8_INLINE bool operator==(const Local<S>& that) const {
|
||
|
+ internal::Address* a = reinterpret_cast<internal::Address*>(val_);
|
||
|
+ internal::Address* b = reinterpret_cast<internal::Address*>(that.val_);
|
||
|
+ if (a == nullptr) return b == nullptr;
|
||
|
+ if (b == nullptr) return false;
|
||
|
+ return *a == *b;
|
||
|
+ }
|
||
|
+
|
||
|
+ template <class S>
|
||
|
+ V8_INLINE bool operator!=(const TracedReferenceBase<S>& that) const {
|
||
|
+ return !operator==(that);
|
||
|
+ }
|
||
|
+
|
||
|
+ template <class S>
|
||
|
+ V8_INLINE bool operator!=(const Local<S>& that) const {
|
||
|
+ return !operator==(that);
|
||
|
+ }
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Assigns a wrapper class ID to the handle.
|
||
|
+ */
|
||
|
+ V8_INLINE void SetWrapperClassId(uint16_t class_id);
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Returns the class ID previously assigned to this handle or 0 if no class ID
|
||
|
+ * was previously assigned.
|
||
|
+ */
|
||
|
+ V8_INLINE uint16_t WrapperClassId() const;
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Adds a finalization callback to the handle. The type of this callback is
|
||
|
+ * similar to WeakCallbackType::kInternalFields, i.e., it will pass the
|
||
|
+ * parameter and the first two internal fields of the object.
|
||
|
+ *
|
||
|
+ * The callback is then supposed to reset the handle in the callback. No
|
||
|
+ * further V8 API may be called in this callback. In case additional work
|
||
|
+ * involving V8 needs to be done, a second callback can be scheduled using
|
||
|
+ * WeakCallbackInfo<void>::SetSecondPassCallback.
|
||
|
+ */
|
||
|
+ V8_INLINE void SetFinalizationCallback(
|
||
|
+ void* parameter, WeakCallbackInfo<void>::Callback callback);
|
||
|
+
|
||
|
+ template <class S>
|
||
|
+ V8_INLINE TracedReferenceBase<S>& As() const {
|
||
|
+ return reinterpret_cast<TracedReferenceBase<S>&>(
|
||
|
+ const_cast<TracedReferenceBase<T>&>(*this));
|
||
|
+ }
|
||
|
+
|
||
|
+ private:
|
||
|
+ enum DestructionMode { kWithDestructor, kWithoutDestructor };
|
||
|
+
|
||
|
+ /**
|
||
|
+ * An empty TracedReferenceBase without storage cell.
|
||
|
+ */
|
||
|
+ TracedReferenceBase() = default;
|
||
|
+
|
||
|
+ V8_INLINE static T* New(Isolate* isolate, T* that, void* slot,
|
||
|
+ DestructionMode destruction_mode);
|
||
|
+
|
||
|
+ T* val_ = nullptr;
|
||
|
+
|
||
|
+ friend class EmbedderHeapTracer;
|
||
|
+ template <typename F>
|
||
|
+ friend class Local;
|
||
|
+ friend class Object;
|
||
|
+ template <typename F>
|
||
|
+ friend class TracedGlobal;
|
||
|
+ template <typename F>
|
||
|
+ friend class TracedReference;
|
||
|
+ template <typename F>
|
||
|
+ friend class ReturnValue;
|
||
|
+};
|
||
|
+
|
||
|
+/**
|
||
|
+ * A traced handle with destructor that clears the handle. For more details see
|
||
|
+ * TracedReferenceBase.
|
||
|
+ */
|
||
|
+template <typename T>
|
||
|
+class TracedGlobal : public TracedReferenceBase<T> {
|
||
|
+ public:
|
||
|
+ using TracedReferenceBase<T>::Reset;
|
||
|
+
|
||
|
+ /**
|
||
|
+ * Destructor resetting the handle.
|
||
|
+ */
|
||
|
+ ~TracedGlobal() { this->Reset(); }
|
||
|
+
|
||
|
+ /**
|
||
|
* An empty TracedGlobal without storage cell.
|
||
|
*/
|
||
|
- TracedGlobal() = default;
|
||
|
+ TracedGlobal() : TracedReferenceBase<T>() {}
|
||
|
|
||
|
/**
|
||
|
* Construct a TracedGlobal from a Local.
|
||
|
@@ -837,8 +952,9 @@ class TracedGlobal {
|
||
|
* pointing to the same object.
|
||
|
*/
|
||
|
template <class S>
|
||
|
- TracedGlobal(Isolate* isolate, Local<S> that)
|
||
|
- : val_(New(isolate, *that, &val_)) {
|
||
|
+ TracedGlobal(Isolate* isolate, Local<S> that) : TracedReferenceBase<T>() {
|
||
|
+ this->val_ = this->New(isolate, that.val_, &this->val_,
|
||
|
+ TracedReferenceBase<T>::kWithDestructor);
|
||
|
TYPE_CHECK(T, S);
|
||
|
}
|
||
|
|
||
|
@@ -905,121 +1021,126 @@ class TracedGlobal {
|
||
|
V8_INLINE TracedGlobal& operator=(const TracedGlobal<S>& rhs);
|
||
|
|
||
|
/**
|
||
|
- * Returns true if this TracedGlobal is empty, i.e., has not been assigned an
|
||
|
- * object.
|
||
|
- */
|
||
|
- bool IsEmpty() const { return val_ == nullptr; }
|
||
|
-
|
||
|
- /**
|
||
|
- * If non-empty, destroy the underlying storage cell. |IsEmpty| will return
|
||
|
- * true after this call.
|
||
|
- */
|
||
|
- V8_INLINE void Reset();
|
||
|
-
|
||
|
- /**
|
||
|
* If non-empty, destroy the underlying storage cell and create a new one with
|
||
|
* the contents of other if other is non empty
|
||
|
*/
|
||
|
template <class S>
|
||
|
V8_INLINE void Reset(Isolate* isolate, const Local<S>& other);
|
||
|
|
||
|
- /**
|
||
|
- * Construct a Local<T> from this handle.
|
||
|
- */
|
||
|
- Local<T> Get(Isolate* isolate) const { return Local<T>::New(isolate, *this); }
|
||
|
-
|
||
|
template <class S>
|
||
|
V8_INLINE TracedGlobal<S>& As() const {
|
||
|
return reinterpret_cast<TracedGlobal<S>&>(
|
||
|
const_cast<TracedGlobal<T>&>(*this));
|
||
|
}
|
||
|
+};
|
||
|
|
||
|
- template <class S>
|
||
|
- V8_INLINE bool operator==(const TracedGlobal<S>& that) const {
|
||
|
- internal::Address* a = reinterpret_cast<internal::Address*>(**this);
|
||
|
- internal::Address* b = reinterpret_cast<internal::Address*>(*that);
|
||
|
- if (a == nullptr) return b == nullptr;
|
||
|
- if (b == nullptr) return false;
|
||
|
- return *a == *b;
|
||
|
- }
|
||
|
+/**
|
||
|
+ * A traced handle without destructor that clears the handle. The embedder needs
|
||
|
+ * to ensure that the handle is not accessed once the V8 object has been
|
||
|
+ * reclaimed. This can happen when the handle is not passed through the
|
||
|
+ * EmbedderHeapTracer. For more details see TracedReferenceBase.
|
||
|
+ */
|
||
|
+template <typename T>
|
||
|
+class TracedReference : public TracedReferenceBase<T> {
|
||
|
+ public:
|
||
|
+ using TracedReferenceBase<T>::Reset;
|
||
|
+
|
||
|
+ /**
|
||
|
+ * An empty TracedReference without storage cell.
|
||
|
+ */
|
||
|
+ TracedReference() : TracedReferenceBase<T>() {}
|
||
|
|
||
|
+ /**
|
||
|
+ * Construct a TracedReference from a Local.
|
||
|
+ *
|
||
|
+ * When the Local is non-empty, a new storage cell is created
|
||
|
+ * pointing to the same object.
|
||
|
+ */
|
||
|
template <class S>
|
||
|
- V8_INLINE bool operator==(const Local<S>& that) const {
|
||
|
- internal::Address* a = reinterpret_cast<internal::Address*>(**this);
|
||
|
- internal::Address* b = reinterpret_cast<internal::Address*>(*that);
|
||
|
- if (a == nullptr) return b == nullptr;
|
||
|
- if (b == nullptr) return false;
|
||
|
- return *a == *b;
|
||
|
+ TracedReference(Isolate* isolate, Local<S> that) : TracedReferenceBase<T>() {
|
||
|
+ this->val_ = this->New(isolate, that.val_, &this->val_,
|
||
|
+ TracedReferenceBase<T>::kWithoutDestructor);
|
||
|
+ TYPE_CHECK(T, S);
|
||
|
}
|
||
|
|
||
|
- template <class S>
|
||
|
- V8_INLINE bool operator!=(const TracedGlobal<S>& that) const {
|
||
|
- return !operator==(that);
|
||
|
+ /**
|
||
|
+ * Move constructor initializing TracedReference from an
|
||
|
+ * existing one.
|
||
|
+ */
|
||
|
+ V8_INLINE TracedReference(TracedReference&& other) {
|
||
|
+ // Forward to operator=.
|
||
|
+ *this = std::move(other);
|
||
|
}
|
||
|
|
||
|
- template <class S>
|
||
|
- V8_INLINE bool operator!=(const Local<S>& that) const {
|
||
|
- return !operator==(that);
|
||
|
+ /**
|
||
|
+ * Move constructor initializing TracedReference from an
|
||
|
+ * existing one.
|
||
|
+ */
|
||
|
+ template <typename S>
|
||
|
+ V8_INLINE TracedReference(TracedReference<S>&& other) {
|
||
|
+ // Forward to operator=.
|
||
|
+ *this = std::move(other);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
- * Assigns a wrapper class ID to the handle.
|
||
|
+ * Copy constructor initializing TracedReference from an
|
||
|
+ * existing one.
|
||
|
*/
|
||
|
- V8_INLINE void SetWrapperClassId(uint16_t class_id);
|
||
|
+ V8_INLINE TracedReference(const TracedReference& other) {
|
||
|
+ // Forward to operator=;
|
||
|
+ *this = other;
|
||
|
+ }
|
||
|
|
||
|
/**
|
||
|
- * Returns the class ID previously assigned to this handle or 0 if no class ID
|
||
|
- * was previously assigned.
|
||
|
+ * Copy constructor initializing TracedReference from an
|
||
|
+ * existing one.
|
||
|
*/
|
||
|
- V8_INLINE uint16_t WrapperClassId() const;
|
||
|
+ template <typename S>
|
||
|
+ V8_INLINE TracedReference(const TracedReference<S>& other) {
|
||
|
+ // Forward to operator=;
|
||
|
+ *this = other;
|
||
|
+ }
|
||
|
|
||
|
/**
|
||
|
- * Adds a finalization callback to the handle. The type of this callback is
|
||
|
- * similar to WeakCallbackType::kInternalFields, i.e., it will pass the
|
||
|
- * parameter and the first two internal fields of the object.
|
||
|
- *
|
||
|
- * The callback is then supposed to reset the handle in the callback. No
|
||
|
- * further V8 API may be called in this callback. In case additional work
|
||
|
- * involving V8 needs to be done, a second callback can be scheduled using
|
||
|
- * WeakCallbackInfo<void>::SetSecondPassCallback.
|
||
|
+ * Move assignment operator initializing TracedGlobal from an existing one.
|
||
|
*/
|
||
|
- V8_INLINE void SetFinalizationCallback(
|
||
|
- void* parameter, WeakCallbackInfo<void>::Callback callback);
|
||
|
+ V8_INLINE TracedReference& operator=(TracedReference&& rhs);
|
||
|
|
||
|
- private:
|
||
|
- // Wrapping type used when clearing on destruction is required.
|
||
|
- struct WrappedForDestruction {
|
||
|
- T* value;
|
||
|
-
|
||
|
- explicit WrappedForDestruction(T* val) : value(val) {}
|
||
|
- ~WrappedForDestruction();
|
||
|
- operator T*() const { return value; }
|
||
|
- T* operator*() const { return value; }
|
||
|
- T* operator->() const { return value; }
|
||
|
- WrappedForDestruction& operator=(const WrappedForDestruction& other) {
|
||
|
- value = other.value;
|
||
|
- return *this;
|
||
|
- }
|
||
|
- WrappedForDestruction& operator=(T* val) {
|
||
|
- value = val;
|
||
|
- return *this;
|
||
|
- }
|
||
|
- };
|
||
|
+ /**
|
||
|
+ * Move assignment operator initializing TracedGlobal from an existing one.
|
||
|
+ */
|
||
|
+ template <class S>
|
||
|
+ V8_INLINE TracedReference& operator=(TracedReference<S>&& rhs);
|
||
|
|
||
|
- V8_INLINE static T* New(Isolate* isolate, T* that, void* slot);
|
||
|
+ /**
|
||
|
+ * Copy assignment operator initializing TracedGlobal from an existing one.
|
||
|
+ *
|
||
|
+ * Note: Prohibited when |other| has a finalization callback set through
|
||
|
+ * |SetFinalizationCallback|.
|
||
|
+ */
|
||
|
+ V8_INLINE TracedReference& operator=(const TracedReference& rhs);
|
||
|
|
||
|
- T* operator*() const { return this->val_; }
|
||
|
+ /**
|
||
|
+ * Copy assignment operator initializing TracedGlobal from an existing one.
|
||
|
+ *
|
||
|
+ * Note: Prohibited when |other| has a finalization callback set through
|
||
|
+ * |SetFinalizationCallback|.
|
||
|
+ */
|
||
|
+ template <class S>
|
||
|
+ V8_INLINE TracedReference& operator=(const TracedReference<S>& rhs);
|
||
|
|
||
|
- typename std::conditional<
|
||
|
- TracedGlobalTrait<TracedGlobal<T>>::kRequiresExplicitDestruction,
|
||
|
- WrappedForDestruction, T*>::type val_{nullptr};
|
||
|
+ /**
|
||
|
+ * If non-empty, destroy the underlying storage cell and create a new one with
|
||
|
+ * the contents of other if other is non empty
|
||
|
+ */
|
||
|
+ template <class S>
|
||
|
+ V8_INLINE void Reset(Isolate* isolate, const Local<S>& other);
|
||
|
|
||
|
- friend class EmbedderHeapTracer;
|
||
|
- template <typename F>
|
||
|
- friend class Local;
|
||
|
- friend class Object;
|
||
|
- template <typename F>
|
||
|
- friend class ReturnValue;
|
||
|
+ template <class S>
|
||
|
+ V8_INLINE TracedReference<S>& As() const {
|
||
|
+ return reinterpret_cast<TracedReference<S>&>(
|
||
|
+ const_cast<TracedReference<T>&>(*this));
|
||
|
+ }
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
@@ -3640,8 +3761,9 @@ class V8_EXPORT Object : public Value {
|
||
|
return object.val_->InternalFieldCount();
|
||
|
}
|
||
|
|
||
|
- /** Same as above, but works for TracedGlobal. */
|
||
|
- V8_INLINE static int InternalFieldCount(const TracedGlobal<Object>& object) {
|
||
|
+ /** Same as above, but works for TracedReferenceBase. */
|
||
|
+ V8_INLINE static int InternalFieldCount(
|
||
|
+ const TracedReferenceBase<Object>& object) {
|
||
|
return object.val_->InternalFieldCount();
|
||
|
}
|
||
|
|
||
|
@@ -3666,7 +3788,7 @@ class V8_EXPORT Object : public Value {
|
||
|
|
||
|
/** Same as above, but works for TracedGlobal. */
|
||
|
V8_INLINE static void* GetAlignedPointerFromInternalField(
|
||
|
- const TracedGlobal<Object>& object, int index) {
|
||
|
+ const TracedReferenceBase<Object>& object, int index) {
|
||
|
return object.val_->GetAlignedPointerFromInternalField(index);
|
||
|
}
|
||
|
|
||
|
@@ -3956,7 +4078,7 @@ class ReturnValue {
|
||
|
template <typename S>
|
||
|
V8_INLINE void Set(const Global<S>& handle);
|
||
|
template <typename S>
|
||
|
- V8_INLINE void Set(const TracedGlobal<S>& handle);
|
||
|
+ V8_INLINE void Set(const TracedReferenceBase<S>& handle);
|
||
|
template <typename S>
|
||
|
V8_INLINE void Set(const Local<S> handle);
|
||
|
// Fast primitive setters
|
||
|
@@ -7376,7 +7498,8 @@ class V8_EXPORT EmbedderHeapTracer {
|
||
|
class V8_EXPORT TracedGlobalHandleVisitor {
|
||
|
public:
|
||
|
virtual ~TracedGlobalHandleVisitor() = default;
|
||
|
- virtual void VisitTracedGlobalHandle(const TracedGlobal<Value>& value) = 0;
|
||
|
+ virtual void VisitTracedGlobalHandle(const TracedGlobal<Value>& handle) {}
|
||
|
+ virtual void VisitTracedReference(const TracedReference<Value>& handle) {}
|
||
|
};
|
||
|
|
||
|
/**
|
||
|
@@ -7414,7 +7537,7 @@ class V8_EXPORT EmbedderHeapTracer {
|
||
|
virtual void RegisterV8References(
|
||
|
const std::vector<std::pair<void*, void*> >& embedder_fields) = 0;
|
||
|
|
||
|
- void RegisterEmbedderReference(const TracedGlobal<v8::Value>& ref);
|
||
|
+ void RegisterEmbedderReference(const TracedReferenceBase<v8::Value>& ref);
|
||
|
|
||
|
/**
|
||
|
* Called at the beginning of a GC cycle.
|
||
|
@@ -7475,32 +7598,35 @@ class V8_EXPORT EmbedderHeapTracer {
|
||
|
*
|
||
|
* If this returns false, then V8 may decide that the object referred to by
|
||
|
* such a handle is reclaimed. In that case:
|
||
|
- * - No action is required if handles are used with destructors.
|
||
|
- * - When run without destructors (by specializing
|
||
|
- * |TracedGlobalTrait::kRequiresExplicitDestruction|) V8 calls
|
||
|
- * |ResetHandleInNonTracingGC|.
|
||
|
- *
|
||
|
- * Note that the |handle| is different from the |TracedGlobal<T>| handle that
|
||
|
- * the embedder holds for retaining the object. The embedder may use
|
||
|
- * |TracedGlobal<T>::WrapperClassId()| to distinguish cases where it wants
|
||
|
- * handles to be treated as roots from not being treated as roots.
|
||
|
+ * - No action is required if handles are used with destructors, i.e., by just
|
||
|
+ * using |TracedGlobal|.
|
||
|
+ * - When run without destructors, i.e., by using
|
||
|
+ * |TracedReference|, V8 calls |ResetHandleInNonTracingGC|.
|
||
|
+ *
|
||
|
+ * Note that the |handle| is different from the handle that the embedder holds
|
||
|
+ * for retaining the object. The embedder may use |WrapperClassId()| to
|
||
|
+ * distinguish cases where it wants handles to be treated as roots from not
|
||
|
+ * being treated as roots.
|
||
|
*/
|
||
|
virtual bool IsRootForNonTracingGC(
|
||
|
- const v8::TracedGlobal<v8::Value>& handle) {
|
||
|
- return true;
|
||
|
- }
|
||
|
+ const v8::TracedReference<v8::Value>& handle);
|
||
|
+ virtual bool IsRootForNonTracingGC(const v8::TracedGlobal<v8::Value>& handle);
|
||
|
|
||
|
/**
|
||
|
* Used in combination with |IsRootForNonTracingGC|. Called by V8 when an
|
||
|
* object that is backed by a handle is reclaimed by a non-tracing garbage
|
||
|
* collection. It is up to the embedder to reset the original handle.
|
||
|
*
|
||
|
- * Note that the |handle| is different from the |TracedGlobal<T>| handle that
|
||
|
- * the embedder holds for retaining the object. It is up to the embedder to
|
||
|
- * find the orignal |TracedGlobal<T>| handle via the object or class id.
|
||
|
+ * Note that the |handle| is different from the handle that the embedder holds
|
||
|
+ * for retaining the object. It is up to the embedder to find the original
|
||
|
+ * handle via the object or class id.
|
||
|
*/
|
||
|
virtual void ResetHandleInNonTracingGC(
|
||
|
- const v8::TracedGlobal<v8::Value>& handle) {}
|
||
|
+ const v8::TracedReference<v8::Value>& handle);
|
||
|
+ V8_DEPRECATE_SOON(
|
||
|
+ "Use TracedReference version when not requiring destructors.",
|
||
|
+ virtual void ResetHandleInNonTracingGC(
|
||
|
+ const v8::TracedGlobal<v8::Value>& handle));
|
||
|
|
||
|
/*
|
||
|
* Called by the embedder to immediately perform a full garbage collection.
|
||
|
@@ -9103,8 +9229,12 @@ class V8_EXPORT V8 {
|
||
|
template <class T>
|
||
|
friend class Maybe;
|
||
|
template <class T>
|
||
|
+ friend class TracedReferenceBase;
|
||
|
+ template <class T>
|
||
|
friend class TracedGlobal;
|
||
|
template <class T>
|
||
|
+ friend class TracedReference;
|
||
|
+ template <class T>
|
||
|
friend class WeakCallbackInfo;
|
||
|
template <class T> friend class Eternal;
|
||
|
template <class T> friend class PersistentBase;
|
||
|
@@ -9975,7 +10105,7 @@ Local<T> Local<T>::New(Isolate* isolate,
|
||
|
}
|
||
|
|
||
|
template <class T>
|
||
|
-Local<T> Local<T>::New(Isolate* isolate, const TracedGlobal<T>& that) {
|
||
|
+Local<T> Local<T>::New(Isolate* isolate, const TracedReferenceBase<T>& that) {
|
||
|
return New(isolate, that.val_);
|
||
|
}
|
||
|
|
||
|
@@ -10156,26 +10286,20 @@ Global<T>& Global<T>::operator=(Global<S
|
||
|
}
|
||
|
|
||
|
template <class T>
|
||
|
-TracedGlobal<T>::WrappedForDestruction::~WrappedForDestruction() {
|
||
|
- if (value == nullptr) return;
|
||
|
- V8::DisposeTracedGlobal(reinterpret_cast<internal::Address*>(value));
|
||
|
- value = nullptr;
|
||
|
-}
|
||
|
-
|
||
|
-template <class T>
|
||
|
-T* TracedGlobal<T>::New(Isolate* isolate, T* that, void* slot) {
|
||
|
+T* TracedReferenceBase<T>::New(Isolate* isolate, T* that, void* slot,
|
||
|
+ DestructionMode destruction_mode) {
|
||
|
if (that == nullptr) return nullptr;
|
||
|
internal::Address* p = reinterpret_cast<internal::Address*>(that);
|
||
|
return reinterpret_cast<T*>(V8::GlobalizeTracedReference(
|
||
|
reinterpret_cast<internal::Isolate*>(isolate), p,
|
||
|
reinterpret_cast<internal::Address*>(slot),
|
||
|
- TracedGlobalTrait<TracedGlobal<T>>::kRequiresExplicitDestruction));
|
||
|
+ destruction_mode == kWithDestructor));
|
||
|
}
|
||
|
|
||
|
template <class T>
|
||
|
-void TracedGlobal<T>::Reset() {
|
||
|
+void TracedReferenceBase<T>::Reset() {
|
||
|
if (IsEmpty()) return;
|
||
|
- V8::DisposeTracedGlobal(reinterpret_cast<internal::Address*>(**this));
|
||
|
+ V8::DisposeTracedGlobal(reinterpret_cast<internal::Address*>(val_));
|
||
|
val_ = nullptr;
|
||
|
}
|
||
|
|
||
|
@@ -10185,7 +10309,8 @@ void TracedGlobal<T>::Reset(Isolate* iso
|
||
|
TYPE_CHECK(T, S);
|
||
|
Reset();
|
||
|
if (other.IsEmpty()) return;
|
||
|
- this->val_ = New(isolate, other.val_, &val_);
|
||
|
+ this->val_ = this->New(isolate, other.val_, &this->val_,
|
||
|
+ TracedReferenceBase<T>::kWithDestructor);
|
||
|
}
|
||
|
|
||
|
template <class T>
|
||
|
@@ -10233,28 +10358,83 @@ TracedGlobal<T>& TracedGlobal<T>::operat
|
||
|
}
|
||
|
|
||
|
template <class T>
|
||
|
-void TracedGlobal<T>::SetWrapperClassId(uint16_t class_id) {
|
||
|
+template <class S>
|
||
|
+void TracedReference<T>::Reset(Isolate* isolate, const Local<S>& other) {
|
||
|
+ TYPE_CHECK(T, S);
|
||
|
+ Reset();
|
||
|
+ if (other.IsEmpty()) return;
|
||
|
+ this->val_ = this->New(isolate, other.val_, &this->val_,
|
||
|
+ TracedReferenceBase<T>::kWithoutDestructor);
|
||
|
+}
|
||
|
+
|
||
|
+template <class T>
|
||
|
+template <class S>
|
||
|
+TracedReference<T>& TracedReference<T>::operator=(TracedReference<S>&& rhs) {
|
||
|
+ TYPE_CHECK(T, S);
|
||
|
+ *this = std::move(rhs.template As<T>());
|
||
|
+ return *this;
|
||
|
+}
|
||
|
+
|
||
|
+template <class T>
|
||
|
+template <class S>
|
||
|
+TracedReference<T>& TracedReference<T>::operator=(
|
||
|
+ const TracedReference<S>& rhs) {
|
||
|
+ TYPE_CHECK(T, S);
|
||
|
+ *this = rhs.template As<T>();
|
||
|
+ return *this;
|
||
|
+}
|
||
|
+
|
||
|
+template <class T>
|
||
|
+TracedReference<T>& TracedReference<T>::operator=(TracedReference&& rhs) {
|
||
|
+ if (this != &rhs) {
|
||
|
+ this->Reset();
|
||
|
+ if (rhs.val_ != nullptr) {
|
||
|
+ this->val_ = rhs.val_;
|
||
|
+ V8::MoveTracedGlobalReference(
|
||
|
+ reinterpret_cast<internal::Address**>(&rhs.val_),
|
||
|
+ reinterpret_cast<internal::Address**>(&this->val_));
|
||
|
+ rhs.val_ = nullptr;
|
||
|
+ }
|
||
|
+ }
|
||
|
+ return *this;
|
||
|
+}
|
||
|
+
|
||
|
+template <class T>
|
||
|
+TracedReference<T>& TracedReference<T>::operator=(const TracedReference& rhs) {
|
||
|
+ if (this != &rhs) {
|
||
|
+ this->Reset();
|
||
|
+ if (rhs.val_ != nullptr) {
|
||
|
+ V8::CopyTracedGlobalReference(
|
||
|
+ reinterpret_cast<const internal::Address* const*>(&rhs.val_),
|
||
|
+ reinterpret_cast<internal::Address**>(&this->val_));
|
||
|
+ }
|
||
|
+ }
|
||
|
+ return *this;
|
||
|
+}
|
||
|
+
|
||
|
+template <class T>
|
||
|
+void TracedReferenceBase<T>::SetWrapperClassId(uint16_t class_id) {
|
||
|
typedef internal::Internals I;
|
||
|
if (IsEmpty()) return;
|
||
|
- internal::Address* obj = reinterpret_cast<internal::Address*>(**this);
|
||
|
+ internal::Address* obj = reinterpret_cast<internal::Address*>(val_);
|
||
|
uint8_t* addr = reinterpret_cast<uint8_t*>(obj) + I::kNodeClassIdOffset;
|
||
|
*reinterpret_cast<uint16_t*>(addr) = class_id;
|
||
|
}
|
||
|
|
||
|
template <class T>
|
||
|
-uint16_t TracedGlobal<T>::WrapperClassId() const {
|
||
|
+uint16_t TracedReferenceBase<T>::WrapperClassId() const {
|
||
|
typedef internal::Internals I;
|
||
|
if (IsEmpty()) return 0;
|
||
|
- internal::Address* obj = reinterpret_cast<internal::Address*>(**this);
|
||
|
+ internal::Address* obj = reinterpret_cast<internal::Address*>(val_);
|
||
|
uint8_t* addr = reinterpret_cast<uint8_t*>(obj) + I::kNodeClassIdOffset;
|
||
|
return *reinterpret_cast<uint16_t*>(addr);
|
||
|
}
|
||
|
|
||
|
template <class T>
|
||
|
-void TracedGlobal<T>::SetFinalizationCallback(
|
||
|
+void TracedReferenceBase<T>::SetFinalizationCallback(
|
||
|
void* parameter, typename WeakCallbackInfo<void>::Callback callback) {
|
||
|
- V8::SetFinalizationCallbackTraced(
|
||
|
- reinterpret_cast<internal::Address*>(**this), parameter, callback);
|
||
|
+ V8::SetFinalizationCallbackTraced(reinterpret_cast<internal::Address*>(val_),
|
||
|
+ parameter, callback);
|
||
|
}
|
||
|
|
||
|
template <typename T>
|
||
|
@@ -10273,12 +10453,12 @@ void ReturnValue<T>::Set(const Global<S>
|
||
|
|
||
|
template <typename T>
|
||
|
template <typename S>
|
||
|
-void ReturnValue<T>::Set(const TracedGlobal<S>& handle) {
|
||
|
+void ReturnValue<T>::Set(const TracedReferenceBase<S>& handle) {
|
||
|
TYPE_CHECK(T, S);
|
||
|
if (V8_UNLIKELY(handle.IsEmpty())) {
|
||
|
*value_ = GetDefaultValue();
|
||
|
} else {
|
||
|
- *value_ = *reinterpret_cast<internal::Address*>(*handle);
|
||
|
+ *value_ = *reinterpret_cast<internal::Address*>(handle.val_);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
diff -up chromium-78.0.3904.70/v8/src/api/api.cc.implement-tracedreference chromium-78.0.3904.70/v8/src/api/api.cc
|
||
|
--- chromium-78.0.3904.70/v8/src/api/api.cc.implement-tracedreference 2019-10-24 09:18:56.712105100 -0400
|
||
|
+++ chromium-78.0.3904.70/v8/src/api/api.cc 2019-10-24 09:20:17.428555637 -0400
|
||
|
@@ -10346,11 +10346,12 @@ void EmbedderHeapTracer::DecreaseAllocat
|
||
|
}
|
||
|
|
||
|
void EmbedderHeapTracer::RegisterEmbedderReference(
|
||
|
- const TracedGlobal<v8::Value>& ref) {
|
||
|
+ const TracedReferenceBase<v8::Value>& ref) {
|
||
|
if (ref.IsEmpty()) return;
|
||
|
|
||
|
i::Heap* const heap = reinterpret_cast<i::Isolate*>(isolate_)->heap();
|
||
|
- heap->RegisterExternallyReferencedObject(reinterpret_cast<i::Address*>(*ref));
|
||
|
+ heap->RegisterExternallyReferencedObject(
|
||
|
+ reinterpret_cast<i::Address*>(ref.val_));
|
||
|
}
|
||
|
|
||
|
void EmbedderHeapTracer::IterateTracedGlobalHandles(
|
||
|
@@ -10360,6 +10361,26 @@ void EmbedderHeapTracer::IterateTracedGl
|
||
|
isolate->global_handles()->IterateTracedNodes(visitor);
|
||
|
}
|
||
|
|
||
|
+bool EmbedderHeapTracer::IsRootForNonTracingGC(
|
||
|
+ const v8::TracedReference<v8::Value>& handle) {
|
||
|
+ return true;
|
||
|
+}
|
||
|
+
|
||
|
+bool EmbedderHeapTracer::IsRootForNonTracingGC(
|
||
|
+ const v8::TracedGlobal<v8::Value>& handle) {
|
||
|
+ return true;
|
||
|
+}
|
||
|
+
|
||
|
+void EmbedderHeapTracer::ResetHandleInNonTracingGC(
|
||
|
+ const v8::TracedReference<v8::Value>& handle) {
|
||
|
+ UNREACHABLE();
|
||
|
+}
|
||
|
+
|
||
|
+void EmbedderHeapTracer::ResetHandleInNonTracingGC(
|
||
|
+ const v8::TracedGlobal<v8::Value>& handle) {
|
||
|
+ UNREACHABLE();
|
||
|
+}
|
||
|
+
|
||
|
namespace internal {
|
||
|
|
||
|
const size_t HandleScopeImplementer::kEnteredContextsOffset =
|
||
|
diff -up chromium-78.0.3904.70/v8/src/handles/global-handles.cc.implement-tracedreference chromium-78.0.3904.70/v8/src/handles/global-handles.cc
|
||
|
--- chromium-78.0.3904.70/v8/src/handles/global-handles.cc.implement-tracedreference 2019-10-24 09:20:39.954123225 -0400
|
||
|
+++ chromium-78.0.3904.70/v8/src/handles/global-handles.cc 2019-10-24 09:21:45.911857072 -0400
|
||
|
@@ -901,8 +901,13 @@ void GlobalHandles::IdentifyWeakUnmodifi
|
||
|
DCHECK(node->is_root());
|
||
|
if (is_unmodified(node->location())) {
|
||
|
v8::Value* value = ToApi<v8::Value>(node->handle());
|
||
|
- node->set_root(tracer->IsRootForNonTracingGC(
|
||
|
- *reinterpret_cast<v8::TracedGlobal<v8::Value>*>(&value)));
|
||
|
+ if (node->has_destructor()) {
|
||
|
+ node->set_root(tracer->IsRootForNonTracingGC(
|
||
|
+ *reinterpret_cast<v8::TracedGlobal<v8::Value>*>(&value)));
|
||
|
+ } else {
|
||
|
+ node->set_root(tracer->IsRootForNonTracingGC(
|
||
|
+ *reinterpret_cast<v8::TracedReference<v8::Value>*>(&value)));
|
||
|
+ }
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
@@ -990,7 +995,7 @@ void GlobalHandles::IterateYoungWeakUnmo
|
||
|
} else {
|
||
|
v8::Value* value = ToApi<v8::Value>(node->handle());
|
||
|
tracer->ResetHandleInNonTracingGC(
|
||
|
- *reinterpret_cast<v8::TracedGlobal<v8::Value>*>(&value));
|
||
|
+ *reinterpret_cast<v8::TracedReference<v8::Value>*>(&value));
|
||
|
DCHECK(!node->IsInUse());
|
||
|
}
|
||
|
|
||
|
@@ -1271,8 +1276,13 @@ void GlobalHandles::IterateTracedNodes(
|
||
|
for (TracedNode* node : *traced_nodes_) {
|
||
|
if (node->IsInUse()) {
|
||
|
v8::Value* value = ToApi<v8::Value>(node->handle());
|
||
|
- visitor->VisitTracedGlobalHandle(
|
||
|
- *reinterpret_cast<v8::TracedGlobal<v8::Value>*>(&value));
|
||
|
+ if (node->has_destructor()) {
|
||
|
+ visitor->VisitTracedGlobalHandle(
|
||
|
+ *reinterpret_cast<v8::TracedGlobal<v8::Value>*>(&value));
|
||
|
+ } else {
|
||
|
+ visitor->VisitTracedReference(
|
||
|
+ *reinterpret_cast<v8::TracedReference<v8::Value>*>(&value));
|
||
|
+ }
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
diff -up chromium-78.0.3904.70/v8/src/heap/embedder-tracing.h.implement-tracedreference chromium-78.0.3904.70/v8/src/heap/embedder-tracing.h
|
||
|
--- chromium-78.0.3904.70/v8/src/heap/embedder-tracing.h.implement-tracedreference 2019-10-24 09:22:03.664519559 -0400
|
||
|
+++ chromium-78.0.3904.70/v8/src/heap/embedder-tracing.h 2019-10-24 09:22:45.197729964 -0400
|
||
|
@@ -57,7 +57,12 @@ class V8_EXPORT_PRIVATE LocalEmbedderHea
|
||
|
bool IsRootForNonTracingGC(const v8::TracedGlobal<v8::Value>& handle) {
|
||
|
return !InUse() || remote_tracer_->IsRootForNonTracingGC(handle);
|
||
|
}
|
||
|
- void ResetHandleInNonTracingGC(const v8::TracedGlobal<v8::Value>& handle) {
|
||
|
+
|
||
|
+ bool IsRootForNonTracingGC(const v8::TracedReference<v8::Value>& handle) {
|
||
|
+ return !InUse() || remote_tracer_->IsRootForNonTracingGC(handle);
|
||
|
+ }
|
||
|
+
|
||
|
+ void ResetHandleInNonTracingGC(const v8::TracedReference<v8::Value>& handle) {
|
||
|
// Resetting is only called when IsRootForNonTracingGC returns false which
|
||
|
// can only happen the EmbedderHeapTracer is set on API level.
|
||
|
DCHECK(InUse());
|