| 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 15 matching lines...) Expand all  Loading... | 
| 26 enum WeaknessPersistentConfiguration { | 26 enum WeaknessPersistentConfiguration { | 
| 27   NonWeakPersistentConfiguration, | 27   NonWeakPersistentConfiguration, | 
| 28   WeakPersistentConfiguration | 28   WeakPersistentConfiguration | 
| 29 }; | 29 }; | 
| 30 | 30 | 
| 31 enum CrossThreadnessPersistentConfiguration { | 31 enum CrossThreadnessPersistentConfiguration { | 
| 32   SingleThreadPersistentConfiguration, | 32   SingleThreadPersistentConfiguration, | 
| 33   CrossThreadPersistentConfiguration | 33   CrossThreadPersistentConfiguration | 
| 34 }; | 34 }; | 
| 35 | 35 | 
|  | 36 // Auxillary template, probing if |void T::clear()| exists and is accessible. | 
|  | 37 // Used to conditionally clear the contents of a static persistent. | 
|  | 38 template <typename T> | 
|  | 39 class CanClearPersistentReference { | 
|  | 40   typedef char YesType; | 
|  | 41   typedef struct NoType { char padding[8]; } NoType; | 
|  | 42 | 
|  | 43   // Check if class T has public method "void clear()". | 
|  | 44   template <typename V> | 
|  | 45   static YesType checkHasClearMethod( | 
|  | 46       V* p, | 
|  | 47       typename std::enable_if< | 
|  | 48           std::is_same<decltype(p->clear()), void>::value>::type* = nullptr); | 
|  | 49   template <typename V> | 
|  | 50   static NoType checkHasClearMethod(...); | 
|  | 51 | 
|  | 52  public: | 
|  | 53   static const bool value = sizeof(YesType) + sizeof(T) == | 
|  | 54                             sizeof(checkHasClearMethod<T>(nullptr)) + sizeof(T); | 
|  | 55 }; | 
|  | 56 | 
|  | 57 template <typename T, bool = CanClearPersistentReference<T>::value> | 
|  | 58 class ClearStaticPersistentReference { | 
|  | 59  public: | 
|  | 60   static void clear(T*) {} | 
|  | 61 }; | 
|  | 62 | 
|  | 63 template <typename T> | 
|  | 64 class ClearStaticPersistentReference<T, true> { | 
|  | 65  public: | 
|  | 66   static void clear(T* ptr) { ptr->clear(); } | 
|  | 67 }; | 
|  | 68 | 
| 36 template <typename T, | 69 template <typename T, | 
| 37           WeaknessPersistentConfiguration weaknessConfiguration, | 70           WeaknessPersistentConfiguration weaknessConfiguration, | 
| 38           CrossThreadnessPersistentConfiguration crossThreadnessConfiguration> | 71           CrossThreadnessPersistentConfiguration crossThreadnessConfiguration> | 
| 39 class PersistentBase { | 72 class PersistentBase { | 
| 40   USING_FAST_MALLOC(PersistentBase); | 73   USING_FAST_MALLOC(PersistentBase); | 
| 41   IS_PERSISTENT_REFERENCE_TYPE(); | 74   IS_PERSISTENT_REFERENCE_TYPE(); | 
| 42 | 75 | 
| 43  public: | 76  public: | 
| 44   PersistentBase() : m_raw(nullptr) { | 77   PersistentBase() : m_raw(nullptr) { | 
| 45     saveCreationThreadHeap(); | 78     saveCreationThreadHeap(); | 
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 150   // belonging to the current thread and a persistent that must | 183   // belonging to the current thread and a persistent that must | 
| 151   // be cleared when the ThreadState itself is cleared out and | 184   // be cleared when the ThreadState itself is cleared out and | 
| 152   // destructed. | 185   // destructed. | 
| 153   // | 186   // | 
| 154   // Static singletons arrange for this to happen, either to ensure | 187   // Static singletons arrange for this to happen, either to ensure | 
| 155   // clean LSan leak reports or to register a thread-local persistent | 188   // clean LSan leak reports or to register a thread-local persistent | 
| 156   // needing to be cleared out before the thread is terminated. | 189   // needing to be cleared out before the thread is terminated. | 
| 157   PersistentBase* registerAsStaticReference() { | 190   PersistentBase* registerAsStaticReference() { | 
| 158     if (m_persistentNode) { | 191     if (m_persistentNode) { | 
| 159       ASSERT(ThreadState::current()); | 192       ASSERT(ThreadState::current()); | 
| 160       ThreadState::current()->registerStaticPersistentNode(m_persistentNode, | 193       ThreadState::current()->registerStaticPersistentNode( | 
| 161                                                            nullptr); | 194           m_persistentNode, &PersistentBase::clearPersistentNode); | 
| 162       LEAK_SANITIZER_IGNORE_OBJECT(this); | 195       LEAK_SANITIZER_IGNORE_OBJECT(this); | 
| 163     } | 196     } | 
| 164     return this; | 197     return this; | 
| 165   } | 198   } | 
| 166 | 199 | 
| 167  protected: | 200  protected: | 
| 168   NO_SANITIZE_ADDRESS | 201   NO_SANITIZE_ADDRESS | 
| 169   T* atomicGet() { | 202   T* atomicGet() { | 
| 170     return reinterpret_cast<T*>(acquireLoad(reinterpret_cast<void* volatile*>( | 203     return reinterpret_cast<T*>(acquireLoad(reinterpret_cast<void* volatile*>( | 
| 171         const_cast<typename std::remove_const<T>::type**>(&m_raw)))); | 204         const_cast<typename std::remove_const<T>::type**>(&m_raw)))); | 
| (...skipping 12 matching lines...) Expand all  Loading... | 
| 184     } | 217     } | 
| 185     checkPointer(); | 218     checkPointer(); | 
| 186     if (m_raw) { | 219     if (m_raw) { | 
| 187       if (!m_persistentNode) | 220       if (!m_persistentNode) | 
| 188         initialize(); | 221         initialize(); | 
| 189       return; | 222       return; | 
| 190     } | 223     } | 
| 191     uninitialize(); | 224     uninitialize(); | 
| 192   } | 225   } | 
| 193 | 226 | 
|  | 227   // Used when the registered PersistentNode of this object is | 
|  | 228   // released during ThreadState shutdown, clearing the association. | 
|  | 229   static void clearPersistentNode(void* self, | 
|  | 230                                   ThreadState::ReleasePersistentMode mode) { | 
|  | 231     PersistentBase* persistent = reinterpret_cast<PersistentBase*>(self); | 
|  | 232     ClearStaticPersistentReference<T>::clear(persistent->get()); | 
|  | 233     if (mode == ThreadState::ReleasePersistent) | 
|  | 234       persistent->uninitialize(); | 
|  | 235   } | 
|  | 236 | 
| 194   template <typename VisitorDispatcher> | 237   template <typename VisitorDispatcher> | 
| 195   void tracePersistent(VisitorDispatcher visitor) { | 238   void tracePersistent(VisitorDispatcher visitor) { | 
| 196     static_assert(sizeof(T), "T must be fully defined"); | 239     static_assert(sizeof(T), "T must be fully defined"); | 
| 197     static_assert(IsGarbageCollectedType<T>::value, | 240     static_assert(IsGarbageCollectedType<T>::value, | 
| 198                   "T needs to be a garbage collected object"); | 241                   "T needs to be a garbage collected object"); | 
| 199     if (weaknessConfiguration == WeakPersistentConfiguration) { | 242     if (weaknessConfiguration == WeakPersistentConfiguration) { | 
| 200       if (crossThreadnessConfiguration == CrossThreadPersistentConfiguration) | 243       if (crossThreadnessConfiguration == CrossThreadPersistentConfiguration) | 
| 201         visitor->registerWeakCellWithCallback(reinterpret_cast<void**>(this), | 244         visitor->registerWeakCellWithCallback(reinterpret_cast<void**>(this), | 
| 202                                               handleWeakPersistent); | 245                                               handleWeakPersistent); | 
| 203       else | 246       else | 
| (...skipping 389 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 593 | 636 | 
| 594  private: | 637  private: | 
| 595   template <typename VisitorDispatcher> | 638   template <typename VisitorDispatcher> | 
| 596   void tracePersistent(VisitorDispatcher visitor) { | 639   void tracePersistent(VisitorDispatcher visitor) { | 
| 597     static_assert(sizeof(Collection), "Collection must be fully defined"); | 640     static_assert(sizeof(Collection), "Collection must be fully defined"); | 
| 598     visitor->trace(*static_cast<Collection*>(this)); | 641     visitor->trace(*static_cast<Collection*>(this)); | 
| 599   } | 642   } | 
| 600 | 643 | 
| 601   // Used when the registered PersistentNode of this object is | 644   // Used when the registered PersistentNode of this object is | 
| 602   // released during ThreadState shutdown, clearing the association. | 645   // released during ThreadState shutdown, clearing the association. | 
| 603   static void clearPersistentNode(void* self) { | 646   static void clearPersistentNode(void* self, | 
|  | 647                                   ThreadState::ReleasePersistentMode mode) { | 
| 604     PersistentHeapCollectionBase<Collection>* collection = | 648     PersistentHeapCollectionBase<Collection>* collection = | 
| 605         (reinterpret_cast<PersistentHeapCollectionBase<Collection>*>(self)); | 649         reinterpret_cast<PersistentHeapCollectionBase<Collection>*>(self); | 
| 606     collection->uninitialize(); |  | 
| 607     collection->clear(); | 650     collection->clear(); | 
|  | 651     if (mode == ThreadState::ReleasePersistent) | 
|  | 652       collection->uninitialize(); | 
| 608   } | 653   } | 
| 609 | 654 | 
| 610   NO_SANITIZE_ADDRESS | 655   NO_SANITIZE_ADDRESS | 
| 611   void initialize() { | 656   void initialize() { | 
| 612     // FIXME: Derive affinity based on the collection. | 657     // FIXME: Derive affinity based on the collection. | 
| 613     ThreadState* state = ThreadState::current(); | 658     ThreadState* state = ThreadState::current(); | 
| 614     ASSERT(state->checkThread()); | 659     ASSERT(state->checkThread()); | 
| 615     m_persistentNode = state->getPersistentRegion()->allocatePersistentNode( | 660     m_persistentNode = state->getPersistentRegion()->allocatePersistentNode( | 
| 616         this, | 661         this, | 
| 617         TraceMethodDelegate<PersistentHeapCollectionBase<Collection>, | 662         TraceMethodDelegate<PersistentHeapCollectionBase<Collection>, | 
| (...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 820   static blink::CrossThreadPersistent<T> Unwrap( | 865   static blink::CrossThreadPersistent<T> Unwrap( | 
| 821       const blink::CrossThreadWeakPersistent<T>& wrapped) { | 866       const blink::CrossThreadWeakPersistent<T>& wrapped) { | 
| 822     blink::CrossThreadPersistentRegion::LockScope persistentLock( | 867     blink::CrossThreadPersistentRegion::LockScope persistentLock( | 
| 823         blink::ProcessHeap::crossThreadPersistentRegion()); | 868         blink::ProcessHeap::crossThreadPersistentRegion()); | 
| 824     return blink::CrossThreadPersistent<T>(wrapped.get()); | 869     return blink::CrossThreadPersistent<T>(wrapped.get()); | 
| 825   } | 870   } | 
| 826 }; | 871 }; | 
| 827 } | 872 } | 
| 828 | 873 | 
| 829 #endif  // Persistent_h | 874 #endif  // Persistent_h | 
| OLD | NEW | 
|---|