| 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/Heap.h" | 8 #include "platform/heap/Heap.h" |
| 9 #include "platform/heap/Member.h" | 9 #include "platform/heap/Member.h" |
| 10 #include "platform/heap/PersistentNode.h" | 10 #include "platform/heap/PersistentNode.h" |
| (...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 159 // Register the persistent node as a 'static reference', | 159 // Register the persistent node as a 'static reference', |
| 160 // belonging to the current thread and a persistent that must | 160 // belonging to the current thread and a persistent that must |
| 161 // be cleared when the ThreadState itself is cleared out and | 161 // be cleared when the ThreadState itself is cleared out and |
| 162 // destructed. | 162 // destructed. |
| 163 // | 163 // |
| 164 // Static singletons arrange for this to happen, either to ensure | 164 // Static singletons arrange for this to happen, either to ensure |
| 165 // clean LSan leak reports or to register a thread-local persistent | 165 // clean LSan leak reports or to register a thread-local persistent |
| 166 // needing to be cleared out before the thread is terminated. | 166 // needing to be cleared out before the thread is terminated. |
| 167 PersistentBase* RegisterAsStaticReference() { | 167 PersistentBase* RegisterAsStaticReference() { |
| 168 if (persistent_node_) { | 168 if (persistent_node_) { |
| 169 ASSERT(ThreadState::Current()); | 169 DCHECK(ThreadState::Current()); |
| 170 ThreadState::Current()->RegisterStaticPersistentNode(persistent_node_, | 170 ThreadState::Current()->RegisterStaticPersistentNode(persistent_node_, |
| 171 nullptr); | 171 nullptr); |
| 172 LEAK_SANITIZER_IGNORE_OBJECT(this); | 172 LEAK_SANITIZER_IGNORE_OBJECT(this); |
| 173 } | 173 } |
| 174 return this; | 174 return this; |
| 175 } | 175 } |
| 176 | 176 |
| 177 protected: | 177 protected: |
| 178 NO_SANITIZE_ADDRESS | 178 NO_SANITIZE_ADDRESS |
| 179 T* AtomicGet() { | 179 T* AtomicGet() { |
| (...skipping 27 matching lines...) Expand all Loading... |
| 207 "T needs to be a garbage collected object"); | 207 "T needs to be a garbage collected object"); |
| 208 if (weaknessConfiguration == kWeakPersistentConfiguration) { | 208 if (weaknessConfiguration == kWeakPersistentConfiguration) { |
| 209 visitor->RegisterWeakCallback(this, HandleWeakPersistent); | 209 visitor->RegisterWeakCallback(this, HandleWeakPersistent); |
| 210 } else { | 210 } else { |
| 211 visitor->Mark(raw_); | 211 visitor->Mark(raw_); |
| 212 } | 212 } |
| 213 } | 213 } |
| 214 | 214 |
| 215 NO_SANITIZE_ADDRESS | 215 NO_SANITIZE_ADDRESS |
| 216 void Initialize() { | 216 void Initialize() { |
| 217 ASSERT(!persistent_node_); | 217 DCHECK(!persistent_node_); |
| 218 if (!raw_ || IsHashTableDeletedValue()) | 218 if (!raw_ || IsHashTableDeletedValue()) |
| 219 return; | 219 return; |
| 220 | 220 |
| 221 TraceCallback trace_callback = | 221 TraceCallback trace_callback = |
| 222 TraceMethodDelegate<PersistentBase, | 222 TraceMethodDelegate<PersistentBase, |
| 223 &PersistentBase::TracePersistent>::Trampoline; | 223 &PersistentBase::TracePersistent>::Trampoline; |
| 224 if (crossThreadnessConfiguration == kCrossThreadPersistentConfiguration) { | 224 if (crossThreadnessConfiguration == kCrossThreadPersistentConfiguration) { |
| 225 ProcessHeap::GetCrossThreadPersistentRegion().AllocatePersistentNode( | 225 ProcessHeap::GetCrossThreadPersistentRegion().AllocatePersistentNode( |
| 226 persistent_node_, this, trace_callback); | 226 persistent_node_, this, trace_callback); |
| 227 return; | 227 return; |
| 228 } | 228 } |
| 229 ThreadState* state = | 229 ThreadState* state = |
| 230 ThreadStateFor<ThreadingTrait<T>::kAffinity>::GetState(); | 230 ThreadStateFor<ThreadingTrait<T>::kAffinity>::GetState(); |
| 231 ASSERT(state->CheckThread()); | 231 DCHECK(state->CheckThread()); |
| 232 persistent_node_ = state->GetPersistentRegion()->AllocatePersistentNode( | 232 persistent_node_ = state->GetPersistentRegion()->AllocatePersistentNode( |
| 233 this, trace_callback); | 233 this, trace_callback); |
| 234 #if DCHECK_IS_ON() | 234 #if DCHECK_IS_ON() |
| 235 state_ = state; | 235 state_ = state; |
| 236 #endif | 236 #endif |
| 237 } | 237 } |
| 238 | 238 |
| 239 void Uninitialize() { | 239 void Uninitialize() { |
| 240 if (crossThreadnessConfiguration == kCrossThreadPersistentConfiguration) { | 240 if (crossThreadnessConfiguration == kCrossThreadPersistentConfiguration) { |
| 241 if (AcquireLoad(reinterpret_cast<void* volatile*>(&persistent_node_))) | 241 if (AcquireLoad(reinterpret_cast<void* volatile*>(&persistent_node_))) |
| 242 ProcessHeap::GetCrossThreadPersistentRegion().FreePersistentNode( | 242 ProcessHeap::GetCrossThreadPersistentRegion().FreePersistentNode( |
| 243 persistent_node_); | 243 persistent_node_); |
| 244 return; | 244 return; |
| 245 } | 245 } |
| 246 | 246 |
| 247 if (!persistent_node_) | 247 if (!persistent_node_) |
| 248 return; | 248 return; |
| 249 ThreadState* state = | 249 ThreadState* state = |
| 250 ThreadStateFor<ThreadingTrait<T>::kAffinity>::GetState(); | 250 ThreadStateFor<ThreadingTrait<T>::kAffinity>::GetState(); |
| 251 ASSERT(state->CheckThread()); | 251 DCHECK(state->CheckThread()); |
| 252 // Persistent handle must be created and destructed in the same thread. | 252 // Persistent handle must be created and destructed in the same thread. |
| 253 ASSERT(state_ == state); | 253 #if DCHECK_IS_ON() |
| 254 DCHECK_EQ(state_, state); |
| 255 #endif |
| 254 state->FreePersistentNode(persistent_node_); | 256 state->FreePersistentNode(persistent_node_); |
| 255 persistent_node_ = nullptr; | 257 persistent_node_ = nullptr; |
| 256 } | 258 } |
| 257 | 259 |
| 258 void CheckPointer() const { | 260 void CheckPointer() const { |
| 259 #if DCHECK_IS_ON() | 261 #if DCHECK_IS_ON() |
| 260 if (!raw_ || IsHashTableDeletedValue()) | 262 if (!raw_ || IsHashTableDeletedValue()) |
| 261 return; | 263 return; |
| 262 | 264 |
| 263 if (crossThreadnessConfiguration != kCrossThreadPersistentConfiguration) { | 265 if (crossThreadnessConfiguration != kCrossThreadPersistentConfiguration) { |
| (...skipping 296 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 560 PersistentHeapCollectionBase(const OtherCollection& other) | 562 PersistentHeapCollectionBase(const OtherCollection& other) |
| 561 : Collection(other) { | 563 : Collection(other) { |
| 562 Initialize(); | 564 Initialize(); |
| 563 } | 565 } |
| 564 | 566 |
| 565 ~PersistentHeapCollectionBase() { Uninitialize(); } | 567 ~PersistentHeapCollectionBase() { Uninitialize(); } |
| 566 | 568 |
| 567 // See PersistentBase::registerAsStaticReference() comment. | 569 // See PersistentBase::registerAsStaticReference() comment. |
| 568 PersistentHeapCollectionBase* RegisterAsStaticReference() { | 570 PersistentHeapCollectionBase* RegisterAsStaticReference() { |
| 569 if (persistent_node_) { | 571 if (persistent_node_) { |
| 570 ASSERT(ThreadState::Current()); | 572 DCHECK(ThreadState::Current()); |
| 571 ThreadState::Current()->RegisterStaticPersistentNode( | 573 ThreadState::Current()->RegisterStaticPersistentNode( |
| 572 persistent_node_, | 574 persistent_node_, |
| 573 &PersistentHeapCollectionBase<Collection>::ClearPersistentNode); | 575 &PersistentHeapCollectionBase<Collection>::ClearPersistentNode); |
| 574 LEAK_SANITIZER_IGNORE_OBJECT(this); | 576 LEAK_SANITIZER_IGNORE_OBJECT(this); |
| 575 } | 577 } |
| 576 return this; | 578 return this; |
| 577 } | 579 } |
| 578 | 580 |
| 579 private: | 581 private: |
| 580 template <typename VisitorDispatcher> | 582 template <typename VisitorDispatcher> |
| 581 void TracePersistent(VisitorDispatcher visitor) { | 583 void TracePersistent(VisitorDispatcher visitor) { |
| 582 static_assert(sizeof(Collection), "Collection must be fully defined"); | 584 static_assert(sizeof(Collection), "Collection must be fully defined"); |
| 583 visitor->Trace(*static_cast<Collection*>(this)); | 585 visitor->Trace(*static_cast<Collection*>(this)); |
| 584 } | 586 } |
| 585 | 587 |
| 586 // Used when the registered PersistentNode of this object is | 588 // Used when the registered PersistentNode of this object is |
| 587 // released during ThreadState shutdown, clearing the association. | 589 // released during ThreadState shutdown, clearing the association. |
| 588 static void ClearPersistentNode(void* self) { | 590 static void ClearPersistentNode(void* self) { |
| 589 PersistentHeapCollectionBase<Collection>* collection = | 591 PersistentHeapCollectionBase<Collection>* collection = |
| 590 (reinterpret_cast<PersistentHeapCollectionBase<Collection>*>(self)); | 592 (reinterpret_cast<PersistentHeapCollectionBase<Collection>*>(self)); |
| 591 collection->Uninitialize(); | 593 collection->Uninitialize(); |
| 592 collection->Clear(); | 594 collection->Clear(); |
| 593 } | 595 } |
| 594 | 596 |
| 595 NO_SANITIZE_ADDRESS | 597 NO_SANITIZE_ADDRESS |
| 596 void Initialize() { | 598 void Initialize() { |
| 597 // FIXME: Derive affinity based on the collection. | 599 // FIXME: Derive affinity based on the collection. |
| 598 ThreadState* state = ThreadState::Current(); | 600 ThreadState* state = ThreadState::Current(); |
| 599 ASSERT(state->CheckThread()); | 601 DCHECK(state->CheckThread()); |
| 600 persistent_node_ = state->GetPersistentRegion()->AllocatePersistentNode( | 602 persistent_node_ = state->GetPersistentRegion()->AllocatePersistentNode( |
| 601 this, | 603 this, |
| 602 TraceMethodDelegate<PersistentHeapCollectionBase<Collection>, | 604 TraceMethodDelegate<PersistentHeapCollectionBase<Collection>, |
| 603 &PersistentHeapCollectionBase< | 605 &PersistentHeapCollectionBase< |
| 604 Collection>::TracePersistent>::Trampoline); | 606 Collection>::TracePersistent>::Trampoline); |
| 605 #if DCHECK_IS_ON() | 607 #if DCHECK_IS_ON() |
| 606 state_ = state; | 608 state_ = state; |
| 607 #endif | 609 #endif |
| 608 } | 610 } |
| 609 | 611 |
| 610 void Uninitialize() { | 612 void Uninitialize() { |
| 611 if (!persistent_node_) | 613 if (!persistent_node_) |
| 612 return; | 614 return; |
| 613 ThreadState* state = ThreadState::Current(); | 615 ThreadState* state = ThreadState::Current(); |
| 614 ASSERT(state->CheckThread()); | 616 DCHECK(state->CheckThread()); |
| 615 // Persistent handle must be created and destructed in the same thread. | 617 // Persistent handle must be created and destructed in the same thread. |
| 616 ASSERT(state_ == state); | 618 #if DCHECK_IS_ON() |
| 619 DCHECK_EQ(state_, state); |
| 620 #endif |
| 617 state->FreePersistentNode(persistent_node_); | 621 state->FreePersistentNode(persistent_node_); |
| 618 persistent_node_ = nullptr; | 622 persistent_node_ = nullptr; |
| 619 } | 623 } |
| 620 | 624 |
| 621 PersistentNode* persistent_node_; | 625 PersistentNode* persistent_node_; |
| 622 #if DCHECK_IS_ON() | 626 #if DCHECK_IS_ON() |
| 623 ThreadState* state_; | 627 ThreadState* state_; |
| 624 #endif | 628 #endif |
| 625 }; | 629 }; |
| 626 | 630 |
| (...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 805 static blink::CrossThreadPersistent<T> Unwrap( | 809 static blink::CrossThreadPersistent<T> Unwrap( |
| 806 const blink::CrossThreadWeakPersistent<T>& wrapped) { | 810 const blink::CrossThreadWeakPersistent<T>& wrapped) { |
| 807 blink::CrossThreadPersistentRegion::LockScope persistentLock( | 811 blink::CrossThreadPersistentRegion::LockScope persistentLock( |
| 808 blink::ProcessHeap::GetCrossThreadPersistentRegion()); | 812 blink::ProcessHeap::GetCrossThreadPersistentRegion()); |
| 809 return blink::CrossThreadPersistent<T>(wrapped.Get()); | 813 return blink::CrossThreadPersistent<T>(wrapped.Get()); |
| 810 } | 814 } |
| 811 }; | 815 }; |
| 812 } | 816 } |
| 813 | 817 |
| 814 #endif // Persistent_h | 818 #endif // Persistent_h |
| OLD | NEW |