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(persistent_count, persistent_count_); | 38 DCHECK_EQ(persistent_count, persistent_count_); |
39 #endif | 39 #endif |
40 return persistent_count; | 40 return persistent_count; |
41 } | 41 } |
42 | 42 |
43 void PersistentRegion::EnsurePersistentNodeSlots(void* self, | 43 void PersistentRegion::EnsurePersistentNodeSlots(void* self, |
44 TraceCallback trace) { | 44 TraceCallback trace) { |
45 ASSERT(!free_list_head_); | 45 DCHECK(!free_list_head_); |
46 PersistentNodeSlots* slots = new PersistentNodeSlots; | 46 PersistentNodeSlots* slots = new PersistentNodeSlots; |
47 for (int i = 0; i < PersistentNodeSlots::kSlotCount; ++i) { | 47 for (int i = 0; i < PersistentNodeSlots::kSlotCount; ++i) { |
48 PersistentNode* node = &slots->slot_[i]; | 48 PersistentNode* node = &slots->slot_[i]; |
49 node->SetFreeListNext(free_list_head_); | 49 node->SetFreeListNext(free_list_head_); |
50 free_list_head_ = node; | 50 free_list_head_ = node; |
51 ASSERT(node->IsUnused()); | 51 DCHECK(node->IsUnused()); |
52 } | 52 } |
53 slots->next_ = slots_; | 53 slots->next_ = slots_; |
54 slots_ = slots; | 54 slots_ = slots; |
55 } | 55 } |
56 | 56 |
57 void PersistentRegion::ReleasePersistentNode( | 57 void PersistentRegion::ReleasePersistentNode( |
58 PersistentNode* persistent_node, | 58 PersistentNode* persistent_node, |
59 ThreadState::PersistentClearCallback callback) { | 59 ThreadState::PersistentClearCallback callback) { |
60 ASSERT(!persistent_node->IsUnused()); | 60 DCHECK(!persistent_node->IsUnused()); |
61 // 'self' is in use, containing the persistent wrapper object. | 61 // 'self' is in use, containing the persistent wrapper object. |
62 void* self = persistent_node->Self(); | 62 void* self = persistent_node->Self(); |
63 if (callback) { | 63 if (callback) { |
64 (*callback)(self); | 64 (*callback)(self); |
65 ASSERT(persistent_node->IsUnused()); | 65 DCHECK(persistent_node->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(persistent_node->IsUnused()); | 71 DCHECK(persistent_node->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 should_trace) { | 79 ShouldTraceCallback should_trace) { |
80 size_t debug_marked_object_size = ProcessHeap::TotalMarkedObjectSize(); | 80 size_t debug_marked_object_size = ProcessHeap::TotalMarkedObjectSize(); |
81 base::debug::Alias(&debug_marked_object_size); | 81 base::debug::Alias(&debug_marked_object_size); |
(...skipping 22 matching lines...) Expand all Loading... |
104 debug_marked_object_size = ProcessHeap::TotalMarkedObjectSize(); | 104 debug_marked_object_size = ProcessHeap::TotalMarkedObjectSize(); |
105 } | 105 } |
106 } | 106 } |
107 if (free_count == PersistentNodeSlots::kSlotCount) { | 107 if (free_count == PersistentNodeSlots::kSlotCount) { |
108 PersistentNodeSlots* dead_slots = slots; | 108 PersistentNodeSlots* dead_slots = slots; |
109 *prev_next = slots->next_; | 109 *prev_next = slots->next_; |
110 slots = slots->next_; | 110 slots = slots->next_; |
111 delete dead_slots; | 111 delete dead_slots; |
112 } else { | 112 } else { |
113 if (free_list_last) { | 113 if (free_list_last) { |
114 ASSERT(free_list_next); | 114 DCHECK(free_list_next); |
115 ASSERT(!free_list_last->FreeListNext()); | 115 DCHECK(!free_list_last->FreeListNext()); |
116 free_list_last->SetFreeListNext(free_list_head_); | 116 free_list_last->SetFreeListNext(free_list_head_); |
117 free_list_head_ = free_list_next; | 117 free_list_head_ = free_list_next; |
118 } | 118 } |
119 prev_next = &slots->next_; | 119 prev_next = &slots->next_; |
120 slots = slots->next_; | 120 slots = slots->next_; |
121 } | 121 } |
122 } | 122 } |
123 #if DCHECK_IS_ON() | 123 #if DCHECK_IS_ON() |
124 DCHECK_EQ(persistent_count, persistent_count_); | 124 DCHECK_EQ(persistent_count, persistent_count_); |
125 #endif | 125 #endif |
(...skipping 26 matching lines...) Expand all Loading... |
152 while (slots) { | 152 while (slots) { |
153 for (int i = 0; i < PersistentNodeSlots::kSlotCount; ++i) { | 153 for (int i = 0; i < PersistentNodeSlots::kSlotCount; ++i) { |
154 if (slots->slot_[i].IsUnused()) | 154 if (slots->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->slot_[i].Self()); | 161 slots->slot_[i].Self()); |
162 ASSERT(persistent); | 162 DCHECK(persistent); |
163 void* raw_object = persistent->AtomicGet(); | 163 void* raw_object = persistent->AtomicGet(); |
164 if (!raw_object) | 164 if (!raw_object) |
165 continue; | 165 continue; |
166 BasePage* page = PageFromObject(raw_object); | 166 BasePage* page = PageFromObject(raw_object); |
167 ASSERT(page); | 167 DCHECK(page); |
168 if (page->Arena()->GetThreadState() == thread_state) { | 168 if (page->Arena()->GetThreadState() == thread_state) { |
169 persistent->Clear(); | 169 persistent->Clear(); |
170 ASSERT(slots->slot_[i].IsUnused()); | 170 DCHECK(slots->slot_[i].IsUnused()); |
171 } | 171 } |
172 } | 172 } |
173 slots = slots->next_; | 173 slots = slots->next_; |
174 } | 174 } |
175 } | 175 } |
176 | 176 |
177 #if defined(ADDRESS_SANITIZER) | 177 #if defined(ADDRESS_SANITIZER) |
178 void CrossThreadPersistentRegion::UnpoisonCrossThreadPersistents() { | 178 void CrossThreadPersistentRegion::UnpoisonCrossThreadPersistents() { |
179 MutexLocker lock(mutex_); | 179 MutexLocker lock(mutex_); |
180 int persistent_count = 0; | 180 int persistent_count = 0; |
181 for (PersistentNodeSlots* slots = persistent_region_->slots_; slots; | 181 for (PersistentNodeSlots* slots = persistent_region_->slots_; slots; |
182 slots = slots->next_) { | 182 slots = slots->next_) { |
183 for (int i = 0; i < PersistentNodeSlots::kSlotCount; ++i) { | 183 for (int i = 0; i < PersistentNodeSlots::kSlotCount; ++i) { |
184 const PersistentNode& node = slots->slot_[i]; | 184 const PersistentNode& node = slots->slot_[i]; |
185 if (!node.IsUnused()) { | 185 if (!node.IsUnused()) { |
186 ASAN_UNPOISON_MEMORY_REGION(node.Self(), | 186 ASAN_UNPOISON_MEMORY_REGION(node.Self(), |
187 sizeof(CrossThreadPersistent<void*>)); | 187 sizeof(CrossThreadPersistent<void*>)); |
188 ++persistent_count; | 188 ++persistent_count; |
189 } | 189 } |
190 } | 190 } |
191 } | 191 } |
192 #if DCHECK_IS_ON() | 192 #if DCHECK_IS_ON() |
193 DCHECK_EQ(persistent_count, persistent_region_->persistent_count_); | 193 DCHECK_EQ(persistent_count, persistent_region_->persistent_count_); |
194 #endif | 194 #endif |
195 } | 195 } |
196 #endif | 196 #endif |
197 | 197 |
198 } // namespace blink | 198 } // namespace blink |
OLD | NEW |