Changeset 179576 in webkit
- Timestamp:
- Feb 3, 2015, 4:00:00 PM (10 years ago)
- Location:
- trunk/Source/JavaScriptCore
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/API/tests/testapi.mm
r167326 r179576 30 30 #import "JSExportTests.h" 31 31 32 #import <pthread.h> 33 32 34 extern "C" void JSSynchronousGarbageCollectForDebugging(JSContextRef); 33 35 extern "C" void JSSynchronousEdenCollectForDebugging(JSContextRef); … … 469 471 }(); 470 472 return containsClass; 473 } 474 475 static void* threadMain(void* contextPtr) 476 { 477 JSContext *context = (__bridge JSContext*)contextPtr; 478 479 // Do something to enter the VM. 480 TestObject *testObject = [TestObject testObject]; 481 context[@"testObject"] = testObject; 482 pthread_exit(nullptr); 471 483 } 472 484 … … 1360 1372 } 1361 1373 1374 @autoreleasepool { 1375 JSContext *context = [[JSContext alloc] init]; 1376 1377 pthread_t threadID; 1378 pthread_create(&threadID, NULL, &threadMain, (__bridge void*)context); 1379 pthread_join(threadID, nullptr); 1380 JSSynchronousGarbageCollectForDebugging([context JSGlobalContextRef]); 1381 1382 checkResult(@"Did not crash after entering the VM from another thread", true); 1383 } 1384 1362 1385 currentThisInsideBlockGetterTest(); 1363 1386 runDateTests(); -
trunk/Source/JavaScriptCore/ChangeLog
r179562 r179576 1 2015-02-03 Mark Lam <mark.lam@apple.com> 2 3 Workaround a thread library bug where thread destructors may not get called. 4 <https://webkit.org/b/141209> 5 6 Reviewed by Michael Saboff. 7 8 There's a bug where thread destructors may not get called. As far as 9 we know, this only manifests on darwin ports. We will work around this 10 by checking at GC time if the platform thread is still valid. If not, 11 we'll purge it from the VM's registeredThreads list before proceeding 12 with thread scanning activity. 13 14 Note: it is important that we do this invalid thread detection during 15 suspension, because the validity (and liveness) of the other thread is 16 only guaranteed while it is suspended. 17 18 * API/tests/testapi.mm: 19 (threadMain): 20 - Added a test to enter the VM from another thread before we GC on 21 the main thread. 22 23 * heap/MachineStackMarker.cpp: 24 (JSC::MachineThreads::removeThreadWithLockAlreadyAcquired): 25 (JSC::MachineThreads::removeCurrentThread): 26 - refactored removeThreadWithLockAlreadyAcquired() out from 27 removeCurrentThread() so that we can also call it for purging invalid 28 threads. 29 (JSC::suspendThread): 30 - Added a return status to tell if the suspension succeeded or not. 31 (JSC::MachineThreads::tryCopyOtherThreadStacks): 32 - Check if the suspension failed, and purge the thread if we can't 33 suspend it. Failure to suspend implies that the thread has 34 terminated without calling its destructor. 35 * heap/MachineStackMarker.h: 36 1 37 2015-02-03 Joseph Pecoraro <pecoraro@apple.com> 2 38 -
trunk/Source/JavaScriptCore/heap/MachineStackMarker.cpp
r179319 r179576 191 191 } 192 192 193 void MachineThreads::removeCurrentThread() 194 { 195 PlatformThread currentPlatformThread = getCurrentPlatformThread(); 196 197 MutexLocker lock(m_registeredThreadsMutex); 198 199 if (equalThread(currentPlatformThread, m_registeredThreads->platformThread)) { 193 template<typename PlatformThread> 194 void MachineThreads::removeThreadWithLockAlreadyAcquired(PlatformThread threadToRemove) 195 { 196 if (equalThread(threadToRemove, m_registeredThreads->platformThread)) { 200 197 Thread* t = m_registeredThreads; 201 198 m_registeredThreads = m_registeredThreads->next; … … 205 202 Thread* t; 206 203 for (t = m_registeredThreads->next; t; t = t->next) { 207 if (equalThread(t->platformThread, currentPlatformThread)) {204 if (equalThread(t->platformThread, threadToRemove)) { 208 205 last->next = t->next; 209 206 break; … … 215 212 } 216 213 } 217 214 215 void MachineThreads::removeCurrentThread() 216 { 217 PlatformThread currentPlatformThread = getCurrentPlatformThread(); 218 219 MutexLocker lock(m_registeredThreadsMutex); 220 removeThreadWithLockAlreadyAcquired(currentPlatformThread); 221 } 222 218 223 void MachineThreads::gatherFromCurrentThread(ConservativeRoots& conservativeRoots, JITStubRoutineSet& jitStubRoutines, CodeBlockSet& codeBlocks, void* stackCurrent, RegisterState& registers) 219 224 { … … 227 232 } 228 233 229 static inline void suspendThread(const PlatformThread& platformThread) 230 { 231 #if OS(DARWIN) 232 thread_suspend(platformThread); 233 #elif OS(WINDOWS) 234 SuspendThread(platformThread); 234 static inline bool suspendThread(const PlatformThread& platformThread) 235 { 236 #if OS(DARWIN) 237 kern_return_t result = thread_suspend(platformThread); 238 return result == KERN_SUCCESS; 239 #elif OS(WINDOWS) 240 bool threadIsSuspended = (SuspendThread(platformThread) != (DWORD)-1); 241 ASSERT(threadIsSuspended); 242 return threadIsSuspended; 235 243 #elif USE(PTHREADS) 236 244 pthread_kill(platformThread, SigThreadSuspendResume); 245 return true; 237 246 #else 238 247 #error Need a way to suspend threads on this platform … … 453 462 454 463 PlatformThread currentPlatformThread = getCurrentPlatformThread(); 455 for (Thread* thread = m_registeredThreads; thread; thread = thread->next) { 456 if (!equalThread(thread->platformThread, currentPlatformThread)) 457 suspendThread(thread->platformThread); 464 int numberOfThreads = 0; // Using 0 to denote that we haven't counted the number of threads yet. 465 int index = 1; 466 467 for (Thread* thread = m_registeredThreads; thread; index++) { 468 if (!equalThread(thread->platformThread, currentPlatformThread)) { 469 bool success = suspendThread(thread->platformThread); 470 #if OS(DARWIN) 471 if (!success) { 472 if (!numberOfThreads) { 473 for (Thread* countedThread = m_registeredThreads; countedThread; countedThread = countedThread->next) 474 numberOfThreads++; 475 } 476 477 // Re-do the suspension to get the actual failure result for logging. 478 kern_return_t error = thread_suspend(thread->platformThread); 479 ASSERT(error != KERN_SUCCESS); 480 481 WTFReportError(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, 482 "JavaScript garbage collection encountered an invalid thread (err 0x%x): Thread [%d/%d: %p] platformThread %p.", 483 error, index, numberOfThreads, thread, reinterpret_cast<void*>(thread->platformThread)); 484 485 Thread* nextThread = thread->next; 486 removeThreadWithLockAlreadyAcquired(thread->platformThread); 487 thread = nextThread; 488 continue; 489 } 490 #else 491 UNUSED_PARAM(numberOfThreads); 492 ASSERT_UNUSED(success, success); 493 #endif 494 } 495 thread = thread->next; 458 496 } 459 497 -
trunk/Source/JavaScriptCore/heap/MachineStackMarker.h
r179319 r179576 59 59 void removeCurrentThread(); 60 60 61 template<typename PlatformThread> 62 void removeThreadWithLockAlreadyAcquired(PlatformThread); 63 61 64 Mutex m_registeredThreadsMutex; 62 65 Thread* m_registeredThreads;
Note:
See TracChangeset
for help on using the changeset viewer.