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

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

Issue 1919663002: Unify and generalize thread static persistent finalization. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: rebased 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 /* 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 208 matching lines...) Expand 10 before | Expand all | Expand 10 after
219 } 219 }
220 ASSERT(checkThread()); 220 ASSERT(checkThread());
221 221
222 // Finish sweeping. 222 // Finish sweeping.
223 completeSweep(); 223 completeSweep();
224 224
225 // From here on ignore all conservatively discovered 225 // From here on ignore all conservatively discovered
226 // pointers into the heap owned by this thread. 226 // pointers into the heap owned by this thread.
227 m_isTerminating = true; 227 m_isTerminating = true;
228 228
229 ThreadState::callThreadShutdownHooks(); 229 releaseStaticPersistentNodes();
230 230
231 // Set the terminate flag on all heap pages of this thread. This is used to 231 // Set the terminate flag on all heap pages of this thread. This is used to
232 // ensure we don't trace pages on other threads that are not part of the 232 // ensure we don't trace pages on other threads that are not part of the
233 // thread local GC. 233 // thread local GC.
234 prepareForThreadStateTermination(); 234 prepareForThreadStateTermination();
235 235
236 ProcessHeap::crossThreadPersistentRegion().prepareForThreadStateTermination( this); 236 ProcessHeap::crossThreadPersistentRegion().prepareForThreadStateTermination( this);
237 237
238 // Do thread local GC's as long as the count of thread local Persistents 238 // Do thread local GC's as long as the count of thread local Persistents
239 // changes and is above zero. 239 // changes and is above zero.
(...skipping 14 matching lines...) Expand all
254 254
255 // Add pages to the orphaned page pool to ensure any global GCs from this po int 255 // Add pages to the orphaned page pool to ensure any global GCs from this po int
256 // on will not trace objects on this thread's arenas. 256 // on will not trace objects on this thread's arenas.
257 cleanupPages(); 257 cleanupPages();
258 } 258 }
259 259
260 void ThreadState::cleanupMainThread() 260 void ThreadState::cleanupMainThread()
261 { 261 {
262 ASSERT(isMainThread()); 262 ASSERT(isMainThread());
263 263
264 releaseStaticPersistentNodes();
265
264 #if defined(LEAK_SANITIZER) 266 #if defined(LEAK_SANITIZER)
265 // If LSan is about to perform leak detection, release all the registered 267 // If LSan is about to perform leak detection, after having released all
266 // static Persistent<> root references to global caches that Blink keeps, 268 // the registered static Persistent<> root references to global caches
267 // followed by GCs to clear out all they referred to. 269 // that Blink keeps, follow up with a round of GCs to clear out all
270 // what they referred to.
268 // 271 //
269 // This is not needed for caches over non-Oilpan objects, as they're 272 // This is not needed for caches over non-Oilpan objects, as they're
270 // not scanned by LSan due to being held in non-global storage 273 // not scanned by LSan due to being held in non-global storage
271 // ("static" references inside functions/methods.) 274 // ("static" references inside functions/methods.)
272 releaseStaticPersistentNodes();
273 ThreadHeap::collectAllGarbage(); 275 ThreadHeap::collectAllGarbage();
274 #endif 276 #endif
275 277
276 // Finish sweeping before shutting down V8. Otherwise, some destructor 278 // Finish sweeping before shutting down V8. Otherwise, some destructor
277 // may access V8 and cause crashes. 279 // may access V8 and cause crashes.
278 completeSweep(); 280 completeSweep();
279 281
280 // It is unsafe to trigger GCs after this point because some 282 // It is unsafe to trigger GCs after this point because some
281 // destructor may access already-detached V8 and cause crashes. 283 // destructor may access already-detached V8 and cause crashes.
282 // Also it is useless. So we forbid GCs. 284 // Also it is useless. So we forbid GCs.
283 enterGCForbiddenScope(); 285 enterGCForbiddenScope();
284 } 286 }
285 287
286 void ThreadState::detachMainThread() 288 void ThreadState::detachMainThread()
287 { 289 {
288 // Enter a safe point before trying to acquire threadAttachMutex 290 // Enter a safe point before trying to acquire threadAttachMutex
289 // to avoid dead lock if another thread is preparing for GC, has acquired 291 // to avoid dead lock if another thread is preparing for GC, has acquired
290 // threadAttachMutex and waiting for other threads to pause or reach a 292 // threadAttachMutex and waiting for other threads to pause or reach a
291 // safepoint. 293 // safepoint.
292 ThreadState* state = mainThreadState(); 294 ThreadState* state = mainThreadState();
293 ASSERT(!state->isSweepingInProgress()); 295 ASSERT(!state->isSweepingInProgress());
294 296
295 state->heap().detach(state); 297 state->heap().detach(state);
296 state->~ThreadState(); 298 state->~ThreadState();
297 } 299 }
298 300
299 void ThreadState::callThreadShutdownHooks()
300 {
301 // Invoke the cleanup hooks. This gives an opportunity to release any
302 // persistent handles that may exist, e.g. in thread-specific static
303 // locals.
304 for (const OwnPtr<SameThreadClosure>& hook : m_threadShutdownHooks)
305 (*hook)();
306 }
307
308 void ThreadState::detachCurrentThread() 301 void ThreadState::detachCurrentThread()
309 { 302 {
310 ThreadState* state = current(); 303 ThreadState* state = current();
311 state->heap().detach(state); 304 state->heap().detach(state);
312 RELEASE_ASSERT(state->gcState() == ThreadState::NoGCScheduled); 305 RELEASE_ASSERT(state->gcState() == ThreadState::NoGCScheduled);
313 delete state; 306 delete state;
314 } 307 }
315 308
316 NO_SANITIZE_ADDRESS 309 NO_SANITIZE_ADDRESS
317 void ThreadState::visitAsanFakeStackForPointer(Visitor* visitor, Address ptr) 310 void ThreadState::visitAsanFakeStackForPointer(Visitor* visitor, Address ptr)
(...skipping 997 matching lines...) Expand 10 before | Expand all | Expand 10 after
1315 void ThreadState::addInterruptor(PassOwnPtr<BlinkGCInterruptor> interruptor) 1308 void ThreadState::addInterruptor(PassOwnPtr<BlinkGCInterruptor> interruptor)
1316 { 1309 {
1317 ASSERT(checkThread()); 1310 ASSERT(checkThread());
1318 SafePointScope scope(BlinkGC::HeapPointersOnStack); 1311 SafePointScope scope(BlinkGC::HeapPointersOnStack);
1319 { 1312 {
1320 MutexLocker locker(m_heap->threadAttachMutex()); 1313 MutexLocker locker(m_heap->threadAttachMutex());
1321 m_interruptors.append(interruptor); 1314 m_interruptors.append(interruptor);
1322 } 1315 }
1323 } 1316 }
1324 1317
1325 void ThreadState::registerThreadShutdownHook(PassOwnPtr<SameThreadClosure> hook) 1318 void ThreadState::registerStaticPersistentNode(PersistentNode* node, PersistentC learCallback callback)
1326 { 1319 {
1327 ASSERT(checkThread());
1328 ASSERT(!isTerminating());
1329 m_threadShutdownHooks.append(hook);
1330 }
1331
1332 #if defined(LEAK_SANITIZER) 1320 #if defined(LEAK_SANITIZER)
1333 void ThreadState::registerStaticPersistentNode(PersistentNode* node)
1334 {
1335 if (m_disabledStaticPersistentsRegistration) 1321 if (m_disabledStaticPersistentsRegistration)
1336 return; 1322 return;
1323 #endif
1337 1324
1338 ASSERT(!m_staticPersistents.contains(node)); 1325 ASSERT(!m_staticPersistents.contains(node));
1339 m_staticPersistents.add(node); 1326 m_staticPersistents.add(node, callback);
1340 } 1327 }
1341 1328
1342 void ThreadState::releaseStaticPersistentNodes() 1329 void ThreadState::releaseStaticPersistentNodes()
1343 { 1330 {
1344 for (PersistentNode* node : m_staticPersistents) 1331 HashMap<PersistentNode*, ThreadState::PersistentClearCallback> staticPersist ents;
1345 getPersistentRegion()->freePersistentNode(node); 1332 staticPersistents.swap(m_staticPersistents);
1346 1333
1347 m_staticPersistents.clear(); 1334 PersistentRegion* persistentRegion = getPersistentRegion();
1335 for (const auto& it : staticPersistents)
1336 persistentRegion->releasePersistentNode(it.key, it.value);
1348 } 1337 }
1349 1338
1339 void ThreadState::freePersistentNode(PersistentNode* persistentNode)
1340 {
1341 PersistentRegion* persistentRegion = getPersistentRegion();
1342 persistentRegion->freePersistentNode(persistentNode);
1343 // Do not allow static persistents to be freed before
1344 // they're all released in releaseStaticPersistentNodes().
1345 //
1346 // There's no fundamental reason why this couldn't be supported,
1347 // but no known use for it.
1348 ASSERT(!m_staticPersistents.contains(persistentNode));
1349 }
1350
1351 #if defined(LEAK_SANITIZER)
1350 void ThreadState::enterStaticReferenceRegistrationDisabledScope() 1352 void ThreadState::enterStaticReferenceRegistrationDisabledScope()
1351 { 1353 {
1352 m_disabledStaticPersistentsRegistration++; 1354 m_disabledStaticPersistentsRegistration++;
1353 } 1355 }
1354 1356
1355 void ThreadState::leaveStaticReferenceRegistrationDisabledScope() 1357 void ThreadState::leaveStaticReferenceRegistrationDisabledScope()
1356 { 1358 {
1357 ASSERT(m_disabledStaticPersistentsRegistration); 1359 ASSERT(m_disabledStaticPersistentsRegistration);
1358 m_disabledStaticPersistentsRegistration--; 1360 m_disabledStaticPersistentsRegistration--;
1359 } 1361 }
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after
1515 threadDump->addScalar("dead_count", "objects", totalDeadCount); 1517 threadDump->addScalar("dead_count", "objects", totalDeadCount);
1516 threadDump->addScalar("live_size", "bytes", totalLiveSize); 1518 threadDump->addScalar("live_size", "bytes", totalLiveSize);
1517 threadDump->addScalar("dead_size", "bytes", totalDeadSize); 1519 threadDump->addScalar("dead_size", "bytes", totalDeadSize);
1518 1520
1519 WebMemoryAllocatorDump* heapsDump = BlinkGCMemoryDumpProvider::instance()->c reateMemoryAllocatorDumpForCurrentGC(heapsDumpName); 1521 WebMemoryAllocatorDump* heapsDump = BlinkGCMemoryDumpProvider::instance()->c reateMemoryAllocatorDumpForCurrentGC(heapsDumpName);
1520 WebMemoryAllocatorDump* classesDump = BlinkGCMemoryDumpProvider::instance()- >createMemoryAllocatorDumpForCurrentGC(classesDumpName); 1522 WebMemoryAllocatorDump* classesDump = BlinkGCMemoryDumpProvider::instance()- >createMemoryAllocatorDumpForCurrentGC(classesDumpName);
1521 BlinkGCMemoryDumpProvider::instance()->currentProcessMemoryDump()->addOwners hipEdge(classesDump->guid(), heapsDump->guid()); 1523 BlinkGCMemoryDumpProvider::instance()->currentProcessMemoryDump()->addOwners hipEdge(classesDump->guid(), heapsDump->guid());
1522 } 1524 }
1523 1525
1524 } // namespace blink 1526 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/platform/heap/ThreadState.h ('k') | third_party/WebKit/Source/web/tests/RunAllTests.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698