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 #include "config.h" | 5 #include "config.h" |
| 6 #include "platform/heap/PersistentNode.h" | 6 #include "platform/heap/PersistentNode.h" |
| 7 | 7 |
| 8 #include "platform/heap/Handle.h" | |
| 9 | |
| 8 namespace blink { | 10 namespace blink { |
| 9 | 11 |
| 10 PersistentRegion::~PersistentRegion() | 12 PersistentRegion::~PersistentRegion() |
| 11 { | 13 { |
| 12 PersistentNodeSlots* slots = m_slots; | 14 PersistentNodeSlots* slots = m_slots; |
| 13 while (slots) { | 15 while (slots) { |
| 14 PersistentNodeSlots* deadSlots = slots; | 16 PersistentNodeSlots* deadSlots = slots; |
| 15 slots = slots->m_next; | 17 slots = slots->m_next; |
| 16 delete deadSlots; | 18 delete deadSlots; |
| 17 } | 19 } |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 53 m_freeListHead = nullptr; | 55 m_freeListHead = nullptr; |
| 54 int persistentCount = 0; | 56 int persistentCount = 0; |
| 55 PersistentNodeSlots** prevNext = &m_slots; | 57 PersistentNodeSlots** prevNext = &m_slots; |
| 56 PersistentNodeSlots* slots = m_slots; | 58 PersistentNodeSlots* slots = m_slots; |
| 57 while (slots) { | 59 while (slots) { |
| 58 PersistentNode* freeListNext = nullptr; | 60 PersistentNode* freeListNext = nullptr; |
| 59 PersistentNode* freeListLast = nullptr; | 61 PersistentNode* freeListLast = nullptr; |
| 60 int freeCount = 0; | 62 int freeCount = 0; |
| 61 for (int i = 0; i < PersistentNodeSlots::slotCount; ++i) { | 63 for (int i = 0; i < PersistentNodeSlots::slotCount; ++i) { |
| 62 PersistentNode* node = &slots->m_slot[i]; | 64 PersistentNode* node = &slots->m_slot[i]; |
| 65 if (!node->isValid()) { | |
| 66 // We do allow CrossThreadPersistent<> handles to exist beyond | |
| 67 // the lifetime of the object they refer to and keep alive. | |
| 68 // This to allow an Oilpan thread to shut down and terminate | |
|
haraken
2015/08/03 00:45:25
This is to allow
| |
| 69 // without first coordinating with any and all threads that hold | |
| 70 // CrossThreadPersistent<>s pointing into its heaps - to have | |
| 71 // them first release those references - before the thread | |
| 72 // proceeds to detach its heaps and shuts down. | |
| 73 // | |
| 74 // The cross-thread persistent variant eases the same-thread | |
| 75 // destruction restriction of a persistent (while also keeping | |
| 76 // the object it refers to alive). The persistent reference isn' t | |
| 77 // however so strong so as to prevent a heap being detached and | |
| 78 // destructed. Just that the destruction of the cross-thread | |
| 79 // persistent may happen later and independently from the | |
| 80 // heap of the object it points to. | |
| 81 // | |
| 82 // It is clearly not safe to continue tracing cross-thread | |
| 83 // persistents referring to objects and heaps that have been | |
| 84 // destructed, so these will be marked as invalid and skipped he re. | |
| 85 ++persistentCount; | |
| 86 continue; | |
| 87 } | |
| 63 if (node->isUnused()) { | 88 if (node->isUnused()) { |
| 64 if (!freeListNext) | 89 if (!freeListNext) |
| 65 freeListLast = node; | 90 freeListLast = node; |
| 66 node->setFreeListNext(freeListNext); | 91 node->setFreeListNext(freeListNext); |
| 67 freeListNext = node; | 92 freeListNext = node; |
| 68 ++freeCount; | 93 ++freeCount; |
| 69 } else { | 94 } else { |
| 70 node->tracePersistentNode(visitor); | 95 node->tracePersistentNode(visitor); |
| 71 ++persistentCount; | 96 ++persistentCount; |
| 72 } | 97 } |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 83 freeListLast->setFreeListNext(m_freeListHead); | 108 freeListLast->setFreeListNext(m_freeListHead); |
| 84 m_freeListHead = freeListNext; | 109 m_freeListHead = freeListNext; |
| 85 } | 110 } |
| 86 prevNext = &slots->m_next; | 111 prevNext = &slots->m_next; |
| 87 slots = slots->m_next; | 112 slots = slots->m_next; |
| 88 } | 113 } |
| 89 } | 114 } |
| 90 ASSERT(persistentCount == m_persistentCount); | 115 ASSERT(persistentCount == m_persistentCount); |
| 91 } | 116 } |
| 92 | 117 |
| 118 void CrossThreadPersistentRegion::prepareForThreadStateTermination(ThreadState* threadState) | |
| 119 { | |
| 120 // For heaps belonging to a thread that's detaching, any cross-thread persis tents | |
| 121 // pointing into them needs to be disabled. | |
| 122 MutexLocker lock(m_mutex); | |
| 123 | |
| 124 class Object; | |
| 125 using GCObject = GarbageCollected<Object>; | |
| 126 | |
| 127 // TODO(sof): consider ways of reducing the overhead of this invalidation. | |
| 128 // (e.g., tracking number of active CrossThreadPersistent<>s pointing | |
| 129 // into the heaps of each ThreadState & use that count to terminate traversa l.) | |
|
haraken
2015/08/03 00:45:25
Given that the number of CrossThreadPersistents sh
sof
2015/08/03 08:30:04
I'd like to revisit and address, but thread local
| |
| 130 PersistentNodeSlots* slots = m_persistentRegion->m_slots; | |
| 131 while (slots) { | |
| 132 for (int i = 0; i < PersistentNodeSlots::slotCount; ++i) { | |
| 133 if (!slots->m_slot[i].isValid() || slots->m_slot[i].isUnused()) | |
| 134 continue; | |
| 135 | |
| 136 // 'self' is in use, containing the cross-thread persistent wrapper object. | |
| 137 CrossThreadPersistent<GCObject>* persistent = reinterpret_cast<Cross ThreadPersistent<GCObject>*>(slots->m_slot[i].self()); | |
| 138 ASSERT(persistent); | |
| 139 void* rawObject = persistent->get(); | |
| 140 if (!rawObject) | |
| 141 continue; | |
| 142 BasePage* page = pageFromObject(rawObject); | |
| 143 ASSERT(page); | |
| 144 if (page->heap()->threadState() == threadState) | |
| 145 slots->m_slot[i].invalidate(); | |
| 146 } | |
| 147 slots = slots->m_next; | |
| 148 } | |
| 149 } | |
| 150 | |
| 93 } // namespace blink | 151 } // namespace blink |
| OLD | NEW |