OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2013 Google Inc. All rights reserved. | 2 * Copyright (C) 2013 Google Inc. All rights reserved. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
6 * met: | 6 * met: |
7 * | 7 * |
8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
126 #if defined(LEAK_SANITIZER) | 126 #if defined(LEAK_SANITIZER) |
127 m_disabledStaticPersistentsRegistration(0), | 127 m_disabledStaticPersistentsRegistration(0), |
128 #endif | 128 #endif |
129 m_allocatedObjectSize(0), | 129 m_allocatedObjectSize(0), |
130 m_markedObjectSize(0), | 130 m_markedObjectSize(0), |
131 m_reportedMemoryToV8(0) { | 131 m_reportedMemoryToV8(0) { |
132 ASSERT(checkThread()); | 132 ASSERT(checkThread()); |
133 ASSERT(!**s_threadSpecific); | 133 ASSERT(!**s_threadSpecific); |
134 **s_threadSpecific = this; | 134 **s_threadSpecific = this; |
135 | 135 |
136 m_heap = new ThreadHeap(); | 136 m_heap = WTF::wrapUnique(new ThreadHeap(this)); |
137 ASSERT(m_heap); | |
138 m_heap->attach(this); | |
139 | 137 |
140 for (int arenaIndex = 0; arenaIndex < BlinkGC::LargeObjectArenaIndex; | 138 for (int arenaIndex = 0; arenaIndex < BlinkGC::LargeObjectArenaIndex; |
141 arenaIndex++) | 139 arenaIndex++) |
142 m_arenas[arenaIndex] = new NormalPageArena(this, arenaIndex); | 140 m_arenas[arenaIndex] = new NormalPageArena(this, arenaIndex); |
143 m_arenas[BlinkGC::LargeObjectArenaIndex] = | 141 m_arenas[BlinkGC::LargeObjectArenaIndex] = |
144 new LargeObjectArena(this, BlinkGC::LargeObjectArenaIndex); | 142 new LargeObjectArena(this, BlinkGC::LargeObjectArenaIndex); |
145 | 143 |
146 m_likelyToBePromptlyFreed = | 144 m_likelyToBePromptlyFreed = |
147 wrapArrayUnique(new int[likelyToBePromptlyFreedArraySize]); | 145 wrapArrayUnique(new int[likelyToBePromptlyFreedArraySize]); |
148 clearArenaAges(); | 146 clearArenaAges(); |
149 } | 147 } |
150 | 148 |
151 ThreadState::~ThreadState() { | 149 ThreadState::~ThreadState() { |
152 ASSERT(checkThread()); | 150 ASSERT(checkThread()); |
153 for (int i = 0; i < BlinkGC::NumberOfArenas; ++i) | 151 for (int i = 0; i < BlinkGC::NumberOfArenas; ++i) |
154 delete m_arenas[i]; | 152 delete m_arenas[i]; |
155 | 153 |
156 **s_threadSpecific = nullptr; | 154 **s_threadSpecific = nullptr; |
157 } | 155 } |
158 | 156 |
159 void ThreadState::attachMainThread() { | 157 void ThreadState::attachMainThread() { |
160 s_threadSpecific = new WTF::ThreadSpecific<ThreadState*>(); | 158 s_threadSpecific = new WTF::ThreadSpecific<ThreadState*>(); |
161 new (s_mainThreadStateStorage) ThreadState(); | 159 new (s_mainThreadStateStorage) ThreadState(); |
162 } | 160 } |
163 | 161 |
164 void ThreadState::attachCurrentThread() { | 162 void ThreadState::attachCurrentThread() { |
165 new ThreadState(); | 163 new ThreadState(); |
166 } | 164 } |
167 | 165 |
| 166 void ThreadState::detachCurrentThread() { |
| 167 ThreadState* state = current(); |
| 168 state->runTerminationGC(); |
| 169 if (state->isMainThread()) |
| 170 DCHECK_EQ(state->heap().heapStats().allocatedSpace(), 0u); |
| 171 CHECK(state->gcState() == ThreadState::NoGCScheduled); |
| 172 delete state; |
| 173 } |
| 174 |
168 void ThreadState::removeAllPages() { | 175 void ThreadState::removeAllPages() { |
169 ASSERT(checkThread()); | 176 ASSERT(checkThread()); |
170 for (int i = 0; i < BlinkGC::NumberOfArenas; ++i) | 177 for (int i = 0; i < BlinkGC::NumberOfArenas; ++i) |
171 m_arenas[i]->removeAllPages(); | 178 m_arenas[i]->removeAllPages(); |
172 } | 179 } |
173 | 180 |
174 void ThreadState::runTerminationGC() { | 181 void ThreadState::runTerminationGC() { |
175 if (isMainThread()) { | 182 if (isMainThread()) { |
176 removeAllPages(); | 183 removeAllPages(); |
177 return; | 184 return; |
(...skipping 25 matching lines...) Expand all Loading... |
203 // We should not have any persistents left when getting to this point, | 210 // We should not have any persistents left when getting to this point, |
204 // if we have it is probably a bug so adding a debug ASSERT to catch this. | 211 // if we have it is probably a bug so adding a debug ASSERT to catch this. |
205 ASSERT(!currentCount); | 212 ASSERT(!currentCount); |
206 // All of pre-finalizers should be consumed. | 213 // All of pre-finalizers should be consumed. |
207 ASSERT(m_orderedPreFinalizers.isEmpty()); | 214 ASSERT(m_orderedPreFinalizers.isEmpty()); |
208 RELEASE_ASSERT(gcState() == NoGCScheduled); | 215 RELEASE_ASSERT(gcState() == NoGCScheduled); |
209 | 216 |
210 removeAllPages(); | 217 removeAllPages(); |
211 } | 218 } |
212 | 219 |
213 void ThreadState::detachCurrentThread() { | |
214 ThreadState* state = current(); | |
215 state->heap().detach(state); | |
216 RELEASE_ASSERT(state->gcState() == ThreadState::NoGCScheduled); | |
217 delete state; | |
218 } | |
219 | |
220 NO_SANITIZE_ADDRESS | 220 NO_SANITIZE_ADDRESS |
221 void ThreadState::visitAsanFakeStackForPointer(Visitor* visitor, Address ptr) { | 221 void ThreadState::visitAsanFakeStackForPointer(Visitor* visitor, Address ptr) { |
222 #if defined(ADDRESS_SANITIZER) | 222 #if defined(ADDRESS_SANITIZER) |
223 Address* start = reinterpret_cast<Address*>(m_startOfStack); | 223 Address* start = reinterpret_cast<Address*>(m_startOfStack); |
224 Address* end = reinterpret_cast<Address*>(m_endOfStack); | 224 Address* end = reinterpret_cast<Address*>(m_endOfStack); |
225 Address* fakeFrameStart = nullptr; | 225 Address* fakeFrameStart = nullptr; |
226 Address* fakeFrameEnd = nullptr; | 226 Address* fakeFrameEnd = nullptr; |
227 Address* maybeFakeFrame = reinterpret_cast<Address*>(ptr); | 227 Address* maybeFakeFrame = reinterpret_cast<Address*>(ptr); |
228 Address* realFrameForFakeFrame = reinterpret_cast<Address*>( | 228 Address* realFrameForFakeFrame = reinterpret_cast<Address*>( |
229 __asan_addr_is_in_fake_stack(m_asanFakeStack, maybeFakeFrame, | 229 __asan_addr_is_in_fake_stack(m_asanFakeStack, maybeFakeFrame, |
(...skipping 981 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1211 m_safePointStackCopy.resize(slotCount); | 1211 m_safePointStackCopy.resize(slotCount); |
1212 for (size_t i = 0; i < slotCount; ++i) { | 1212 for (size_t i = 0; i < slotCount; ++i) { |
1213 m_safePointStackCopy[i] = from[i]; | 1213 m_safePointStackCopy[i] = from[i]; |
1214 } | 1214 } |
1215 } | 1215 } |
1216 | 1216 |
1217 void ThreadState::addInterruptor( | 1217 void ThreadState::addInterruptor( |
1218 std::unique_ptr<BlinkGCInterruptor> interruptor) { | 1218 std::unique_ptr<BlinkGCInterruptor> interruptor) { |
1219 ASSERT(checkThread()); | 1219 ASSERT(checkThread()); |
1220 SafePointScope scope(BlinkGC::HeapPointersOnStack); | 1220 SafePointScope scope(BlinkGC::HeapPointersOnStack); |
1221 { | 1221 m_interruptors.push_back(std::move(interruptor)); |
1222 MutexLocker locker(m_heap->threadAttachMutex()); | |
1223 m_interruptors.push_back(std::move(interruptor)); | |
1224 } | |
1225 } | 1222 } |
1226 | 1223 |
1227 void ThreadState::registerStaticPersistentNode( | 1224 void ThreadState::registerStaticPersistentNode( |
1228 PersistentNode* node, | 1225 PersistentNode* node, |
1229 PersistentClearCallback callback) { | 1226 PersistentClearCallback callback) { |
1230 #if defined(LEAK_SANITIZER) | 1227 #if defined(LEAK_SANITIZER) |
1231 if (m_disabledStaticPersistentsRegistration) | 1228 if (m_disabledStaticPersistentsRegistration) |
1232 return; | 1229 return; |
1233 #endif | 1230 #endif |
1234 | 1231 |
(...skipping 26 matching lines...) Expand all Loading... |
1261 void ThreadState::enterStaticReferenceRegistrationDisabledScope() { | 1258 void ThreadState::enterStaticReferenceRegistrationDisabledScope() { |
1262 m_disabledStaticPersistentsRegistration++; | 1259 m_disabledStaticPersistentsRegistration++; |
1263 } | 1260 } |
1264 | 1261 |
1265 void ThreadState::leaveStaticReferenceRegistrationDisabledScope() { | 1262 void ThreadState::leaveStaticReferenceRegistrationDisabledScope() { |
1266 ASSERT(m_disabledStaticPersistentsRegistration); | 1263 ASSERT(m_disabledStaticPersistentsRegistration); |
1267 m_disabledStaticPersistentsRegistration--; | 1264 m_disabledStaticPersistentsRegistration--; |
1268 } | 1265 } |
1269 #endif | 1266 #endif |
1270 | 1267 |
1271 void ThreadState::lockThreadAttachMutex() { | |
1272 m_heap->threadAttachMutex().lock(); | |
1273 } | |
1274 | |
1275 void ThreadState::unlockThreadAttachMutex() { | |
1276 m_heap->threadAttachMutex().unlock(); | |
1277 } | |
1278 | |
1279 void ThreadState::invokePreFinalizers() { | 1268 void ThreadState::invokePreFinalizers() { |
1280 ASSERT(checkThread()); | 1269 ASSERT(checkThread()); |
1281 ASSERT(!sweepForbidden()); | 1270 ASSERT(!sweepForbidden()); |
1282 TRACE_EVENT0("blink_gc", "ThreadState::invokePreFinalizers"); | 1271 TRACE_EVENT0("blink_gc", "ThreadState::invokePreFinalizers"); |
1283 | 1272 |
1284 double startTime = WTF::currentTimeMS(); | 1273 double startTime = WTF::currentTimeMS(); |
1285 if (!m_orderedPreFinalizers.isEmpty()) { | 1274 if (!m_orderedPreFinalizers.isEmpty()) { |
1286 SweepForbiddenScope sweepForbidden(this); | 1275 SweepForbiddenScope sweepForbidden(this); |
1287 ScriptForbiddenIfMainThreadScope scriptForbidden; | 1276 ScriptForbiddenIfMainThreadScope scriptForbidden; |
1288 | 1277 |
(...skipping 279 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1568 collectGarbage(BlinkGC::NoHeapPointersOnStack, BlinkGC::GCWithSweep, | 1557 collectGarbage(BlinkGC::NoHeapPointersOnStack, BlinkGC::GCWithSweep, |
1569 BlinkGC::ForcedGC); | 1558 BlinkGC::ForcedGC); |
1570 size_t liveObjects = heap().heapStats().markedObjectSize(); | 1559 size_t liveObjects = heap().heapStats().markedObjectSize(); |
1571 if (liveObjects == previousLiveObjects) | 1560 if (liveObjects == previousLiveObjects) |
1572 break; | 1561 break; |
1573 previousLiveObjects = liveObjects; | 1562 previousLiveObjects = liveObjects; |
1574 } | 1563 } |
1575 } | 1564 } |
1576 | 1565 |
1577 } // namespace blink | 1566 } // namespace blink |
OLD | NEW |