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 #include "platform/heap/PersistentNode.h" | 5 #include "platform/heap/PersistentNode.h" |
6 | 6 |
7 #include "base/debug/alias.h" | 7 #include "base/debug/alias.h" |
8 #include "platform/heap/Handle.h" | 8 #include "platform/heap/Handle.h" |
9 | 9 |
10 namespace blink { | 10 namespace blink { |
(...skipping 24 matching lines...) Expand all Loading... |
35 } | 35 } |
36 } | 36 } |
37 #if DCHECK_IS_ON() | 37 #if DCHECK_IS_ON() |
38 DCHECK_EQ(persistentCount, m_persistentCount); | 38 DCHECK_EQ(persistentCount, m_persistentCount); |
39 #endif | 39 #endif |
40 return persistentCount; | 40 return persistentCount; |
41 } | 41 } |
42 | 42 |
43 void PersistentRegion::ensurePersistentNodeSlots(void* self, | 43 void PersistentRegion::ensurePersistentNodeSlots(void* self, |
44 TraceCallback trace) { | 44 TraceCallback trace) { |
45 ASSERT(!m_freeListHead); | 45 DCHECK(!m_freeListHead); |
46 PersistentNodeSlots* slots = new PersistentNodeSlots; | 46 PersistentNodeSlots* slots = new PersistentNodeSlots; |
47 for (int i = 0; i < PersistentNodeSlots::slotCount; ++i) { | 47 for (int i = 0; i < PersistentNodeSlots::slotCount; ++i) { |
48 PersistentNode* node = &slots->m_slot[i]; | 48 PersistentNode* node = &slots->m_slot[i]; |
49 node->setFreeListNext(m_freeListHead); | 49 node->setFreeListNext(m_freeListHead); |
50 m_freeListHead = node; | 50 m_freeListHead = node; |
51 ASSERT(node->isUnused()); | 51 DCHECK(node->isUnused()); |
52 } | 52 } |
53 slots->m_next = m_slots; | 53 slots->m_next = m_slots; |
54 m_slots = slots; | 54 m_slots = slots; |
55 } | 55 } |
56 | 56 |
57 void PersistentRegion::releasePersistentNode( | 57 void PersistentRegion::releasePersistentNode( |
58 PersistentNode* persistentNode, | 58 PersistentNode* persistentNode, |
59 ThreadState::PersistentClearCallback callback) { | 59 ThreadState::PersistentClearCallback callback) { |
60 ASSERT(!persistentNode->isUnused()); | 60 DCHECK(!persistentNode->isUnused()); |
61 // 'self' is in use, containing the persistent wrapper object. | 61 // 'self' is in use, containing the persistent wrapper object. |
62 void* self = persistentNode->self(); | 62 void* self = persistentNode->self(); |
63 if (callback) { | 63 if (callback) { |
64 (*callback)(self); | 64 (*callback)(self); |
65 ASSERT(persistentNode->isUnused()); | 65 DCHECK(persistentNode->isUnused()); |
66 return; | 66 return; |
67 } | 67 } |
68 Persistent<DummyGCBase>* persistent = | 68 Persistent<DummyGCBase>* persistent = |
69 reinterpret_cast<Persistent<DummyGCBase>*>(self); | 69 reinterpret_cast<Persistent<DummyGCBase>*>(self); |
70 persistent->clear(); | 70 persistent->clear(); |
71 ASSERT(persistentNode->isUnused()); | 71 DCHECK(persistentNode->isUnused()); |
72 } | 72 } |
73 | 73 |
74 // This function traces all PersistentNodes. If we encounter | 74 // This function traces all PersistentNodes. If we encounter |
75 // a PersistentNodeSlot that contains only freed PersistentNodes, | 75 // a PersistentNodeSlot that contains only freed PersistentNodes, |
76 // we delete the PersistentNodeSlot. This function rebuilds the free | 76 // we delete the PersistentNodeSlot. This function rebuilds the free |
77 // list of PersistentNodes. | 77 // list of PersistentNodes. |
78 void PersistentRegion::tracePersistentNodes(Visitor* visitor, | 78 void PersistentRegion::tracePersistentNodes(Visitor* visitor, |
79 ShouldTraceCallback shouldTrace) { | 79 ShouldTraceCallback shouldTrace) { |
80 size_t debugMarkedObjectSize = ProcessHeap::totalMarkedObjectSize(); | 80 size_t debugMarkedObjectSize = ProcessHeap::totalMarkedObjectSize(); |
81 base::debug::Alias(&debugMarkedObjectSize); | 81 base::debug::Alias(&debugMarkedObjectSize); |
(...skipping 22 matching lines...) Expand all Loading... |
104 debugMarkedObjectSize = ProcessHeap::totalMarkedObjectSize(); | 104 debugMarkedObjectSize = ProcessHeap::totalMarkedObjectSize(); |
105 } | 105 } |
106 } | 106 } |
107 if (freeCount == PersistentNodeSlots::slotCount) { | 107 if (freeCount == PersistentNodeSlots::slotCount) { |
108 PersistentNodeSlots* deadSlots = slots; | 108 PersistentNodeSlots* deadSlots = slots; |
109 *prevNext = slots->m_next; | 109 *prevNext = slots->m_next; |
110 slots = slots->m_next; | 110 slots = slots->m_next; |
111 delete deadSlots; | 111 delete deadSlots; |
112 } else { | 112 } else { |
113 if (freeListLast) { | 113 if (freeListLast) { |
114 ASSERT(freeListNext); | 114 DCHECK(freeListNext); |
115 ASSERT(!freeListLast->freeListNext()); | 115 DCHECK(!freeListLast->freeListNext()); |
116 freeListLast->setFreeListNext(m_freeListHead); | 116 freeListLast->setFreeListNext(m_freeListHead); |
117 m_freeListHead = freeListNext; | 117 m_freeListHead = freeListNext; |
118 } | 118 } |
119 prevNext = &slots->m_next; | 119 prevNext = &slots->m_next; |
120 slots = slots->m_next; | 120 slots = slots->m_next; |
121 } | 121 } |
122 } | 122 } |
123 #if DCHECK_IS_ON() | 123 #if DCHECK_IS_ON() |
124 DCHECK_EQ(persistentCount, m_persistentCount); | 124 DCHECK_EQ(persistentCount, m_persistentCount); |
125 #endif | 125 #endif |
(...skipping 26 matching lines...) Expand all Loading... |
152 while (slots) { | 152 while (slots) { |
153 for (int i = 0; i < PersistentNodeSlots::slotCount; ++i) { | 153 for (int i = 0; i < PersistentNodeSlots::slotCount; ++i) { |
154 if (slots->m_slot[i].isUnused()) | 154 if (slots->m_slot[i].isUnused()) |
155 continue; | 155 continue; |
156 | 156 |
157 // 'self' is in use, containing the cross-thread persistent wrapper | 157 // 'self' is in use, containing the cross-thread persistent wrapper |
158 // object. | 158 // object. |
159 CrossThreadPersistent<DummyGCBase>* persistent = | 159 CrossThreadPersistent<DummyGCBase>* persistent = |
160 reinterpret_cast<CrossThreadPersistent<DummyGCBase>*>( | 160 reinterpret_cast<CrossThreadPersistent<DummyGCBase>*>( |
161 slots->m_slot[i].self()); | 161 slots->m_slot[i].self()); |
162 ASSERT(persistent); | 162 DCHECK(persistent); |
163 void* rawObject = persistent->atomicGet(); | 163 void* rawObject = persistent->atomicGet(); |
164 if (!rawObject) | 164 if (!rawObject) |
165 continue; | 165 continue; |
166 BasePage* page = pageFromObject(rawObject); | 166 BasePage* page = pageFromObject(rawObject); |
167 ASSERT(page); | 167 DCHECK(page); |
168 // The main thread will upon detach just mark its heap pages as orphaned, | 168 // The main thread will upon detach just mark its heap pages as orphaned, |
169 // but not invalidate its CrossThreadPersistent<>s. | 169 // but not invalidate its CrossThreadPersistent<>s. |
170 if (page->orphaned()) | 170 if (page->orphaned()) |
171 continue; | 171 continue; |
172 if (page->arena()->getThreadState() == threadState) { | 172 if (page->arena()->getThreadState() == threadState) { |
173 persistent->clear(); | 173 persistent->clear(); |
174 ASSERT(slots->m_slot[i].isUnused()); | 174 DCHECK(slots->m_slot[i].isUnused()); |
175 } | 175 } |
176 } | 176 } |
177 slots = slots->m_next; | 177 slots = slots->m_next; |
178 } | 178 } |
179 } | 179 } |
180 | 180 |
181 #if defined(ADDRESS_SANITIZER) | 181 #if defined(ADDRESS_SANITIZER) |
182 void CrossThreadPersistentRegion::unpoisonCrossThreadPersistents() { | 182 void CrossThreadPersistentRegion::unpoisonCrossThreadPersistents() { |
183 MutexLocker lock(m_mutex); | 183 MutexLocker lock(m_mutex); |
184 int persistentCount = 0; | 184 int persistentCount = 0; |
185 for (PersistentNodeSlots* slots = m_persistentRegion->m_slots; slots; | 185 for (PersistentNodeSlots* slots = m_persistentRegion->m_slots; slots; |
186 slots = slots->m_next) { | 186 slots = slots->m_next) { |
187 for (int i = 0; i < PersistentNodeSlots::slotCount; ++i) { | 187 for (int i = 0; i < PersistentNodeSlots::slotCount; ++i) { |
188 const PersistentNode& node = slots->m_slot[i]; | 188 const PersistentNode& node = slots->m_slot[i]; |
189 if (!node.isUnused()) { | 189 if (!node.isUnused()) { |
190 ASAN_UNPOISON_MEMORY_REGION(node.self(), | 190 ASAN_UNPOISON_MEMORY_REGION(node.self(), |
191 sizeof(CrossThreadPersistent<void*>)); | 191 sizeof(CrossThreadPersistent<void*>)); |
192 ++persistentCount; | 192 ++persistentCount; |
193 } | 193 } |
194 } | 194 } |
195 } | 195 } |
196 #if DCHECK_IS_ON() | 196 #if DCHECK_IS_ON() |
197 DCHECK_EQ(persistentCount, m_persistentRegion->m_persistentCount); | 197 DCHECK_EQ(persistentCount, m_persistentRegion->m_persistentCount); |
198 #endif | 198 #endif |
199 } | 199 } |
200 #endif | 200 #endif |
201 | 201 |
202 } // namespace blink | 202 } // namespace blink |
OLD | NEW |