| Index: third_party/WebKit/Source/platform/heap/Member.h
|
| diff --git a/third_party/WebKit/Source/platform/heap/Member.h b/third_party/WebKit/Source/platform/heap/Member.h
|
| index f342ba79f7e4751234d23411a47e357d0d3ddcb4..d37a06773d1073b9540429706fa1c2856f3be4eb 100644
|
| --- a/third_party/WebKit/Source/platform/heap/Member.h
|
| +++ b/third_party/WebKit/Source/platform/heap/Member.h
|
| @@ -13,54 +13,62 @@ namespace blink {
|
|
|
| template<typename T> class Persistent;
|
|
|
| -// 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.
|
| -// During the mark phase of the GC all live objects are marked as live and
|
| -// all Member fields of a live object will be traced marked as live as well.
|
| -template<typename T>
|
| -class Member {
|
| +enum class TracenessMemberConfiguration {
|
| + Traced,
|
| + Untraced,
|
| +};
|
| +
|
| +template<typename T, TracenessMemberConfiguration tracenessConfiguration = TracenessMemberConfiguration::Traced>
|
| +class MemberBase {
|
| DISALLOW_NEW_EXCEPT_PLACEMENT_NEW();
|
| public:
|
| - Member() : m_raw(nullptr)
|
| + MemberBase() : m_raw(nullptr)
|
| {
|
| + saveCreationThreadState();
|
| }
|
|
|
| - Member(std::nullptr_t) : m_raw(nullptr)
|
| + MemberBase(std::nullptr_t) : m_raw(nullptr)
|
| {
|
| + saveCreationThreadState();
|
| }
|
|
|
| - Member(T* raw) : m_raw(raw)
|
| + MemberBase(T* raw) : m_raw(raw)
|
| {
|
| + saveCreationThreadState();
|
| checkPointer();
|
| }
|
|
|
| - explicit Member(T& raw) : m_raw(&raw)
|
| + explicit MemberBase(T& raw) : m_raw(&raw)
|
| {
|
| + saveCreationThreadState();
|
| checkPointer();
|
| }
|
|
|
| - Member(WTF::HashTableDeletedValueType) : m_raw(reinterpret_cast<T*>(-1))
|
| + MemberBase(WTF::HashTableDeletedValueType) : m_raw(reinterpret_cast<T*>(-1))
|
| {
|
| + saveCreationThreadState();
|
| }
|
|
|
| bool isHashTableDeletedValue() const { return m_raw == reinterpret_cast<T*>(-1); }
|
|
|
| - Member(const Member& other) : m_raw(other)
|
| + MemberBase(const MemberBase& other) : m_raw(other)
|
| {
|
| + saveCreationThreadState();
|
| checkPointer();
|
| }
|
|
|
| template<typename U>
|
| - Member(const Persistent<U>& other)
|
| + MemberBase(const Persistent<U>& other)
|
| {
|
| + saveCreationThreadState();
|
| m_raw = other;
|
| checkPointer();
|
| }
|
|
|
| template<typename U>
|
| - Member(const Member<U>& other) : m_raw(other)
|
| + MemberBase(const MemberBase<U>& other) : m_raw(other)
|
| {
|
| + saveCreationThreadState();
|
| checkPointer();
|
| }
|
|
|
| @@ -79,7 +87,7 @@ public:
|
| T& operator*() const { return *m_raw; }
|
|
|
| template<typename U>
|
| - Member& operator=(const Persistent<U>& other)
|
| + MemberBase& operator=(const Persistent<U>& other)
|
| {
|
| m_raw = other;
|
| checkPointer();
|
| @@ -87,7 +95,7 @@ public:
|
| }
|
|
|
| template<typename U>
|
| - Member& operator=(const Member<U>& other)
|
| + MemberBase& operator=(const MemberBase<U>& other)
|
| {
|
| m_raw = other;
|
| checkPointer();
|
| @@ -95,20 +103,20 @@ public:
|
| }
|
|
|
| template<typename U>
|
| - Member& operator=(U* other)
|
| + MemberBase& operator=(U* other)
|
| {
|
| m_raw = other;
|
| checkPointer();
|
| return *this;
|
| }
|
|
|
| - Member& operator=(std::nullptr_t)
|
| + MemberBase& operator=(std::nullptr_t)
|
| {
|
| m_raw = nullptr;
|
| return *this;
|
| }
|
|
|
| - void swap(Member<T>& other)
|
| + void swap(MemberBase<T>& other)
|
| {
|
| std::swap(m_raw, other.m_raw);
|
| checkPointer();
|
| @@ -122,7 +130,7 @@ public:
|
| protected:
|
| void checkPointer()
|
| {
|
| -#if ENABLE(ASSERT) && defined(ADDRESS_SANITIZER)
|
| +#if DCHECK_IS_ON()
|
| if (!m_raw)
|
| return;
|
| // HashTable can store a special value (which is not aligned to the
|
| @@ -132,6 +140,23 @@ protected:
|
| if (reinterpret_cast<intptr_t>(m_raw) % allocationGranularity)
|
| return;
|
|
|
| + if (tracenessConfiguration != TracenessMemberConfiguration::Untraced) {
|
| + ThreadState* current = ThreadState::current();
|
| + DCHECK(current);
|
| + // m_creationThreadState may be null when this is used in a heap
|
| + // collection which initialized the Member with memset and the
|
| + // constructor wasn't called.
|
| + if (m_creationThreadState) {
|
| + // Member should point to objects that belong in the same ThreadHeap.
|
| + DCHECK_EQ(&ThreadState::fromObject(m_raw)->heap(), &m_creationThreadState->heap());
|
| + // Member should point to objects that belong in the same ThreadHeap.
|
| + DCHECK_EQ(¤t->heap(), &m_creationThreadState->heap());
|
| + } else {
|
| + DCHECK_EQ(&ThreadState::fromObject(m_raw)->heap(), ¤t->heap());
|
| + }
|
| + }
|
| +
|
| +#if defined(ADDRESS_SANITIZER)
|
| // TODO(haraken): What we really want to check here is that the pointer
|
| // is a traceable object. In other words, the pointer is either of:
|
| //
|
| @@ -145,15 +170,95 @@ protected:
|
| if (IsFullyDefined<T>::value && !IsGarbageCollectedMixin<T>::value)
|
| ASSERT(HeapObjectHeader::fromPayload(m_raw)->checkHeader());
|
| #endif
|
| +#endif
|
| + }
|
| +
|
| + void saveCreationThreadState()
|
| + {
|
| +#if DCHECK_IS_ON()
|
| + if (tracenessConfiguration == TracenessMemberConfiguration::Untraced) {
|
| + m_creationThreadState = nullptr;
|
| + } else {
|
| + m_creationThreadState = ThreadState::current();
|
| + // Members should be created in an attached thread. But an empty
|
| + // value Member may be created on an unattached thread by a heap
|
| + // collection iterator.
|
| + DCHECK(m_creationThreadState || !m_raw);
|
| + }
|
| +#endif
|
| }
|
|
|
| T* m_raw;
|
| +#if DCHECK_IS_ON()
|
| + const ThreadState* m_creationThreadState;
|
| +#endif
|
|
|
| template<bool x, WTF::WeakHandlingFlag y, WTF::ShouldWeakPointersBeMarkedStrongly z, typename U, typename V> friend struct CollectionBackingTraceTrait;
|
| friend class Visitor;
|
|
|
| };
|
|
|
| +// 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.
|
| +// During the mark phase of the GC all live objects are marked as live and
|
| +// all Member fields of a live object will be traced marked as live as well.
|
| +template<typename T>
|
| +class Member : public MemberBase<T, TracenessMemberConfiguration::Traced> {
|
| + DISALLOW_NEW_EXCEPT_PLACEMENT_NEW();
|
| + typedef MemberBase<T, TracenessMemberConfiguration::Traced> Parent;
|
| +public:
|
| + Member() : Parent() { }
|
| + Member(std::nullptr_t) : Parent(nullptr) { }
|
| + Member(T* raw) : Parent(raw) { }
|
| + Member(T& raw) : Parent(raw) { }
|
| + Member(WTF::HashTableDeletedValueType x) : Parent(x) { }
|
| +
|
| + Member(const Member& other) : Parent(other) { }
|
| + template<typename U>
|
| + Member(const Member<U>& other) : Parent(other) { }
|
| + template<typename U>
|
| + Member(const Persistent<U>& other) : Parent(other) { }
|
| +
|
| + template<typename U>
|
| + Member& operator=(const Persistent<U>& other)
|
| + {
|
| + Parent::operator=(other);
|
| + return *this;
|
| + }
|
| +
|
| + template<typename U>
|
| + Member& operator=(const Member<U>& other)
|
| + {
|
| + Parent::operator=(other);
|
| + return *this;
|
| + }
|
| +
|
| + template<typename U>
|
| + Member& operator=(const WeakMember<U>& other)
|
| + {
|
| + Parent::operator=(other);
|
| + return *this;
|
| + }
|
| +
|
| + template<typename U>
|
| + Member& operator=(U* other)
|
| + {
|
| + Parent::operator=(other);
|
| + return *this;
|
| + }
|
| +
|
| + Member& operator=(std::nullptr_t)
|
| + {
|
| + Parent::operator=(nullptr);
|
| + return *this;
|
| + }
|
| +
|
| +protected:
|
| + 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
|
| // heap allocated objects.
|
| // However instead of creating a strong pointer to the object, the WeakMember creates
|
| @@ -161,21 +266,22 @@ protected:
|
| // to a heap allocated object are weak the object will be garbage collected. At the
|
| // time of GC the weak pointers will automatically be set to null.
|
| template<typename T>
|
| -class WeakMember : public Member<T> {
|
| +class WeakMember : public MemberBase<T, TracenessMemberConfiguration::Traced> {
|
| + typedef MemberBase<T, TracenessMemberConfiguration::Traced> Parent;
|
| public:
|
| - WeakMember() : Member<T>() { }
|
| + WeakMember() : Parent() { }
|
|
|
| - WeakMember(std::nullptr_t) : Member<T>(nullptr) { }
|
| + WeakMember(std::nullptr_t) : Parent(nullptr) { }
|
|
|
| - WeakMember(T* raw) : Member<T>(raw) { }
|
| + WeakMember(T* raw) : Parent(raw) { }
|
|
|
| - WeakMember(WTF::HashTableDeletedValueType x) : Member<T>(x) { }
|
| + WeakMember(WTF::HashTableDeletedValueType x) : Parent(x) { }
|
|
|
| template<typename U>
|
| - WeakMember(const Persistent<U>& other) : Member<T>(other) { }
|
| + WeakMember(const Persistent<U>& other) : Parent(other) { }
|
|
|
| template<typename U>
|
| - WeakMember(const Member<U>& other) : Member<T>(other) { }
|
| + WeakMember(const Member<U>& other) : Parent(other) { }
|
|
|
| template<typename U>
|
| WeakMember& operator=(const Persistent<U>& other)
|
| @@ -222,21 +328,22 @@ private:
|
| // course, it must be guaranteed that the pointing on-heap object is kept alive
|
| // while the raw pointer is pointing to the object.
|
| template<typename T>
|
| -class UntracedMember final : public Member<T> {
|
| +class UntracedMember final : public MemberBase<T, TracenessMemberConfiguration::Untraced> {
|
| + typedef MemberBase<T, TracenessMemberConfiguration::Untraced> Parent;
|
| public:
|
| - UntracedMember() : Member<T>() { }
|
| + UntracedMember() : Parent() { }
|
|
|
| - UntracedMember(std::nullptr_t) : Member<T>(nullptr) { }
|
| + UntracedMember(std::nullptr_t) : Parent(nullptr) { }
|
|
|
| - UntracedMember(T* raw) : Member<T>(raw) { }
|
| + UntracedMember(T* raw) : Parent(raw) { }
|
|
|
| template<typename U>
|
| - UntracedMember(const Persistent<U>& other) : Member<T>(other) { }
|
| + UntracedMember(const Persistent<U>& other) : Parent(other) { }
|
|
|
| template<typename U>
|
| - UntracedMember(const Member<U>& other) : Member<T>(other) { }
|
| + UntracedMember(const Member<U>& other) : Parent(other) { }
|
|
|
| - UntracedMember(WTF::HashTableDeletedValueType x) : Member<T>(x) { }
|
| + UntracedMember(WTF::HashTableDeletedValueType x) : Parent(x) { }
|
|
|
| template<typename U>
|
| UntracedMember& operator=(const Persistent<U>& other)
|
|
|