| OLD | NEW |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #ifndef Persistent_h | 5 #ifndef Persistent_h |
| 6 #define Persistent_h | 6 #define Persistent_h |
| 7 | 7 |
| 8 #include "platform/heap/Member.h" | 8 #include "platform/heap/Member.h" |
| 9 #include "platform/heap/PersistentNode.h" | 9 #include "platform/heap/PersistentNode.h" |
| 10 #include "wtf/Allocator.h" | 10 #include "wtf/Allocator.h" |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 84 } | 84 } |
| 85 | 85 |
| 86 ~PersistentBase() | 86 ~PersistentBase() |
| 87 { | 87 { |
| 88 uninitialize(); | 88 uninitialize(); |
| 89 m_raw = nullptr; | 89 m_raw = nullptr; |
| 90 } | 90 } |
| 91 | 91 |
| 92 bool isHashTableDeletedValue() const { return m_raw == reinterpret_cast<T*>(
-1); } | 92 bool isHashTableDeletedValue() const { return m_raw == reinterpret_cast<T*>(
-1); } |
| 93 | 93 |
| 94 template<typename VisitorDispatcher> | |
| 95 void trace(VisitorDispatcher visitor) | |
| 96 { | |
| 97 static_assert(sizeof(T), "T must be fully defined"); | |
| 98 static_assert(IsGarbageCollectedType<T>::value, "T needs to be a garbage
collected object"); | |
| 99 if (weaknessConfiguration == WeakPersistentConfiguration) { | |
| 100 visitor->registerWeakCell(&m_raw); | |
| 101 } else { | |
| 102 visitor->mark(m_raw); | |
| 103 } | |
| 104 } | |
| 105 | |
| 106 T* release() | 94 T* release() |
| 107 { | 95 { |
| 108 T* result = m_raw; | 96 T* result = m_raw; |
| 109 assign(nullptr); | 97 assign(nullptr); |
| 110 return result; | 98 return result; |
| 111 } | 99 } |
| 112 | 100 |
| 113 void clear() { assign(nullptr); } | 101 void clear() { assign(nullptr); } |
| 114 T& operator*() const { return *m_raw; } | 102 T& operator*() const { return *m_raw; } |
| 115 explicit operator bool() const { return m_raw; } | 103 explicit operator bool() const { return m_raw; } |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 181 m_raw = ptr; | 169 m_raw = ptr; |
| 182 checkPointer(); | 170 checkPointer(); |
| 183 if (m_raw) { | 171 if (m_raw) { |
| 184 if (!m_persistentNode) | 172 if (!m_persistentNode) |
| 185 initialize(); | 173 initialize(); |
| 186 return; | 174 return; |
| 187 } | 175 } |
| 188 uninitialize(); | 176 uninitialize(); |
| 189 } | 177 } |
| 190 | 178 |
| 179 template<typename VisitorDispatcher> |
| 180 void tracePersistent(VisitorDispatcher visitor) |
| 181 { |
| 182 static_assert(sizeof(T), "T must be fully defined"); |
| 183 static_assert(IsGarbageCollectedType<T>::value, "T needs to be a garbage
collected object"); |
| 184 if (weaknessConfiguration == WeakPersistentConfiguration) { |
| 185 visitor->registerWeakCell(&m_raw); |
| 186 } else { |
| 187 visitor->mark(m_raw); |
| 188 } |
| 189 } |
| 190 |
| 191 NO_LAZY_SWEEP_SANITIZE_ADDRESS | 191 NO_LAZY_SWEEP_SANITIZE_ADDRESS |
| 192 void initialize() | 192 void initialize() |
| 193 { | 193 { |
| 194 ASSERT(!m_persistentNode); | 194 ASSERT(!m_persistentNode); |
| 195 if (!m_raw || isHashTableDeletedValue()) | 195 if (!m_raw || isHashTableDeletedValue()) |
| 196 return; | 196 return; |
| 197 | 197 |
| 198 TraceCallback traceCallback = TraceMethodDelegate<PersistentBase<T, weak
nessConfiguration, crossThreadnessConfiguration>, &PersistentBase<T, weaknessCon
figuration, crossThreadnessConfiguration>::trace>::trampoline; | 198 TraceCallback traceCallback = TraceMethodDelegate<PersistentBase<T, weak
nessConfiguration, crossThreadnessConfiguration>, &PersistentBase<T, weaknessCon
figuration, crossThreadnessConfiguration>::tracePersistent>::trampoline; |
| 199 if (crossThreadnessConfiguration == CrossThreadPersistentConfiguration)
{ | 199 if (crossThreadnessConfiguration == CrossThreadPersistentConfiguration)
{ |
| 200 ProcessHeap::crossThreadPersistentRegion().allocatePersistentNode(m_
persistentNode, this, traceCallback); | 200 ProcessHeap::crossThreadPersistentRegion().allocatePersistentNode(m_
persistentNode, this, traceCallback); |
| 201 return; | 201 return; |
| 202 } | 202 } |
| 203 ThreadState* state = ThreadStateFor<ThreadingTrait<T>::Affinity>::state(
); | 203 ThreadState* state = ThreadStateFor<ThreadingTrait<T>::Affinity>::state(
); |
| 204 ASSERT(state->checkThread()); | 204 ASSERT(state->checkThread()); |
| 205 m_persistentNode = state->getPersistentRegion()->allocatePersistentNode(
this, traceCallback); | 205 m_persistentNode = state->getPersistentRegion()->allocatePersistentNode(
this, traceCallback); |
| 206 #if ENABLE(ASSERT) | 206 #if ENABLE(ASSERT) |
| 207 m_state = state; | 207 m_state = state; |
| 208 #endif | 208 #endif |
| (...skipping 281 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 490 PersistentHeapCollectionBase(const OtherCollection& other) : Collection(othe
r) | 490 PersistentHeapCollectionBase(const OtherCollection& other) : Collection(othe
r) |
| 491 { | 491 { |
| 492 initialize(); | 492 initialize(); |
| 493 } | 493 } |
| 494 | 494 |
| 495 ~PersistentHeapCollectionBase() | 495 ~PersistentHeapCollectionBase() |
| 496 { | 496 { |
| 497 uninitialize(); | 497 uninitialize(); |
| 498 } | 498 } |
| 499 | 499 |
| 500 template<typename VisitorDispatcher> | |
| 501 void trace(VisitorDispatcher visitor) | |
| 502 { | |
| 503 static_assert(sizeof(Collection), "Collection must be fully defined"); | |
| 504 visitor->trace(*static_cast<Collection*>(this)); | |
| 505 } | |
| 506 | |
| 507 // See PersistentBase::registerAsStaticReference() comment. | 500 // See PersistentBase::registerAsStaticReference() comment. |
| 508 PersistentHeapCollectionBase* registerAsStaticReference() | 501 PersistentHeapCollectionBase* registerAsStaticReference() |
| 509 { | 502 { |
| 510 if (m_persistentNode) { | 503 if (m_persistentNode) { |
| 511 ASSERT(ThreadState::current()); | 504 ASSERT(ThreadState::current()); |
| 512 ThreadState::current()->registerStaticPersistentNode(m_persistentNod
e, &PersistentHeapCollectionBase<Collection>::clearPersistentNode); | 505 ThreadState::current()->registerStaticPersistentNode(m_persistentNod
e, &PersistentHeapCollectionBase<Collection>::clearPersistentNode); |
| 513 LEAK_SANITIZER_IGNORE_OBJECT(this); | 506 LEAK_SANITIZER_IGNORE_OBJECT(this); |
| 514 } | 507 } |
| 515 return this; | 508 return this; |
| 516 } | 509 } |
| 517 | 510 |
| 518 private: | 511 private: |
| 519 | 512 |
| 513 template<typename VisitorDispatcher> |
| 514 void tracePersistent(VisitorDispatcher visitor) |
| 515 { |
| 516 static_assert(sizeof(Collection), "Collection must be fully defined"); |
| 517 visitor->trace(*static_cast<Collection*>(this)); |
| 518 } |
| 519 |
| 520 // Used when the registered PersistentNode of this object is | 520 // Used when the registered PersistentNode of this object is |
| 521 // released during ThreadState shutdown, clearing the association. | 521 // released during ThreadState shutdown, clearing the association. |
| 522 static void clearPersistentNode(void *self) | 522 static void clearPersistentNode(void *self) |
| 523 { | 523 { |
| 524 PersistentHeapCollectionBase<Collection>* collection = (reinterpret_cast
<PersistentHeapCollectionBase<Collection>*>(self)); | 524 PersistentHeapCollectionBase<Collection>* collection = (reinterpret_cast
<PersistentHeapCollectionBase<Collection>*>(self)); |
| 525 collection->uninitialize(); | 525 collection->uninitialize(); |
| 526 collection->clear(); | 526 collection->clear(); |
| 527 } | 527 } |
| 528 | 528 |
| 529 NO_LAZY_SWEEP_SANITIZE_ADDRESS | 529 NO_LAZY_SWEEP_SANITIZE_ADDRESS |
| 530 void initialize() | 530 void initialize() |
| 531 { | 531 { |
| 532 // FIXME: Derive affinity based on the collection. | 532 // FIXME: Derive affinity based on the collection. |
| 533 ThreadState* state = ThreadState::current(); | 533 ThreadState* state = ThreadState::current(); |
| 534 ASSERT(state->checkThread()); | 534 ASSERT(state->checkThread()); |
| 535 m_persistentNode = state->getPersistentRegion()->allocatePersistentNode(
this, TraceMethodDelegate<PersistentHeapCollectionBase<Collection>, &PersistentH
eapCollectionBase<Collection>::trace>::trampoline); | 535 m_persistentNode = state->getPersistentRegion()->allocatePersistentNode(
this, TraceMethodDelegate<PersistentHeapCollectionBase<Collection>, &PersistentH
eapCollectionBase<Collection>::tracePersistent>::trampoline); |
| 536 #if ENABLE(ASSERT) | 536 #if ENABLE(ASSERT) |
| 537 m_state = state; | 537 m_state = state; |
| 538 #endif | 538 #endif |
| 539 } | 539 } |
| 540 | 540 |
| 541 void uninitialize() | 541 void uninitialize() |
| 542 { | 542 { |
| 543 if (!m_persistentNode) | 543 if (!m_persistentNode) |
| 544 return; | 544 return; |
| 545 ThreadState* state = ThreadState::current(); | 545 ThreadState* state = ThreadState::current(); |
| (...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 742 // into it. | 742 // into it. |
| 743 // | 743 // |
| 744 // TODO(sof): remove this hack once wtf/Functional.h can also work with a ty
pe like | 744 // TODO(sof): remove this hack once wtf/Functional.h can also work with a ty
pe like |
| 745 // CrossThreadWeakPersistent<>. | 745 // CrossThreadWeakPersistent<>. |
| 746 static WeakPtr<T> unwrap(const StorageType& value) { return WeakPtr<T>(WeakR
eference<T>::create(value.get())); } | 746 static WeakPtr<T> unwrap(const StorageType& value) { return WeakPtr<T>(WeakR
eference<T>::create(value.get())); } |
| 747 }; | 747 }; |
| 748 | 748 |
| 749 } // namespace WTF | 749 } // namespace WTF |
| 750 | 750 |
| 751 #endif // Persistent_h | 751 #endif // Persistent_h |
| OLD | NEW |