Changeset 179648 in webkit
- Timestamp:
- Feb 4, 2015, 4:32:47 PM (10 years ago)
- Location:
- trunk/Source/JavaScriptCore
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ChangeLog
r179640 r179648 1 2015-02-04 Mark Lam <mark.lam@apple.com> 2 3 r179576 introduce a deadlock potential during GC thread suspension. 4 <https://webkit.org/b/141268> 5 6 Reviewed by Michael Saboff. 7 8 http://trac.webkit.org/r179576 introduced a potential for deadlocking. 9 In the GC thread suspension loop, we currently delete 10 MachineThreads::Thread that we detect to be invalid. This is unsafe 11 because we may have already suspended some threads, and one of those 12 suspended threads may still be holding the C heap lock which we need 13 for deleting the invalid thread. 14 15 The fix is to put the invalid threads in a separate toBeDeleted list, 16 and delete them only after GC has resumed all threads. 17 18 * heap/MachineStackMarker.cpp: 19 (JSC::MachineThreads::removeCurrentThread): 20 - Undo refactoring removeThreadWithLockAlreadyAcquired() out of 21 removeCurrentThread() since it is no longer needed. 22 23 (JSC::MachineThreads::tryCopyOtherThreadStacks): 24 - Put invalid Threads on a threadsToBeDeleted list, and delete those 25 Threads only after all threads have been resumed. 26 27 (JSC::MachineThreads::removeThreadWithLockAlreadyAcquired): Deleted. 28 * heap/MachineStackMarker.h: 29 1 30 2015-02-04 Joseph Pecoraro <pecoraro@apple.com> 2 31 -
trunk/Source/JavaScriptCore/heap/MachineStackMarker.cpp
r179609 r179648 184 184 } 185 185 186 template<typename PlatformThread> 187 void MachineThreads::removeThreadWithLockAlreadyAcquired(PlatformThread threadToRemove) 188 { 189 if (equalThread(threadToRemove, m_registeredThreads->platformThread)) { 186 void MachineThreads::removeCurrentThread() 187 { 188 PlatformThread currentPlatformThread = getCurrentPlatformThread(); 189 190 MutexLocker lock(m_registeredThreadsMutex); 191 if (equalThread(currentPlatformThread, m_registeredThreads->platformThread)) { 190 192 Thread* t = m_registeredThreads; 191 193 m_registeredThreads = m_registeredThreads->next; … … 195 197 Thread* t; 196 198 for (t = m_registeredThreads->next; t; t = t->next) { 197 if (equalThread(t->platformThread, threadToRemove)) {199 if (equalThread(t->platformThread, currentPlatformThread)) { 198 200 last->next = t->next; 199 201 break; … … 204 206 delete t; 205 207 } 206 }207 208 void MachineThreads::removeCurrentThread()209 {210 PlatformThread currentPlatformThread = getCurrentPlatformThread();211 212 MutexLocker lock(m_registeredThreadsMutex);213 removeThreadWithLockAlreadyAcquired(currentPlatformThread);214 208 } 215 209 … … 457 451 int numberOfThreads = 0; // Using 0 to denote that we haven't counted the number of threads yet. 458 452 int index = 1; 459 453 Thread* threadsToBeDeleted = nullptr; 454 455 Thread* previousThread = nullptr; 460 456 for (Thread* thread = m_registeredThreads; thread; index++) { 461 457 if (!equalThread(thread->platformThread, currentPlatformThread)) { … … 475 471 "JavaScript garbage collection encountered an invalid thread (err 0x%x): Thread [%d/%d: %p] platformThread %p.", 476 472 error, index, numberOfThreads, thread, reinterpret_cast<void*>(thread->platformThread)); 477 473 474 // Put the invalid thread on the threadsToBeDeleted list. 475 // We can't just delete it here because we have suspended other 476 // threads, and they may still be holding the C heap lock which 477 // we need for deleting the invalid thread. Hence, we need to 478 // defer the deletion till after we have resumed all threads. 478 479 Thread* nextThread = thread->next; 479 removeThreadWithLockAlreadyAcquired(thread->platformThread); 480 thread->next = threadsToBeDeleted; 481 threadsToBeDeleted = thread; 482 483 if (previousThread) 484 previousThread->next = nextThread; 485 else 486 m_registeredThreads = nextThread; 480 487 thread = nextThread; 481 488 continue; … … 486 493 #endif 487 494 } 495 previousThread = thread; 488 496 thread = thread->next; 489 497 } … … 499 507 } 500 508 509 for (Thread* thread = threadsToBeDeleted; thread; ) { 510 Thread* nextThread = thread->next; 511 delete thread; 512 thread = nextThread; 513 } 514 501 515 return *size <= capacity; 502 516 } -
trunk/Source/JavaScriptCore/heap/MachineStackMarker.h
r179609 r179648 58 58 void removeCurrentThread(); 59 59 60 template<typename PlatformThread>61 void removeThreadWithLockAlreadyAcquired(PlatformThread);62 63 60 Mutex m_registeredThreadsMutex; 64 61 Thread* m_registeredThreads;
Note:
See TracChangeset
for help on using the changeset viewer.