Index: third_party/WebKit/Source/platform/heap/Persistent.h |
diff --git a/third_party/WebKit/Source/platform/heap/Persistent.h b/third_party/WebKit/Source/platform/heap/Persistent.h |
index 8aa3708af2df13521feaaa734413965cde3ac299..64b03d3a5a5976412dda1f316530dca8c83291c0 100644 |
--- a/third_party/WebKit/Source/platform/heap/Persistent.h |
+++ b/third_party/WebKit/Source/platform/heap/Persistent.h |
@@ -77,12 +77,20 @@ public: |
checkPointer(); |
} |
+ PersistentBase(WTF::HashTableDeletedValueType) : m_raw(reinterpret_cast<T*>(-1)) |
+ { |
+ initialize(); |
+ checkPointer(); |
+ } |
+ |
~PersistentBase() |
{ |
uninitialize(); |
m_raw = nullptr; |
} |
+ bool isHashTableDeletedValue() const { return m_raw == reinterpret_cast<T*>(-1); } |
+ |
template<typename VisitorDispatcher> |
void trace(VisitorDispatcher visitor) |
{ |
@@ -184,7 +192,7 @@ private: |
void initialize() |
{ |
ASSERT(!m_persistentNode); |
- if (!m_raw) |
+ if (!m_raw || isHashTableDeletedValue()) |
return; |
TraceCallback traceCallback = TraceMethodDelegate<PersistentBase<T, weaknessConfiguration, crossThreadnessConfiguration>, &PersistentBase<T, weaknessConfiguration, crossThreadnessConfiguration>::trace>::trampoline; |
@@ -202,14 +210,15 @@ private: |
void uninitialize() |
{ |
+ if (!m_persistentNode) |
sof
2016/05/25 13:11:42
Moving this up here (again) will lead to a race.
|
+ return; |
+ |
if (crossThreadnessConfiguration == CrossThreadPersistentConfiguration) { |
if (acquireLoad(reinterpret_cast<void* volatile*>(&m_persistentNode))) |
ProcessHeap::crossThreadPersistentRegion().freePersistentNode(m_persistentNode); |
return; |
} |
- if (!m_persistentNode) |
- return; |
ThreadState* state = ThreadStateFor<ThreadingTrait<T>::Affinity>::state(); |
ASSERT(state->checkThread()); |
// Persistent handle must be created and destructed in the same thread. |
@@ -221,7 +230,7 @@ private: |
void checkPointer() |
{ |
#if ENABLE(ASSERT) && defined(ADDRESS_SANITIZER) |
- if (!m_raw) |
+ if (!m_raw || isHashTableDeletedValue()) |
return; |
// ThreadHeap::isHeapObjectAlive(m_raw) checks that m_raw is a traceable |
@@ -372,6 +381,7 @@ public: |
CrossThreadPersistent(const CrossThreadPersistent<U>& other) : Parent(other) { } |
template<typename U> |
CrossThreadPersistent(const Member<U>& other) : Parent(other) { } |
+ CrossThreadPersistent(WTF::HashTableDeletedValueType x) : Parent(x) { } |
T* atomicGet() { return Parent::atomicGet(); } |
@@ -682,6 +692,17 @@ template<typename T, typename U> inline bool operator!=(const Persistent<T>& a, |
namespace WTF { |
+template <typename T> |
+struct CrossThreadPersistentHash : MemberHash<T> { |
+ STATIC_ONLY(CrossThreadPersistentHash); |
+}; |
+ |
+template <typename T> |
+struct DefaultHash<blink::CrossThreadPersistent<T>> { |
+ STATIC_ONLY(DefaultHash); |
+ using Hash = CrossThreadPersistentHash<T>; |
+}; |
+ |
template<typename T> |
struct ParamStorageTraits<blink::WeakPersistentThisPointer<T>> { |
STATIC_ONLY(ParamStorageTraits); |