| Index: third_party/WebKit/Source/platform/heap/Handle.h
|
| diff --git a/third_party/WebKit/Source/platform/heap/Handle.h b/third_party/WebKit/Source/platform/heap/Handle.h
|
| index b5e0eb399a1ed538ee1418d8a14089c51250026a..ab8953b963a4292a895679463a62b03e311a9bf4 100644
|
| --- a/third_party/WebKit/Source/platform/heap/Handle.h
|
| +++ b/third_party/WebKit/Source/platform/heap/Handle.h
|
| @@ -656,6 +656,24 @@ public:
|
| }
|
| };
|
|
|
| +template<typename T, bool = IsGarbageCollectedMixin<T>::value> class GCMixinTrait;
|
| +template<typename T>
|
| +class GCMixinTrait<T, true> {
|
| +public:
|
| + static HeapObjectHeader* heapObjectHeader(T* obj)
|
| + {
|
| + return obj->heapObjectHeader();
|
| + }
|
| +};
|
| +template<typename T>
|
| +class GCMixinTrait<T, false> {
|
| +public:
|
| + static HeapObjectHeader* heapObjectHeader(T* obj)
|
| + {
|
| + return HeapObjectHeader::fromPayload(obj);
|
| + }
|
| +};
|
| +
|
| // Members are used in classes to contain strong pointers to other oilpan heap
|
| // allocated objects.
|
| // All Member fields of a class must be traced in the class' trace method.
|
| @@ -666,10 +684,12 @@ class Member {
|
| public:
|
| Member() : m_raw(nullptr)
|
| {
|
| + checkPointer();
|
| }
|
|
|
| Member(std::nullptr_t) : m_raw(nullptr)
|
| {
|
| + checkPointer();
|
| }
|
|
|
| Member(T* raw) : m_raw(raw)
|
| @@ -762,6 +782,7 @@ public:
|
| Member& operator=(std::nullptr_t)
|
| {
|
| m_raw = nullptr;
|
| + checkPointer();
|
| return *this;
|
| }
|
|
|
| @@ -771,17 +792,38 @@ public:
|
| checkPointer();
|
| }
|
|
|
| - T* get() const { return m_raw; }
|
| + T* get() const
|
| + {
|
| +#if ENABLE(ASSERT)
|
| + if (m_raw && m_gcGeneration) {
|
| + ASSERT(m_gcGeneration == GCMixinTrait<T>::heapObjectHeader(m_raw)->gcGeneration());
|
| + }
|
| +#endif
|
| + return m_raw;
|
| + }
|
|
|
| - void clear() { m_raw = nullptr; }
|
| + // This method is an accessor without any security checks, and it is
|
| + // expected to be used under some limited condition.
|
| + // So do NOT use it, if you do not know what it means.
|
| + T* unsafeGet() const
|
| + {
|
| + return m_raw;
|
| + }
|
|
|
| + void clear()
|
| + {
|
| + m_raw = nullptr;
|
| + checkPointer();
|
| + }
|
|
|
| protected:
|
| void checkPointer()
|
| {
|
| #if ENABLE(ASSERT)
|
| - if (!m_raw)
|
| + if (!m_raw) {
|
| + m_gcGeneration = 0;
|
| return;
|
| + }
|
| // HashTable can store a special value (which is not aligned to the
|
| // allocation granularity) to Member<> to represent a deleted entry.
|
| // Thus we treat a pointer that is not aligned to the granularity
|
| @@ -799,16 +841,22 @@ protected:
|
| // but we cannot call it here because it requires to include T.h.
|
| // So we currently only try to implement the check for (a), but do
|
| // not insist that T's definition is in scope.
|
| - if (IsFullyDefined<T>::value && !IsGarbageCollectedMixin<T>::value)
|
| - ASSERT(HeapObjectHeader::fromPayload(m_raw)->checkHeader());
|
| + if (IsFullyDefined<T>::value) {
|
| + m_gcGeneration = GCMixinTrait<T>::heapObjectHeader(m_raw)->gcGeneration();
|
| + } else {
|
| + m_gcGeneration = 0;
|
| + }
|
| #endif
|
| }
|
|
|
| T* m_raw;
|
|
|
| +#if ENABLE(ASSERT)
|
| + uint16_t m_gcGeneration;
|
| +#endif
|
| +
|
| template<bool x, WTF::WeakHandlingFlag y, WTF::ShouldWeakPointersBeMarkedStrongly z, typename U, typename V> friend struct CollectionBackingTraceTrait;
|
| friend class Visitor;
|
| -
|
| };
|
|
|
| // WeakMember is similar to Member in that it is used to point to other oilpan
|
| @@ -869,6 +917,7 @@ public:
|
| WeakMember& operator=(std::nullptr_t)
|
| {
|
| this->m_raw = nullptr;
|
| + this->checkPointer();
|
| return *this;
|
| }
|
|
|
| @@ -941,13 +990,14 @@ public:
|
| UntracedMember& operator=(std::nullptr_t)
|
| {
|
| this->m_raw = nullptr;
|
| + this->checkPointer();
|
| return *this;
|
| }
|
| };
|
|
|
| // Comparison operators between (Weak)Members, Persistents, and UntracedMembers.
|
| -template<typename T, typename U> inline bool operator==(const Member<T>& a, const Member<U>& b) { return a.get() == b.get(); }
|
| -template<typename T, typename U> inline bool operator!=(const Member<T>& a, const Member<U>& b) { return a.get() != b.get(); }
|
| +template<typename T, typename U> inline bool operator==(const Member<T>& a, const Member<U>& b) { return a.unsafeGet() == b.unsafeGet(); }
|
| +template<typename T, typename U> inline bool operator!=(const Member<T>& a, const Member<U>& b) { return a.unsafeGet() != b.unsafeGet(); }
|
| template<typename T, typename U> inline bool operator==(const Persistent<T>& a, const Persistent<U>& b) { return a.get() == b.get(); }
|
| template<typename T, typename U> inline bool operator!=(const Persistent<T>& a, const Persistent<U>& b) { return a.get() != b.get(); }
|
|
|
| @@ -1414,11 +1464,9 @@ template<typename T> struct PtrHash<blink::Member<T>> : PtrHash<T*> {
|
| static bool equal(const U& a, const V& b) { return a == b; }
|
| };
|
|
|
| -template<typename T> struct PtrHash<blink::WeakMember<T>> : PtrHash<blink::Member<T>> {
|
| -};
|
| +template<typename T> struct PtrHash<blink::WeakMember<T>> : PtrHash<blink::Member<T>> { };
|
|
|
| -template<typename T> struct PtrHash<blink::UntracedMember<T>> : PtrHash<blink::Member<T>> {
|
| -};
|
| +template<typename T> struct PtrHash<blink::UntracedMember<T>> : PtrHash<blink::Member<T>> { };
|
|
|
| // PtrHash is the default hash for hash tables with members.
|
| template<typename T> struct DefaultHash<blink::Member<T>> {
|
|
|