Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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 PersistentNode_h | 5 #ifndef PersistentNode_h |
| 6 #define PersistentNode_h | 6 #define PersistentNode_h |
| 7 | 7 |
| 8 #include "platform/PlatformExport.h" | 8 #include "platform/PlatformExport.h" |
| 9 #include "platform/heap/ThreadState.h" | 9 #include "platform/heap/ThreadState.h" |
| 10 #include "wtf/Assertions.h" | 10 #include "wtf/Assertions.h" |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 37 | 37 |
| 38 // Ideally the trace method should be virtual and automatically dispatch | 38 // Ideally the trace method should be virtual and automatically dispatch |
| 39 // to the most specific implementation. However having a virtual method | 39 // to the most specific implementation. However having a virtual method |
| 40 // on PersistentNode leads to too eager template instantiation with MSVC | 40 // on PersistentNode leads to too eager template instantiation with MSVC |
| 41 // which leads to include cycles. | 41 // which leads to include cycles. |
| 42 // Instead we call the constructor with a TraceCallback which knows the | 42 // Instead we call the constructor with a TraceCallback which knows the |
| 43 // type of the most specific child and calls trace directly. See | 43 // type of the most specific child and calls trace directly. See |
| 44 // TraceMethodDelegate in Visitor.h for how this is done. | 44 // TraceMethodDelegate in Visitor.h for how this is done. |
| 45 void tracePersistentNode(Visitor* visitor) | 45 void tracePersistentNode(Visitor* visitor) |
| 46 { | 46 { |
| 47 ASSERT(isValid()); | |
| 47 ASSERT(!isUnused()); | 48 ASSERT(!isUnused()); |
| 48 ASSERT(m_trace); | 49 ASSERT(m_trace); |
| 49 m_trace(visitor, m_self); | 50 m_trace(visitor, m_self); |
| 50 } | 51 } |
| 51 | 52 |
| 52 void initialize(void* self, TraceCallback trace) | 53 void initialize(void* self, TraceCallback trace) |
| 53 { | 54 { |
| 54 ASSERT(isUnused()); | 55 ASSERT(isUnused()); |
| 55 m_self = self; | 56 m_self = self; |
| 56 m_trace = trace; | 57 m_trace = trace; |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 70 PersistentNode* node = reinterpret_cast<PersistentNode*>(m_self); | 71 PersistentNode* node = reinterpret_cast<PersistentNode*>(m_self); |
| 71 ASSERT(!node || node->isUnused()); | 72 ASSERT(!node || node->isUnused()); |
| 72 return node; | 73 return node; |
| 73 } | 74 } |
| 74 | 75 |
| 75 bool isUnused() const | 76 bool isUnused() const |
| 76 { | 77 { |
| 77 return !m_trace; | 78 return !m_trace; |
| 78 } | 79 } |
| 79 | 80 |
| 81 bool isValid() const | |
| 82 { | |
| 83 return !(reinterpret_cast<uintptr_t>(m_self) & 0x1); | |
| 84 } | |
| 85 | |
| 86 void invalidate() | |
| 87 { | |
| 88 m_self = reinterpret_cast<Address>(reinterpret_cast<uintptr_t>(m_self) | 0x1); | |
|
haraken
2015/08/03 00:45:25
Or I'd prefer just clearing the pointer. The seman
sof
2015/08/03 08:30:04
Can do that instead, that is, clear out the underl
| |
| 89 } | |
| 90 | |
| 91 void* self() const | |
| 92 { | |
| 93 return m_self; | |
| 94 } | |
| 95 | |
| 80 private: | 96 private: |
| 81 // If this PersistentNode is in use: | 97 // If this PersistentNode is in use: |
| 82 // - m_self points to the corresponding Persistent handle. | 98 // - m_self points to the corresponding Persistent handle. |
| 83 // - m_trace points to the trace method. | 99 // - m_trace points to the trace method. |
| 84 // If this PersistentNode is freed: | 100 // If this PersistentNode is freed: |
| 85 // - m_self points to the next freed PersistentNode. | 101 // - m_self points to the next freed PersistentNode. |
| 86 // - m_trace is nullptr. | 102 // - m_trace is nullptr. |
| 87 void* m_self; | 103 void* m_self; |
| 88 TraceCallback m_trace; | 104 TraceCallback m_trace; |
| 89 }; | 105 }; |
| 90 | 106 |
| 91 struct PersistentNodeSlots final { | 107 struct PersistentNodeSlots final { |
| 92 private: | 108 private: |
| 93 static const int slotCount = 256; | 109 static const int slotCount = 256; |
| 94 PersistentNodeSlots* m_next; | 110 PersistentNodeSlots* m_next; |
| 95 PersistentNode m_slot[slotCount]; | 111 PersistentNode m_slot[slotCount]; |
| 96 friend class PersistentRegion; | 112 friend class PersistentRegion; |
| 113 friend class CrossThreadPersistentRegion; | |
| 97 }; | 114 }; |
| 98 | 115 |
| 99 // PersistentRegion provides a region of PersistentNodes. PersistentRegion | 116 // PersistentRegion provides a region of PersistentNodes. PersistentRegion |
| 100 // holds a linked list of PersistentNodeSlots, each of which stores | 117 // holds a linked list of PersistentNodeSlots, each of which stores |
| 101 // a predefined number of PersistentNodes. You can call allocatePersistentNode/ | 118 // a predefined number of PersistentNodes. You can call allocatePersistentNode/ |
| 102 // freePersistentNode to allocate/free a PersistentNode on the region. | 119 // freePersistentNode to allocate/free a PersistentNode on the region. |
| 103 class PLATFORM_EXPORT PersistentRegion final { | 120 class PLATFORM_EXPORT PersistentRegion final { |
| 104 public: | 121 public: |
| 105 PersistentRegion() | 122 PersistentRegion() |
| 106 : m_freeListHead(nullptr) | 123 : m_freeListHead(nullptr) |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 132 persistentNode->setFreeListNext(m_freeListHead); | 149 persistentNode->setFreeListNext(m_freeListHead); |
| 133 m_freeListHead = persistentNode; | 150 m_freeListHead = persistentNode; |
| 134 #if ENABLE(ASSERT) | 151 #if ENABLE(ASSERT) |
| 135 --m_persistentCount; | 152 --m_persistentCount; |
| 136 #endif | 153 #endif |
| 137 } | 154 } |
| 138 void tracePersistentNodes(Visitor*); | 155 void tracePersistentNodes(Visitor*); |
| 139 int numberOfPersistents(); | 156 int numberOfPersistents(); |
| 140 | 157 |
| 141 private: | 158 private: |
| 159 friend CrossThreadPersistentRegion; | |
| 160 | |
| 142 void ensurePersistentNodeSlots(void*, TraceCallback); | 161 void ensurePersistentNodeSlots(void*, TraceCallback); |
| 143 | 162 |
| 144 PersistentNode* m_freeListHead; | 163 PersistentNode* m_freeListHead; |
| 145 PersistentNodeSlots* m_slots; | 164 PersistentNodeSlots* m_slots; |
| 146 #if ENABLE(ASSERT) | 165 #if ENABLE(ASSERT) |
| 147 int m_persistentCount; | 166 int m_persistentCount; |
| 148 #endif | 167 #endif |
| 149 }; | 168 }; |
| 150 | 169 |
| 151 class CrossThreadPersistentRegion final { | 170 class CrossThreadPersistentRegion final { |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 163 MutexLocker lock(m_mutex); | 182 MutexLocker lock(m_mutex); |
| 164 m_persistentRegion->freePersistentNode(persistentNode); | 183 m_persistentRegion->freePersistentNode(persistentNode); |
| 165 } | 184 } |
| 166 | 185 |
| 167 void tracePersistentNodes(Visitor* visitor) | 186 void tracePersistentNodes(Visitor* visitor) |
| 168 { | 187 { |
| 169 MutexLocker lock(m_mutex); | 188 MutexLocker lock(m_mutex); |
| 170 m_persistentRegion->tracePersistentNodes(visitor); | 189 m_persistentRegion->tracePersistentNodes(visitor); |
| 171 } | 190 } |
| 172 | 191 |
| 192 void prepareForThreadStateTermination(ThreadState*); | |
| 193 | |
| 173 private: | 194 private: |
| 174 // We don't make CrossThreadPersistentRegion inherit from PersistentRegion | 195 // We don't make CrossThreadPersistentRegion inherit from PersistentRegion |
| 175 // because we don't want to virtualize performance-sensitive methods | 196 // because we don't want to virtualize performance-sensitive methods |
| 176 // such as PersistentRegion::allocate/freePersistentNode. | 197 // such as PersistentRegion::allocate/freePersistentNode. |
| 177 OwnPtr<PersistentRegion> m_persistentRegion; | 198 OwnPtr<PersistentRegion> m_persistentRegion; |
| 178 Mutex m_mutex; | 199 Mutex m_mutex; |
| 179 }; | 200 }; |
| 180 | 201 |
| 181 } // namespace blink | 202 } // namespace blink |
| 182 | 203 |
| 183 #endif | 204 #endif |
| OLD | NEW |