Chromium Code Reviews| 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..5ad7a6cb8ce2fffa534a2ccad7d21f57b0ab781a 100644 |
| --- a/third_party/WebKit/Source/platform/heap/Handle.h |
| +++ b/third_party/WebKit/Source/platform/heap/Handle.h |
| @@ -656,6 +656,36 @@ public: |
| } |
| }; |
| +template<typename T, bool = IsGarbageCollectedMixin<T>::value> class GarbageCollectedMixinTrait; |
| +template<typename T> |
| +class GarbageCollectedMixinTrait<T, true> { |
| +public: |
| + static HeapObjectHeader* heapObjectHeader(T* obj) |
| + { |
| + return obj->heapObjectHeader(); |
| + } |
| + static uint16_t gcGeneration(T* obj) |
| + { |
| + // While constructing GarbageCollectedMixin classes, we skip looking |
| + // for gcGeneration, because the object may not be fully allocated. |
|
haraken
2015/11/10 16:37:05
Sorry, I'm getting confused. Why can't we call hea
peria
2015/11/11 02:46:34
obj->heapObjectHeader() (on line#665) depends on t
haraken
2015/11/11 04:19:29
Thanks for the clarification; now I understand the
peria
2015/11/11 05:51:51
SGTM
I moved this Trait to Heap.h in PS6.
|
| + if (ThreadState::current()->isGCForbidden()) |
|
haraken
2015/11/10 16:37:05
Let's rename isGCForbidden() to isConstructingGCMi
peria
2015/11/11 05:51:51
Renaming it looks confusing in other places, so I
|
| + return 0; |
| + return heapObjectHeader(obj)->gcGeneration(); |
| + } |
| +}; |
| +template<typename T> |
| +class GarbageCollectedMixinTrait<T, false> { |
| +public: |
| + static HeapObjectHeader* heapObjectHeader(T* obj) |
| + { |
| + return HeapObjectHeader::fromPayload(obj); |
| + } |
| + static uint16_t gcGeneration(T* obj) |
| + { |
| + return heapObjectHeader(obj)->gcGeneration(); |
| + } |
| +}; |
| + |
| // 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 +696,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 +794,7 @@ public: |
| Member& operator=(std::nullptr_t) |
| { |
| m_raw = nullptr; |
| + checkPointer(); |
| return *this; |
| } |
| @@ -771,17 +804,40 @@ public: |
| checkPointer(); |
| } |
| - T* get() const { return m_raw; } |
| + T* get() const |
| + { |
| +#if ENABLE(ASSERT) |
| + // Verify that this handle points a live on-heap object, if a pointer |
|
haraken
2015/11/10 16:37:05
points to
peria
2015/11/11 02:46:34
Done.
|
| + // has been assigned to this handle out of GarbageCollectedMixin constructions. |
| + if (m_raw && m_gcGeneration) { |
| + ASSERT(m_gcGeneration == GarbageCollectedMixinTrait<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; |
|
haraken
2015/11/10 16:37:05
You won't need this. Given that you're checking if
peria
2015/11/11 02:46:34
Agree. Done.
|
| 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 +855,18 @@ 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()); |
| + m_gcGeneration = GarbageCollectedMixinTrait<T>::gcGeneration(m_raw); |
|
haraken
2015/11/11 04:19:29
So you can update the code to:
HeapObjectHeader
peria
2015/11/11 05:51:51
Acknowledged.
|
| #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 +927,7 @@ public: |
| WeakMember& operator=(std::nullptr_t) |
| { |
| this->m_raw = nullptr; |
| + this->checkPointer(); |
| return *this; |
| } |
| @@ -941,13 +1000,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 +1474,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>> { |