Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(67)

Side by Side Diff: third_party/WebKit/Source/platform/heap/PersistentNode.cpp

Issue 1919663002: Unify and generalize thread static persistent finalization. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: generalize clearing Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 "platform/heap/Handle.h" 7 #include "platform/heap/Handle.h"
8 8
9 namespace blink { 9 namespace blink {
10 10
11 namespace {
12
13 class DummyGCBase final : public GarbageCollected<DummyGCBase> {
14 public:
15 DEFINE_INLINE_TRACE() { }
16 };
17
18 }
19
11 PersistentRegion::~PersistentRegion() 20 PersistentRegion::~PersistentRegion()
12 { 21 {
13 PersistentNodeSlots* slots = m_slots; 22 PersistentNodeSlots* slots = m_slots;
14 while (slots) { 23 while (slots) {
15 PersistentNodeSlots* deadSlots = slots; 24 PersistentNodeSlots* deadSlots = slots;
16 slots = slots->m_next; 25 slots = slots->m_next;
17 delete deadSlots; 26 delete deadSlots;
18 } 27 }
19 } 28 }
20 29
(...skipping 17 matching lines...) Expand all
38 for (int i = 0; i < PersistentNodeSlots::slotCount; ++i) { 47 for (int i = 0; i < PersistentNodeSlots::slotCount; ++i) {
39 PersistentNode* node = &slots->m_slot[i]; 48 PersistentNode* node = &slots->m_slot[i];
40 node->setFreeListNext(m_freeListHead); 49 node->setFreeListNext(m_freeListHead);
41 m_freeListHead = node; 50 m_freeListHead = node;
42 ASSERT(node->isUnused()); 51 ASSERT(node->isUnused());
43 } 52 }
44 slots->m_next = m_slots; 53 slots->m_next = m_slots;
45 m_slots = slots; 54 m_slots = slots;
46 } 55 }
47 56
57 void PersistentRegion::releasePersistentNode(PersistentNode* persistentNode, Thr eadState::PersistentClearCallback callback)
58 {
59 ASSERT(!persistentNode->isUnused());
60 // 'self' is in use, containing the persistent wrapper object.
61 void* self = persistentNode->self();
62 if (callback) {
63 (*callback)(self);
64 ASSERT(persistentNode->isUnused());
65 return;
66 }
67 Persistent<DummyGCBase>* persistent = reinterpret_cast<Persistent<DummyGCBas e>*>(self);
68 persistent->clear();
69 ASSERT(persistentNode->isUnused());
70 }
71
48 // This function traces all PersistentNodes. If we encounter 72 // This function traces all PersistentNodes. If we encounter
49 // a PersistentNodeSlot that contains only freed PersistentNodes, 73 // a PersistentNodeSlot that contains only freed PersistentNodes,
50 // we delete the PersistentNodeSlot. This function rebuilds the free 74 // we delete the PersistentNodeSlot. This function rebuilds the free
51 // list of PersistentNodes. 75 // list of PersistentNodes.
52 void PersistentRegion::tracePersistentNodes(Visitor* visitor) 76 void PersistentRegion::tracePersistentNodes(Visitor* visitor)
53 { 77 {
54 size_t debugMarkedObjectSize = ProcessHeap::totalMarkedObjectSize(); 78 size_t debugMarkedObjectSize = ProcessHeap::totalMarkedObjectSize();
55 base::debug::Alias(&debugMarkedObjectSize); 79 base::debug::Alias(&debugMarkedObjectSize);
56 80
57 m_freeListHead = nullptr; 81 m_freeListHead = nullptr;
(...skipping 30 matching lines...) Expand all
88 freeListLast->setFreeListNext(m_freeListHead); 112 freeListLast->setFreeListNext(m_freeListHead);
89 m_freeListHead = freeListNext; 113 m_freeListHead = freeListNext;
90 } 114 }
91 prevNext = &slots->m_next; 115 prevNext = &slots->m_next;
92 slots = slots->m_next; 116 slots = slots->m_next;
93 } 117 }
94 } 118 }
95 ASSERT(persistentCount == m_persistentCount); 119 ASSERT(persistentCount == m_persistentCount);
96 } 120 }
97 121
98 namespace {
99 class GCObject final : public GarbageCollected<GCObject> {
100 public:
101 DEFINE_INLINE_TRACE() { }
102 };
103 }
104
105 void CrossThreadPersistentRegion::prepareForThreadStateTermination(ThreadState* threadState) 122 void CrossThreadPersistentRegion::prepareForThreadStateTermination(ThreadState* threadState)
106 { 123 {
107 // For heaps belonging to a thread that's detaching, any cross-thread persis tents 124 // For heaps belonging to a thread that's detaching, any cross-thread persis tents
108 // pointing into them needs to be disabled. Do that by clearing out the unde rlying 125 // pointing into them needs to be disabled. Do that by clearing out the unde rlying
109 // heap reference. 126 // heap reference.
110 MutexLocker lock(m_mutex); 127 MutexLocker lock(m_mutex);
111 128
112 // TODO(sof): consider ways of reducing overhead. (e.g., tracking number of active 129 // TODO(sof): consider ways of reducing overhead. (e.g., tracking number of active
113 // CrossThreadPersistent<>s pointing into the heaps of each ThreadState and use that 130 // CrossThreadPersistent<>s pointing into the heaps of each ThreadState and use that
114 // count to bail out early.) 131 // count to bail out early.)
115 PersistentNodeSlots* slots = m_persistentRegion->m_slots; 132 PersistentNodeSlots* slots = m_persistentRegion->m_slots;
116 while (slots) { 133 while (slots) {
117 for (int i = 0; i < PersistentNodeSlots::slotCount; ++i) { 134 for (int i = 0; i < PersistentNodeSlots::slotCount; ++i) {
118 if (slots->m_slot[i].isUnused()) 135 if (slots->m_slot[i].isUnused())
119 continue; 136 continue;
120 137
121 // 'self' is in use, containing the cross-thread persistent wrapper object. 138 // 'self' is in use, containing the cross-thread persistent wrapper object.
122 CrossThreadPersistent<GCObject>* persistent = reinterpret_cast<Cross ThreadPersistent<GCObject>*>(slots->m_slot[i].self()); 139 CrossThreadPersistent<DummyGCBase>* persistent = reinterpret_cast<Cr ossThreadPersistent<DummyGCBase>*>(slots->m_slot[i].self());
123 ASSERT(persistent); 140 ASSERT(persistent);
124 void* rawObject = persistent->atomicGet(); 141 void* rawObject = persistent->atomicGet();
125 if (!rawObject) 142 if (!rawObject)
126 continue; 143 continue;
127 BasePage* page = pageFromObject(rawObject); 144 BasePage* page = pageFromObject(rawObject);
128 ASSERT(page); 145 ASSERT(page);
129 // The main thread will upon detach just mark its heap pages as orph aned, 146 // The main thread will upon detach just mark its heap pages as orph aned,
130 // but not invalidate its CrossThreadPersistent<>s. 147 // but not invalidate its CrossThreadPersistent<>s.
131 if (page->orphaned()) 148 if (page->orphaned())
132 continue; 149 continue;
133 if (page->arena()->getThreadState() == threadState) 150 if (page->arena()->getThreadState() == threadState)
134 persistent->clear(); 151 persistent->clear();
135 } 152 }
136 slots = slots->m_next; 153 slots = slots->m_next;
137 } 154 }
138 } 155 }
139 156
140 } // namespace blink 157 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698