<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[215265] trunk</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/215265">215265</a></dd>
<dt>Author</dt> <dd>utatane.tea@gmail.com</dd>
<dt>Date</dt> <dd>2017-04-12 05:08:29 -0700 (Wed, 12 Apr 2017)</dd>
</dl>

<h3>Log Message</h3>
<pre>[WTF] Introduce Thread class and use RefPtr&lt;Thread&gt; and align Windows Threading implementation semantics to Pthread one
https://bugs.webkit.org/show_bug.cgi?id=170502

Reviewed by Mark Lam.

Source/JavaScriptCore:

* API/tests/CompareAndSwapTest.cpp:
(testCompareAndSwap):
* JavaScriptCore.xcodeproj/project.pbxproj:
* b3/air/testair.cpp:
* b3/testb3.cpp:
(JSC::B3::run):
* bytecode/SuperSampler.cpp:
(JSC::initializeSuperSampler):
* dfg/DFGWorklist.cpp:
* disassembler/Disassembler.cpp:
* heap/Heap.cpp:
(JSC::Heap::lastChanceToFinalize):
(JSC::Heap::notifyIsSafeToCollect):
* heap/Heap.h:
* heap/MachineStackMarker.cpp:
(JSC::MachineThreads::~MachineThreads):
(JSC::MachineThreads::addCurrentThread):
(JSC::MachineThreads::removeThread):
(JSC::MachineThreads::removeThreadIfFound):
(JSC::MachineThreads::MachineThread::MachineThread):
(JSC::MachineThreads::MachineThread::getRegisters):
(JSC::MachineThreads::MachineThread::Registers::stackPointer):
(JSC::MachineThreads::MachineThread::Registers::framePointer):
(JSC::MachineThreads::MachineThread::Registers::instructionPointer):
(JSC::MachineThreads::MachineThread::Registers::llintPC):
(JSC::MachineThreads::MachineThread::captureStack):
(JSC::MachineThreads::tryCopyOtherThreadStack):
(JSC::MachineThreads::tryCopyOtherThreadStacks):
(pthreadSignalHandlerSuspendResume): Deleted.
(JSC::threadData): Deleted.
(JSC::MachineThreads::Thread::Thread): Deleted.
(JSC::MachineThreads::Thread::createForCurrentThread): Deleted.
(JSC::MachineThreads::Thread::operator==): Deleted.
(JSC::MachineThreads::machineThreadForCurrentThread): Deleted.
(JSC::MachineThreads::ThreadData::ThreadData): Deleted.
(JSC::MachineThreads::ThreadData::~ThreadData): Deleted.
(JSC::MachineThreads::ThreadData::suspend): Deleted.
(JSC::MachineThreads::ThreadData::resume): Deleted.
(JSC::MachineThreads::ThreadData::getRegisters): Deleted.
(JSC::MachineThreads::ThreadData::Registers::stackPointer): Deleted.
(JSC::MachineThreads::ThreadData::Registers::framePointer): Deleted.
(JSC::MachineThreads::ThreadData::Registers::instructionPointer): Deleted.
(JSC::MachineThreads::ThreadData::Registers::llintPC): Deleted.
(JSC::MachineThreads::ThreadData::freeRegisters): Deleted.
(JSC::MachineThreads::ThreadData::captureStack): Deleted.
* heap/MachineStackMarker.h:
(JSC::MachineThreads::MachineThread::suspend):
(JSC::MachineThreads::MachineThread::resume):
(JSC::MachineThreads::MachineThread::threadID):
(JSC::MachineThreads::MachineThread::stackBase):
(JSC::MachineThreads::MachineThread::stackEnd):
(JSC::MachineThreads::threadsListHead):
(JSC::MachineThreads::Thread::operator!=): Deleted.
(JSC::MachineThreads::Thread::suspend): Deleted.
(JSC::MachineThreads::Thread::resume): Deleted.
(JSC::MachineThreads::Thread::getRegisters): Deleted.
(JSC::MachineThreads::Thread::freeRegisters): Deleted.
(JSC::MachineThreads::Thread::captureStack): Deleted.
(JSC::MachineThreads::Thread::platformThread): Deleted.
(JSC::MachineThreads::Thread::stackBase): Deleted.
(JSC::MachineThreads::Thread::stackEnd): Deleted.
* jit/ICStats.cpp:
(JSC::ICStats::ICStats):
(JSC::ICStats::~ICStats):
* jit/ICStats.h:
* jsc.cpp:
(functionDollarAgentStart):
(startTimeoutThreadIfNeeded):
* runtime/JSLock.cpp:
(JSC::JSLock::lock):
* runtime/JSLock.h:
(JSC::JSLock::ownerThread):
(JSC::JSLock::currentThreadIsHoldingLock):
* runtime/SamplingProfiler.cpp:
(JSC::FrameWalker::isValidFramePointer):
(JSC::SamplingProfiler::SamplingProfiler):
(JSC::SamplingProfiler::createThreadIfNecessary):
(JSC::SamplingProfiler::takeSample):
* runtime/SamplingProfiler.h:
* runtime/VM.h:
(JSC::VM::ownerThread):
* runtime/VMTraps.cpp:
(JSC::findActiveVMAndStackBounds):
(JSC::VMTraps::SignalSender::send):
(JSC::VMTraps::fireTrap):

Source/WebCore:

Mechanical change. Use Thread:: APIs.

* Modules/indexeddb/server/IDBServer.cpp:
(WebCore::IDBServer::IDBServer::IDBServer):
* Modules/indexeddb/server/IDBServer.h:
* Modules/webaudio/AsyncAudioDecoder.cpp:
(WebCore::AsyncAudioDecoder::AsyncAudioDecoder):
(WebCore::AsyncAudioDecoder::~AsyncAudioDecoder):
(WebCore::AsyncAudioDecoder::runLoop):
* Modules/webaudio/AsyncAudioDecoder.h:
* Modules/webaudio/OfflineAudioDestinationNode.cpp:
(WebCore::OfflineAudioDestinationNode::OfflineAudioDestinationNode):
(WebCore::OfflineAudioDestinationNode::uninitialize):
(WebCore::OfflineAudioDestinationNode::startRendering):
* Modules/webaudio/OfflineAudioDestinationNode.h:
* Modules/webdatabase/Database.cpp:
(WebCore::Database::securityOrigin):
* Modules/webdatabase/DatabaseThread.cpp:
(WebCore::DatabaseThread::start):
(WebCore::DatabaseThread::databaseThread):
(WebCore::DatabaseThread::recordDatabaseOpen):
(WebCore::DatabaseThread::recordDatabaseClosed):
* Modules/webdatabase/DatabaseThread.h:
(WebCore::DatabaseThread::getThreadID):
* bindings/js/GCController.cpp:
(WebCore::GCController::garbageCollectOnAlternateThreadForDebugging):
* fileapi/AsyncFileStream.cpp:
(WebCore::callOnFileThread):
* loader/icon/IconDatabase.cpp:
(WebCore::IconDatabase::open):
(WebCore::IconDatabase::close):
* loader/icon/IconDatabase.h:
* page/ResourceUsageThread.cpp:
(WebCore::ResourceUsageThread::createThreadIfNeeded):
* page/ResourceUsageThread.h:
* page/scrolling/ScrollingThread.cpp:
(WebCore::ScrollingThread::ScrollingThread):
(WebCore::ScrollingThread::isCurrentThread):
(WebCore::ScrollingThread::createThreadIfNeeded):
(WebCore::ScrollingThread::threadCallback):
* page/scrolling/ScrollingThread.h:
* platform/audio/HRTFDatabaseLoader.cpp:
(WebCore::HRTFDatabaseLoader::HRTFDatabaseLoader):
(WebCore::HRTFDatabaseLoader::loadAsynchronously):
(WebCore::HRTFDatabaseLoader::waitForLoaderThreadCompletion):
* platform/audio/HRTFDatabaseLoader.h:
* platform/audio/ReverbConvolver.cpp:
(WebCore::ReverbConvolver::ReverbConvolver):
(WebCore::ReverbConvolver::~ReverbConvolver):
* platform/audio/ReverbConvolver.h:
* platform/audio/gstreamer/AudioFileReaderGStreamer.cpp:
(WebCore::createBusFromAudioFile):
(WebCore::createBusFromInMemoryAudioFile):
* platform/graphics/gstreamer/WebKitWebSourceGStreamer.cpp:
(ResourceHandleStreamingClient::ResourceHandleStreamingClient):
(ResourceHandleStreamingClient::~ResourceHandleStreamingClient):
* platform/network/cf/LoaderRunLoopCF.cpp:
(WebCore::loaderRunLoop):
* platform/network/curl/CurlDownload.cpp:
(WebCore::CurlDownloadManager::startThreadIfNeeded):
(WebCore::CurlDownloadManager::stopThread):
* platform/network/curl/CurlDownload.h:
* platform/network/curl/SocketStreamHandleImpl.h:
* platform/network/curl/SocketStreamHandleImplCurl.cpp:
(WebCore::SocketStreamHandleImpl::startThread):
(WebCore::SocketStreamHandleImpl::stopThread):
* workers/WorkerThread.cpp:
(WebCore::WorkerThread::WorkerThread):
(WebCore::WorkerThread::start):
(WebCore::WorkerThread::workerThread):
* workers/WorkerThread.h:
(WebCore::WorkerThread::threadID):

Source/WebKit:

Mechanical change. Use Thread:: APIs.

* Storage/StorageThread.cpp:
(WebCore::StorageThread::StorageThread):
(WebCore::StorageThread::~StorageThread):
(WebCore::StorageThread::start):
(WebCore::StorageThread::dispatch):
(WebCore::StorageThread::terminate):
* Storage/StorageThread.h:

Source/WebKit2:

Mechanical change. Use Thread:: APIs.

* NetworkProcess/NetworkProcess.cpp:
(WebKit::NetworkProcess::initializeNetworkProcess):
* NetworkProcess/cache/NetworkCacheIOChannelSoup.cpp:
(WebKit::NetworkCache::IOChannel::readSyncInThread):
* Platform/IPC/Connection.cpp:
(IPC::Connection::processIncomingMessage):
* Shared/EntryPointUtilities/mac/XPCService/XPCServiceEntryPoint.h:
(WebKit::XPCServiceInitializer):
* UIProcess/linux/MemoryPressureMonitor.cpp:
(WebKit::MemoryPressureMonitor::MemoryPressureMonitor):
* WebProcess/WebProcess.cpp:
(WebKit::WebProcess::initializeWebProcess):

Source/WTF:

This patch is refactoring of WTF Threading mechanism to merge JavaScriptCore's threading extension to WTF Threading.
Previously, JavaScriptCore requires richer threading features (such as suspending and resuming threads), and they
are implemented for PlatformThread in JavaScriptCore. But these features should be implemented in WTF Threading side
instead of maintaining JSC's own threading features too. This patch removes these features from JSC and move it to
WTF Threading.

However, current WTF Threading has one problem: Windows version of WTF Threading has different semantics from Pthreads
one. In Windows WTF Threading, we cannot perform any operation after the target thread is detached: WTF Threading stop
tracking the state of the thread once the thread is detached. But this is not the same to Pthreads one. In Pthreads,
pthread_detach just means that the resource of the thread will be destroyed automatically. While some operations like
pthread_join will be rejected, some operations like pthread_kill will be accepted.

The problem is that detached thread can be suspended and resumed in JSC. For example, in jsc.cpp, we start the worker
thread and detach it immediately. In worker thread, we will create VM and thus concurrent GC will suspend and resume
the detached thread. However, in Windows WTF Threading, we have no reference to the detached thread. Thus we cannot
perform suspend and resume operations onto the detached thread.

To solve the problem, we change Windows Threading mechanism drastically to align it to the Pthread semantics. In the
new Threading, we have RefPtr&lt;Thread&gt; class. It holds a handle to a platform thread. We can perform threading operations
with this class. For example, Thread::suspend is offered. And we use destructor of the thread local variable to release
the resources held by RefPtr&lt;Thread&gt;. In Windows, Thread::detach does nothing because the resource will be destroyed
automatically by RefPtr&lt;Thread&gt;.

To do so, we introduce ThreadHolder for Windows. This is similar to the previous ThreadIdentifierData for Pthreads.
It holds RefPtr&lt;Thread&gt; in the thread local storage (technically, it is Fiber Local Storage in Windows). Thread::current()
will return this reference.

The problematic situation is that the order of the deallocation of the thread local storage is not defined. So we should
not touch thread local storage in the destructor of the thread local storage. To avoid such edge cases, we have
currentThread() / Thread::currentID() APIs. They are safe to be called even in the destructor of the other thread local
storage. And in Windows, in the FLS destructor, we will create the thread_local variable to defer the destruction of
the ThreadHolder. We ensure that this destructor is called after the other FLS destructors are called in Windows 10.

This patch is performance neutral.

* WTF.xcodeproj/project.pbxproj:
* benchmarks/ConditionSpeedTest.cpp:
* benchmarks/LockFairnessTest.cpp:
* benchmarks/LockSpeedTest.cpp:
* wtf/AutomaticThread.cpp:
(WTF::AutomaticThread::start):
* wtf/CMakeLists.txt:
* wtf/MainThread.h:
* wtf/MemoryPressureHandler.h:
* wtf/ParallelJobsGeneric.cpp:
(WTF::ParallelEnvironment::ThreadPrivate::tryLockFor):
(WTF::ParallelEnvironment::ThreadPrivate::workerThread):
* wtf/ParallelJobsGeneric.h:
(WTF::ParallelEnvironment::ThreadPrivate::ThreadPrivate): Deleted.
* wtf/ParkingLot.cpp:
(WTF::ParkingLot::forEachImpl):
* wtf/ParkingLot.h:
(WTF::ParkingLot::forEach):
* wtf/PlatformRegisters.h: Renamed from Source/JavaScriptCore/runtime/PlatformThread.h.
* wtf/RefPtr.h:
(WTF::RefPtr::RefPtr):
* wtf/ThreadFunctionInvocation.h:
(WTF::ThreadFunctionInvocation::ThreadFunctionInvocation):
* wtf/ThreadHolder.cpp: Added.
(WTF::ThreadHolder::~ThreadHolder):
(WTF::ThreadHolder::initialize):
* wtf/ThreadHolder.h: Renamed from Source/WTF/wtf/ThreadIdentifierDataPthreads.h.
(WTF::ThreadHolder::thread):
(WTF::ThreadHolder::ThreadHolder):
* wtf/ThreadHolderPthreads.cpp: Renamed from Source/WTF/wtf/ThreadIdentifierDataPthreads.cpp.
(WTF::ThreadHolder::initializeOnce):
(WTF::ThreadHolder::current):
(WTF::ThreadHolder::destruct):
* wtf/ThreadHolderWin.cpp: Added.
(WTF::threadMapMutex):
(WTF::threadMap):
(WTF::ThreadHolder::initializeOnce):
(WTF::ThreadHolder::current):
(WTF::ThreadHolder::destruct):
* wtf/ThreadSpecific.h:
* wtf/Threading.cpp:
(WTF::Thread::normalizeThreadName):
(WTF::threadEntryPoint):
(WTF::Thread::create):
(WTF::Thread::setCurrentThreadIsUserInteractive):
(WTF::Thread::setCurrentThreadIsUserInitiated):
(WTF::Thread::setGlobalMaxQOSClass):
(WTF::Thread::adjustedQOSClass):
(WTF::Thread::dump):
(WTF::initializeThreading):
(WTF::normalizeThreadName): Deleted.
(WTF::createThread): Deleted.
(WTF::setCurrentThreadIsUserInteractive): Deleted.
(WTF::setCurrentThreadIsUserInitiated): Deleted.
(WTF::setGlobalMaxQOSClass): Deleted.
(WTF::adjustedQOSClass): Deleted.
* wtf/Threading.h:
(WTF::Thread::id):
(WTF::Thread::operator==):
(WTF::Thread::operator!=):
(WTF::Thread::joinableState):
(WTF::Thread::didBecomeDetached):
(WTF::Thread::didJoin):
(WTF::Thread::hasExited):
(WTF::currentThread):
* wtf/ThreadingPthreads.cpp:
(WTF::Thread::Thread):
(WTF::Thread::~Thread):
(WTF::Thread::signalHandlerSuspendResume):
(WTF::Thread::initializePlatformThreading):
(WTF::initializeCurrentThreadEvenIfNonWTFCreated):
(WTF::wtfThreadEntryPoint):
(WTF::Thread::createInternal):
(WTF::Thread::initializeCurrentThreadInternal):
(WTF::Thread::changePriority):
(WTF::Thread::waitForCompletion):
(WTF::Thread::detach):
(WTF::Thread::current):
(WTF::Thread::currentID):
(WTF::Thread::signal):
(WTF::Thread::resume):
(WTF::Thread::getRegisters):
(WTF::Thread::didExit):
(WTF::Thread::establish):
(WTF::PthreadState::PthreadState): Deleted.
(WTF::PthreadState::joinableState): Deleted.
(WTF::PthreadState::pthreadHandle): Deleted.
(WTF::PthreadState::didBecomeDetached): Deleted.
(WTF::PthreadState::didExit): Deleted.
(WTF::PthreadState::didJoin): Deleted.
(WTF::PthreadState::hasExited): Deleted.
(WTF::threadMapMutex): Deleted.
(WTF::initializeThreading): Deleted.
(WTF::threadMap): Deleted.
(WTF::identifierByPthreadHandle): Deleted.
(WTF::establishIdentifierForPthreadHandle): Deleted.
(WTF::pthreadHandleForIdentifierWithLockAlreadyHeld): Deleted.
(WTF::createThreadInternal): Deleted.
(WTF::initializeCurrentThreadInternal): Deleted.
(WTF::changeThreadPriority): Deleted.
(WTF::waitForThreadCompletion): Deleted.
(WTF::detachThread): Deleted.
(WTF::threadDidExit): Deleted.
(WTF::currentThread): Deleted.
(WTF::signalThread): Deleted.
* wtf/ThreadingWin.cpp:
(WTF::Thread::Thread):
(WTF::Thread::~Thread):
(WTF::Thread::initializeCurrentThreadInternal):
(WTF::Thread::initializePlatformThreading):
(WTF::wtfThreadEntryPoint):
(WTF::Thread::createInternal):
(WTF::Thread::changePriority):
(WTF::Thread::waitForCompletion):
(WTF::Thread::detach):
(WTF::Thread::resume):
(WTF::Thread::getRegisters):
(WTF::Thread::current):
(WTF::Thread::currentID):
(WTF::Thread::didExit):
(WTF::Thread::establish):
(WTF::initializeCurrentThreadInternal): Deleted.
(WTF::threadMapMutex): Deleted.
(WTF::initializeThreading): Deleted.
(WTF::threadMap): Deleted.
(WTF::storeThreadHandleByIdentifier): Deleted.
(WTF::threadHandleForIdentifier): Deleted.
(WTF::clearThreadHandleForIdentifier): Deleted.
(WTF::createThreadInternal): Deleted.
(WTF::changeThreadPriority): Deleted.
(WTF::waitForThreadCompletion): Deleted.
(WTF::detachThread): Deleted.
(WTF::currentThread): Deleted.
* wtf/WorkQueue.cpp:
(WTF::WorkQueue::concurrentApply):
* wtf/WorkQueue.h:
* wtf/cocoa/WorkQueueCocoa.cpp:
(WTF::dispatchQOSClass):
* wtf/generic/WorkQueueGeneric.cpp:
(WorkQueue::platformInitialize):
(WorkQueue::platformInvalidate):
* wtf/linux/MemoryPressureHandlerLinux.cpp:
(WTF::MemoryPressureHandler::EventFDPoller::EventFDPoller):
(WTF::MemoryPressureHandler::EventFDPoller::~EventFDPoller):
* wtf/win/MainThreadWin.cpp:
(WTF::initializeMainThreadPlatform):

Tools:

Mechanical change. Use Thread:: APIs.

* DumpRenderTree/JavaScriptThreading.cpp:
(runJavaScriptThread):
(startJavaScriptThreads):
(stopJavaScriptThreads):
* DumpRenderTree/mac/DumpRenderTree.mm:
(testThreadIdentifierMap):
* TestWebKitAPI/Tests/WTF/Condition.cpp:
* TestWebKitAPI/Tests/WTF/Lock.cpp:
(TestWebKitAPI::runLockTest):
* TestWebKitAPI/Tests/WTF/ParkingLot.cpp:</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceJavaScriptCoreAPItestsCompareAndSwapTestcpp">trunk/Source/JavaScriptCore/API/tests/CompareAndSwapTest.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreChangeLog">trunk/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCoreJavaScriptCorexcodeprojprojectpbxproj">trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3airtestaircpp">trunk/Source/JavaScriptCore/b3/air/testair.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreb3testb3cpp">trunk/Source/JavaScriptCore/b3/testb3.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorebytecodeSuperSamplercpp">trunk/Source/JavaScriptCore/bytecode/SuperSampler.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGWorklistcpp">trunk/Source/JavaScriptCore/dfg/DFGWorklist.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoredisassemblerDisassemblercpp">trunk/Source/JavaScriptCore/disassembler/Disassembler.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreheapHeapcpp">trunk/Source/JavaScriptCore/heap/Heap.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreheapHeaph">trunk/Source/JavaScriptCore/heap/Heap.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreheapMachineStackMarkercpp">trunk/Source/JavaScriptCore/heap/MachineStackMarker.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreheapMachineStackMarkerh">trunk/Source/JavaScriptCore/heap/MachineStackMarker.h</a></li>
<li><a href="#trunkSourceJavaScriptCorejitICStatscpp">trunk/Source/JavaScriptCore/jit/ICStats.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCorejitICStatsh">trunk/Source/JavaScriptCore/jit/ICStats.h</a></li>
<li><a href="#trunkSourceJavaScriptCorejsccpp">trunk/Source/JavaScriptCore/jsc.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeJSLockcpp">trunk/Source/JavaScriptCore/runtime/JSLock.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeJSLockh">trunk/Source/JavaScriptCore/runtime/JSLock.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeSamplingProfilercpp">trunk/Source/JavaScriptCore/runtime/SamplingProfiler.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeSamplingProfilerh">trunk/Source/JavaScriptCore/runtime/SamplingProfiler.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeVMh">trunk/Source/JavaScriptCore/runtime/VM.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeVMTrapscpp">trunk/Source/JavaScriptCore/runtime/VMTraps.cpp</a></li>
<li><a href="#trunkSourceWTFChangeLog">trunk/Source/WTF/ChangeLog</a></li>
<li><a href="#trunkSourceWTFWTFxcodeprojprojectpbxproj">trunk/Source/WTF/WTF.xcodeproj/project.pbxproj</a></li>
<li><a href="#trunkSourceWTFbenchmarksConditionSpeedTestcpp">trunk/Source/WTF/benchmarks/ConditionSpeedTest.cpp</a></li>
<li><a href="#trunkSourceWTFbenchmarksLockFairnessTestcpp">trunk/Source/WTF/benchmarks/LockFairnessTest.cpp</a></li>
<li><a href="#trunkSourceWTFbenchmarksLockSpeedTestcpp">trunk/Source/WTF/benchmarks/LockSpeedTest.cpp</a></li>
<li><a href="#trunkSourceWTFwtfAutomaticThreadcpp">trunk/Source/WTF/wtf/AutomaticThread.cpp</a></li>
<li><a href="#trunkSourceWTFwtfCMakeListstxt">trunk/Source/WTF/wtf/CMakeLists.txt</a></li>
<li><a href="#trunkSourceWTFwtfMainThreadh">trunk/Source/WTF/wtf/MainThread.h</a></li>
<li><a href="#trunkSourceWTFwtfMemoryPressureHandlerh">trunk/Source/WTF/wtf/MemoryPressureHandler.h</a></li>
<li><a href="#trunkSourceWTFwtfParallelJobsGenericcpp">trunk/Source/WTF/wtf/ParallelJobsGeneric.cpp</a></li>
<li><a href="#trunkSourceWTFwtfParallelJobsGenerich">trunk/Source/WTF/wtf/ParallelJobsGeneric.h</a></li>
<li><a href="#trunkSourceWTFwtfParkingLotcpp">trunk/Source/WTF/wtf/ParkingLot.cpp</a></li>
<li><a href="#trunkSourceWTFwtfParkingLoth">trunk/Source/WTF/wtf/ParkingLot.h</a></li>
<li><a href="#trunkSourceWTFwtfRefPtrh">trunk/Source/WTF/wtf/RefPtr.h</a></li>
<li><a href="#trunkSourceWTFwtfThreadFunctionInvocationh">trunk/Source/WTF/wtf/ThreadFunctionInvocation.h</a></li>
<li><a href="#trunkSourceWTFwtfThreadSpecifich">trunk/Source/WTF/wtf/ThreadSpecific.h</a></li>
<li><a href="#trunkSourceWTFwtfThreadingcpp">trunk/Source/WTF/wtf/Threading.cpp</a></li>
<li><a href="#trunkSourceWTFwtfThreadingh">trunk/Source/WTF/wtf/Threading.h</a></li>
<li><a href="#trunkSourceWTFwtfThreadingPthreadscpp">trunk/Source/WTF/wtf/ThreadingPthreads.cpp</a></li>
<li><a href="#trunkSourceWTFwtfThreadingWincpp">trunk/Source/WTF/wtf/ThreadingWin.cpp</a></li>
<li><a href="#trunkSourceWTFwtfWorkQueuecpp">trunk/Source/WTF/wtf/WorkQueue.cpp</a></li>
<li><a href="#trunkSourceWTFwtfWorkQueueh">trunk/Source/WTF/wtf/WorkQueue.h</a></li>
<li><a href="#trunkSourceWTFwtfcocoaWorkQueueCocoacpp">trunk/Source/WTF/wtf/cocoa/WorkQueueCocoa.cpp</a></li>
<li><a href="#trunkSourceWTFwtfgenericWorkQueueGenericcpp">trunk/Source/WTF/wtf/generic/WorkQueueGeneric.cpp</a></li>
<li><a href="#trunkSourceWTFwtflinuxMemoryPressureHandlerLinuxcpp">trunk/Source/WTF/wtf/linux/MemoryPressureHandlerLinux.cpp</a></li>
<li><a href="#trunkSourceWTFwtfwinMainThreadWincpp">trunk/Source/WTF/wtf/win/MainThreadWin.cpp</a></li>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreModulesindexeddbserverIDBServercpp">trunk/Source/WebCore/Modules/indexeddb/server/IDBServer.cpp</a></li>
<li><a href="#trunkSourceWebCoreModulesindexeddbserverIDBServerh">trunk/Source/WebCore/Modules/indexeddb/server/IDBServer.h</a></li>
<li><a href="#trunkSourceWebCoreModuleswebaudioAsyncAudioDecodercpp">trunk/Source/WebCore/Modules/webaudio/AsyncAudioDecoder.cpp</a></li>
<li><a href="#trunkSourceWebCoreModuleswebaudioAsyncAudioDecoderh">trunk/Source/WebCore/Modules/webaudio/AsyncAudioDecoder.h</a></li>
<li><a href="#trunkSourceWebCoreModuleswebaudioOfflineAudioDestinationNodecpp">trunk/Source/WebCore/Modules/webaudio/OfflineAudioDestinationNode.cpp</a></li>
<li><a href="#trunkSourceWebCoreModuleswebaudioOfflineAudioDestinationNodeh">trunk/Source/WebCore/Modules/webaudio/OfflineAudioDestinationNode.h</a></li>
<li><a href="#trunkSourceWebCoreModuleswebdatabaseDatabasecpp">trunk/Source/WebCore/Modules/webdatabase/Database.cpp</a></li>
<li><a href="#trunkSourceWebCoreModuleswebdatabaseDatabaseThreadcpp">trunk/Source/WebCore/Modules/webdatabase/DatabaseThread.cpp</a></li>
<li><a href="#trunkSourceWebCoreModuleswebdatabaseDatabaseThreadh">trunk/Source/WebCore/Modules/webdatabase/DatabaseThread.h</a></li>
<li><a href="#trunkSourceWebCorebindingsjsGCControllercpp">trunk/Source/WebCore/bindings/js/GCController.cpp</a></li>
<li><a href="#trunkSourceWebCorefileapiAsyncFileStreamcpp">trunk/Source/WebCore/fileapi/AsyncFileStream.cpp</a></li>
<li><a href="#trunkSourceWebCoreloadericonIconDatabasecpp">trunk/Source/WebCore/loader/icon/IconDatabase.cpp</a></li>
<li><a href="#trunkSourceWebCoreloadericonIconDatabaseh">trunk/Source/WebCore/loader/icon/IconDatabase.h</a></li>
<li><a href="#trunkSourceWebCorepageResourceUsageThreadcpp">trunk/Source/WebCore/page/ResourceUsageThread.cpp</a></li>
<li><a href="#trunkSourceWebCorepageResourceUsageThreadh">trunk/Source/WebCore/page/ResourceUsageThread.h</a></li>
<li><a href="#trunkSourceWebCorepagescrollingScrollingThreadcpp">trunk/Source/WebCore/page/scrolling/ScrollingThread.cpp</a></li>
<li><a href="#trunkSourceWebCorepagescrollingScrollingThreadh">trunk/Source/WebCore/page/scrolling/ScrollingThread.h</a></li>
<li><a href="#trunkSourceWebCoreplatformaudioHRTFDatabaseLoadercpp">trunk/Source/WebCore/platform/audio/HRTFDatabaseLoader.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformaudioHRTFDatabaseLoaderh">trunk/Source/WebCore/platform/audio/HRTFDatabaseLoader.h</a></li>
<li><a href="#trunkSourceWebCoreplatformaudioReverbConvolvercpp">trunk/Source/WebCore/platform/audio/ReverbConvolver.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformaudioReverbConvolverh">trunk/Source/WebCore/platform/audio/ReverbConvolver.h</a></li>
<li><a href="#trunkSourceWebCoreplatformaudiogstreamerAudioFileReaderGStreamercpp">trunk/Source/WebCore/platform/audio/gstreamer/AudioFileReaderGStreamer.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsgstreamerWebKitWebSourceGStreamercpp">trunk/Source/WebCore/platform/graphics/gstreamer/WebKitWebSourceGStreamer.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformnetworkcfLoaderRunLoopCFcpp">trunk/Source/WebCore/platform/network/cf/LoaderRunLoopCF.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformnetworkcurlCurlDownloadcpp">trunk/Source/WebCore/platform/network/curl/CurlDownload.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformnetworkcurlCurlDownloadh">trunk/Source/WebCore/platform/network/curl/CurlDownload.h</a></li>
<li><a href="#trunkSourceWebCoreplatformnetworkcurlSocketStreamHandleImplh">trunk/Source/WebCore/platform/network/curl/SocketStreamHandleImpl.h</a></li>
<li><a href="#trunkSourceWebCoreplatformnetworkcurlSocketStreamHandleImplCurlcpp">trunk/Source/WebCore/platform/network/curl/SocketStreamHandleImplCurl.cpp</a></li>
<li><a href="#trunkSourceWebCoreworkersWorkerThreadcpp">trunk/Source/WebCore/workers/WorkerThread.cpp</a></li>
<li><a href="#trunkSourceWebCoreworkersWorkerThreadh">trunk/Source/WebCore/workers/WorkerThread.h</a></li>
<li><a href="#trunkSourceWebKitChangeLog">trunk/Source/WebKit/ChangeLog</a></li>
<li><a href="#trunkSourceWebKitStorageStorageThreadcpp">trunk/Source/WebKit/Storage/StorageThread.cpp</a></li>
<li><a href="#trunkSourceWebKitStorageStorageThreadh">trunk/Source/WebKit/Storage/StorageThread.h</a></li>
<li><a href="#trunkSourceWebKit2ChangeLog">trunk/Source/WebKit2/ChangeLog</a></li>
<li><a href="#trunkSourceWebKit2NetworkProcessNetworkProcesscpp">trunk/Source/WebKit2/NetworkProcess/NetworkProcess.cpp</a></li>
<li><a href="#trunkSourceWebKit2NetworkProcesscacheNetworkCacheIOChannelSoupcpp">trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheIOChannelSoup.cpp</a></li>
<li><a href="#trunkSourceWebKit2PlatformIPCConnectioncpp">trunk/Source/WebKit2/Platform/IPC/Connection.cpp</a></li>
<li><a href="#trunkSourceWebKit2SharedEntryPointUtilitiesmacXPCServiceXPCServiceEntryPointh">trunk/Source/WebKit2/Shared/EntryPointUtilities/mac/XPCService/XPCServiceEntryPoint.h</a></li>
<li><a href="#trunkSourceWebKit2UIProcesslinuxMemoryPressureMonitorcpp">trunk/Source/WebKit2/UIProcess/linux/MemoryPressureMonitor.cpp</a></li>
<li><a href="#trunkSourceWebKit2WebProcessWebProcesscpp">trunk/Source/WebKit2/WebProcess/WebProcess.cpp</a></li>
<li><a href="#trunkToolsChangeLog">trunk/Tools/ChangeLog</a></li>
<li><a href="#trunkToolsDumpRenderTreeJavaScriptThreadingcpp">trunk/Tools/DumpRenderTree/JavaScriptThreading.cpp</a></li>
<li><a href="#trunkToolsDumpRenderTreemacDumpRenderTreemm">trunk/Tools/DumpRenderTree/mac/DumpRenderTree.mm</a></li>
<li><a href="#trunkToolsTestWebKitAPITestsWTFConditioncpp">trunk/Tools/TestWebKitAPI/Tests/WTF/Condition.cpp</a></li>
<li><a href="#trunkToolsTestWebKitAPITestsWTFLockcpp">trunk/Tools/TestWebKitAPI/Tests/WTF/Lock.cpp</a></li>
<li><a href="#trunkToolsTestWebKitAPITestsWTFParkingLotcpp">trunk/Tools/TestWebKitAPI/Tests/WTF/ParkingLot.cpp</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkSourceWTFwtfPlatformRegistersh">trunk/Source/WTF/wtf/PlatformRegisters.h</a></li>
<li><a href="#trunkSourceWTFwtfThreadHoldercpp">trunk/Source/WTF/wtf/ThreadHolder.cpp</a></li>
<li><a href="#trunkSourceWTFwtfThreadHolderh">trunk/Source/WTF/wtf/ThreadHolder.h</a></li>
<li><a href="#trunkSourceWTFwtfThreadHolderPthreadscpp">trunk/Source/WTF/wtf/ThreadHolderPthreads.cpp</a></li>
<li><a href="#trunkSourceWTFwtfThreadHolderWincpp">trunk/Source/WTF/wtf/ThreadHolderWin.cpp</a></li>
</ul>

<h3>Removed Paths</h3>
<ul>
<li><a href="#trunkSourceJavaScriptCoreruntimePlatformThreadh">trunk/Source/JavaScriptCore/runtime/PlatformThread.h</a></li>
<li><a href="#trunkSourceWTFwtfThreadIdentifierDataPthreadscpp">trunk/Source/WTF/wtf/ThreadIdentifierDataPthreads.cpp</a></li>
<li><a href="#trunkSourceWTFwtfThreadIdentifierDataPthreadsh">trunk/Source/WTF/wtf/ThreadIdentifierDataPthreads.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceJavaScriptCoreAPItestsCompareAndSwapTestcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/API/tests/CompareAndSwapTest.cpp (215264 => 215265)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/API/tests/CompareAndSwapTest.cpp        2017-04-12 10:14:30 UTC (rev 215264)
+++ trunk/Source/JavaScriptCore/API/tests/CompareAndSwapTest.cpp        2017-04-12 12:08:29 UTC (rev 215265)
</span><span class="lines">@@ -96,7 +96,7 @@
</span><span class="cx"> {
</span><span class="cx">     Bitmap bitmap;
</span><span class="cx">     const int numThreads = 5;
</span><del>-    ThreadIdentifier threadIDs[numThreads];
</del><ins>+    RefPtr&lt;Thread&gt; threads[numThreads];
</ins><span class="cx">     Data data[numThreads];
</span><span class="cx"> 
</span><span class="cx">     WTF::initializeThreading();
</span><span class="lines">@@ -107,12 +107,12 @@
</span><span class="cx">         data[i].id = i;
</span><span class="cx">         data[i].numThreads = numThreads;
</span><span class="cx">         std::function&lt;void()&gt; threadFunc = std::bind(setBitThreadFunc, &amp;data[i]);
</span><del>-        threadIDs[i] = createThread(&quot;setBitThreadFunc&quot;, threadFunc);
</del><ins>+        threads[i] = Thread::create(&quot;setBitThreadFunc&quot;, threadFunc);
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     printf(&quot;Waiting for %d threads to join\n&quot;, numThreads);
</span><span class="cx">     for (int i = 0; i &lt; numThreads; i++)
</span><del>-        waitForThreadCompletion(threadIDs[i]);
</del><ins>+        threads[i]-&gt;waitForCompletion();
</ins><span class="cx"> 
</span><span class="cx">     printf(&quot;PASS: CompareAndSwap test completed without a hang\n&quot;);
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (215264 => 215265)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2017-04-12 10:14:30 UTC (rev 215264)
+++ trunk/Source/JavaScriptCore/ChangeLog        2017-04-12 12:08:29 UTC (rev 215265)
</span><span class="lines">@@ -1,3 +1,96 @@
</span><ins>+2017-04-12  Yusuke Suzuki  &lt;utatane.tea@gmail.com&gt;
+
+        [WTF] Introduce Thread class and use RefPtr&lt;Thread&gt; and align Windows Threading implementation semantics to Pthread one
+        https://bugs.webkit.org/show_bug.cgi?id=170502
+
+        Reviewed by Mark Lam.
+
+        * API/tests/CompareAndSwapTest.cpp:
+        (testCompareAndSwap):
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * b3/air/testair.cpp:
+        * b3/testb3.cpp:
+        (JSC::B3::run):
+        * bytecode/SuperSampler.cpp:
+        (JSC::initializeSuperSampler):
+        * dfg/DFGWorklist.cpp:
+        * disassembler/Disassembler.cpp:
+        * heap/Heap.cpp:
+        (JSC::Heap::lastChanceToFinalize):
+        (JSC::Heap::notifyIsSafeToCollect):
+        * heap/Heap.h:
+        * heap/MachineStackMarker.cpp:
+        (JSC::MachineThreads::~MachineThreads):
+        (JSC::MachineThreads::addCurrentThread):
+        (JSC::MachineThreads::removeThread):
+        (JSC::MachineThreads::removeThreadIfFound):
+        (JSC::MachineThreads::MachineThread::MachineThread):
+        (JSC::MachineThreads::MachineThread::getRegisters):
+        (JSC::MachineThreads::MachineThread::Registers::stackPointer):
+        (JSC::MachineThreads::MachineThread::Registers::framePointer):
+        (JSC::MachineThreads::MachineThread::Registers::instructionPointer):
+        (JSC::MachineThreads::MachineThread::Registers::llintPC):
+        (JSC::MachineThreads::MachineThread::captureStack):
+        (JSC::MachineThreads::tryCopyOtherThreadStack):
+        (JSC::MachineThreads::tryCopyOtherThreadStacks):
+        (pthreadSignalHandlerSuspendResume): Deleted.
+        (JSC::threadData): Deleted.
+        (JSC::MachineThreads::Thread::Thread): Deleted.
+        (JSC::MachineThreads::Thread::createForCurrentThread): Deleted.
+        (JSC::MachineThreads::Thread::operator==): Deleted.
+        (JSC::MachineThreads::machineThreadForCurrentThread): Deleted.
+        (JSC::MachineThreads::ThreadData::ThreadData): Deleted.
+        (JSC::MachineThreads::ThreadData::~ThreadData): Deleted.
+        (JSC::MachineThreads::ThreadData::suspend): Deleted.
+        (JSC::MachineThreads::ThreadData::resume): Deleted.
+        (JSC::MachineThreads::ThreadData::getRegisters): Deleted.
+        (JSC::MachineThreads::ThreadData::Registers::stackPointer): Deleted.
+        (JSC::MachineThreads::ThreadData::Registers::framePointer): Deleted.
+        (JSC::MachineThreads::ThreadData::Registers::instructionPointer): Deleted.
+        (JSC::MachineThreads::ThreadData::Registers::llintPC): Deleted.
+        (JSC::MachineThreads::ThreadData::freeRegisters): Deleted.
+        (JSC::MachineThreads::ThreadData::captureStack): Deleted.
+        * heap/MachineStackMarker.h:
+        (JSC::MachineThreads::MachineThread::suspend):
+        (JSC::MachineThreads::MachineThread::resume):
+        (JSC::MachineThreads::MachineThread::threadID):
+        (JSC::MachineThreads::MachineThread::stackBase):
+        (JSC::MachineThreads::MachineThread::stackEnd):
+        (JSC::MachineThreads::threadsListHead):
+        (JSC::MachineThreads::Thread::operator!=): Deleted.
+        (JSC::MachineThreads::Thread::suspend): Deleted.
+        (JSC::MachineThreads::Thread::resume): Deleted.
+        (JSC::MachineThreads::Thread::getRegisters): Deleted.
+        (JSC::MachineThreads::Thread::freeRegisters): Deleted.
+        (JSC::MachineThreads::Thread::captureStack): Deleted.
+        (JSC::MachineThreads::Thread::platformThread): Deleted.
+        (JSC::MachineThreads::Thread::stackBase): Deleted.
+        (JSC::MachineThreads::Thread::stackEnd): Deleted.
+        * jit/ICStats.cpp:
+        (JSC::ICStats::ICStats):
+        (JSC::ICStats::~ICStats):
+        * jit/ICStats.h:
+        * jsc.cpp:
+        (functionDollarAgentStart):
+        (startTimeoutThreadIfNeeded):
+        * runtime/JSLock.cpp:
+        (JSC::JSLock::lock):
+        * runtime/JSLock.h:
+        (JSC::JSLock::ownerThread):
+        (JSC::JSLock::currentThreadIsHoldingLock):
+        * runtime/SamplingProfiler.cpp:
+        (JSC::FrameWalker::isValidFramePointer):
+        (JSC::SamplingProfiler::SamplingProfiler):
+        (JSC::SamplingProfiler::createThreadIfNecessary):
+        (JSC::SamplingProfiler::takeSample):
+        * runtime/SamplingProfiler.h:
+        * runtime/VM.h:
+        (JSC::VM::ownerThread):
+        * runtime/VMTraps.cpp:
+        (JSC::findActiveVMAndStackBounds):
+        (JSC::VMTraps::SignalSender::send):
+        (JSC::VMTraps::fireTrap):
+
</ins><span class="cx"> 2017-04-11  Dean Jackson  &lt;dino@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Disable outdated WritableStream API
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreJavaScriptCorexcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj (215264 => 215265)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj        2017-04-12 10:14:30 UTC (rev 215264)
+++ trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj        2017-04-12 12:08:29 UTC (rev 215265)
</span><span class="lines">@@ -2471,7 +2471,6 @@
</span><span class="cx">                 FED287B215EC9A5700DA8161 /* LLIntOpcode.h in Headers */ = {isa = PBXBuildFile; fileRef = FED287B115EC9A5700DA8161 /* LLIntOpcode.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 FED94F2E171E3E2300BE77A4 /* Watchdog.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FED94F2B171E3E2300BE77A4 /* Watchdog.cpp */; };
</span><span class="cx">                 FED94F2F171E3E2300BE77A4 /* Watchdog.h in Headers */ = {isa = PBXBuildFile; fileRef = FED94F2C171E3E2300BE77A4 /* Watchdog.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><del>-                FEE43FCE1E6641710077D6D1 /* PlatformThread.h in Headers */ = {isa = PBXBuildFile; fileRef = FEE43FCD1E6641400077D6D1 /* PlatformThread.h */; settings = {ATTRIBUTES = (Private, ); }; };
</del><span class="cx">                 FEF040511AAE662D00BD28B0 /* CompareAndSwapTest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FEF040501AAE662D00BD28B0 /* CompareAndSwapTest.cpp */; };
</span><span class="cx">                 FEFD6FC61D5E7992008F2F0B /* JSStringInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = FEFD6FC51D5E7970008F2F0B /* JSStringInlines.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx"> /* End PBXBuildFile section */
</span><span class="lines">@@ -5101,7 +5100,6 @@
</span><span class="cx">                 FED94F2C171E3E2300BE77A4 /* Watchdog.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Watchdog.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 FEDA50D41B97F442009A3B4F /* PingPongStackOverflowTest.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = PingPongStackOverflowTest.cpp; path = API/tests/PingPongStackOverflowTest.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 FEDA50D51B97F4D9009A3B4F /* PingPongStackOverflowTest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PingPongStackOverflowTest.h; path = API/tests/PingPongStackOverflowTest.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><del>-                FEE43FCD1E6641400077D6D1 /* PlatformThread.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PlatformThread.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</del><span class="cx">                 FEF040501AAE662D00BD28B0 /* CompareAndSwapTest.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CompareAndSwapTest.cpp; path = API/tests/CompareAndSwapTest.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 FEF040521AAEC4ED00BD28B0 /* CompareAndSwapTest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CompareAndSwapTest.h; path = API/tests/CompareAndSwapTest.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 FEFD6FC51D5E7970008F2F0B /* JSStringInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSStringInlines.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -6866,7 +6864,6 @@
</span><span class="cx">                                 F692A8780255597D01FF60F7 /* Operations.h */,
</span><span class="cx">                                 0FE228EA1436AB2300196C48 /* Options.cpp */,
</span><span class="cx">                                 0FE228EB1436AB2300196C48 /* Options.h */,
</span><del>-                                FEE43FCD1E6641400077D6D1 /* PlatformThread.h */,
</del><span class="cx">                                 868916A9155F285400CB2B9A /* PrivateName.h */,
</span><span class="cx">                                 147341DF1DC2CE9600AA29BA /* ProgramExecutable.cpp */,
</span><span class="cx">                                 147341D31DC02E6D00AA29BA /* ProgramExecutable.h */,
</span><span class="lines">@@ -9348,7 +9345,6 @@
</span><span class="cx">                                 0F4A38FA1C8E13DF00190318 /* SuperSampler.h in Headers */,
</span><span class="cx">                                 705B41AC1A6E501E00716757 /* Symbol.h in Headers */,
</span><span class="cx">                                 705B41AE1A6E501E00716757 /* SymbolConstructor.h in Headers */,
</span><del>-                                FEE43FCE1E6641710077D6D1 /* PlatformThread.h in Headers */,
</del><span class="cx">                                 996B73271BDA08EF00331B84 /* SymbolConstructor.lut.h in Headers */,
</span><span class="cx">                                 705B41B01A6E501E00716757 /* SymbolObject.h in Headers */,
</span><span class="cx">                                 705B41B21A6E501E00716757 /* SymbolPrototype.h in Headers */,
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3airtestaircpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/air/testair.cpp (215264 => 215265)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/air/testair.cpp        2017-04-12 10:14:30 UTC (rev 215264)
+++ trunk/Source/JavaScriptCore/b3/air/testair.cpp        2017-04-12 12:08:29 UTC (rev 215265)
</span><span class="lines">@@ -1913,10 +1913,10 @@
</span><span class="cx"> 
</span><span class="cx">     Lock lock;
</span><span class="cx"> 
</span><del>-    Vector&lt;ThreadIdentifier&gt; threads;
</del><ins>+    Vector&lt;RefPtr&lt;Thread&gt;&gt; threads;
</ins><span class="cx">     for (unsigned i = filter ? 1 : WTF::numberOfProcessorCores(); i--;) {
</span><span class="cx">         threads.append(
</span><del>-            createThread(
</del><ins>+            Thread::create(
</ins><span class="cx">                 &quot;testb3 thread&quot;,
</span><span class="cx">                 [&amp;] () {
</span><span class="cx">                     for (;;) {
</span><span class="lines">@@ -1933,8 +1933,8 @@
</span><span class="cx">                 }));
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    for (ThreadIdentifier thread : threads)
-        waitForThreadCompletion(thread);
</del><ins>+    for (RefPtr&lt;Thread&gt; thread : threads)
+        thread-&gt;waitForCompletion();
</ins><span class="cx">     crashLock.lock();
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreb3testb3cpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/b3/testb3.cpp (215264 => 215265)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/b3/testb3.cpp        2017-04-12 10:14:30 UTC (rev 215264)
+++ trunk/Source/JavaScriptCore/b3/testb3.cpp        2017-04-12 12:08:29 UTC (rev 215265)
</span><span class="lines">@@ -16850,10 +16850,10 @@
</span><span class="cx"> 
</span><span class="cx">     Lock lock;
</span><span class="cx"> 
</span><del>-    Vector&lt;ThreadIdentifier&gt; threads;
</del><ins>+    Vector&lt;RefPtr&lt;Thread&gt;&gt; threads;
</ins><span class="cx">     for (unsigned i = filter ? 1 : WTF::numberOfProcessorCores(); i--;) {
</span><span class="cx">         threads.append(
</span><del>-            createThread(
</del><ins>+            Thread::create(
</ins><span class="cx">                 &quot;testb3 thread&quot;,
</span><span class="cx">                 [&amp;] () {
</span><span class="cx">                     for (;;) {
</span><span class="lines">@@ -16870,8 +16870,8 @@
</span><span class="cx">                 }));
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    for (ThreadIdentifier thread : threads)
-        waitForThreadCompletion(thread);
</del><ins>+    for (RefPtr&lt;Thread&gt; thread : threads)
+        thread-&gt;waitForCompletion();
</ins><span class="cx">     crashLock.lock();
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorebytecodeSuperSamplercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/bytecode/SuperSampler.cpp (215264 => 215265)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/bytecode/SuperSampler.cpp        2017-04-12 10:14:30 UTC (rev 215264)
+++ trunk/Source/JavaScriptCore/bytecode/SuperSampler.cpp        2017-04-12 12:08:29 UTC (rev 215265)
</span><span class="lines">@@ -46,7 +46,7 @@
</span><span class="cx">     if (!Options::useSuperSampler())
</span><span class="cx">         return;
</span><span class="cx"> 
</span><del>-    createThread(
</del><ins>+    Thread::create(
</ins><span class="cx">         &quot;JSC Super Sampler&quot;,
</span><span class="cx">         [] () {
</span><span class="cx">             const int sleepQuantum = 10;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGWorklistcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGWorklist.cpp (215264 => 215265)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGWorklist.cpp        2017-04-12 10:14:30 UTC (rev 215264)
+++ trunk/Source/JavaScriptCore/dfg/DFGWorklist.cpp        2017-04-12 12:08:29 UTC (rev 215265)
</span><span class="lines">@@ -144,7 +144,7 @@
</span><span class="cx">             dataLog(m_worklist, &quot;: Thread started\n&quot;);
</span><span class="cx">         
</span><span class="cx">         if (m_relativePriority)
</span><del>-            changeThreadPriority(currentThread(), m_relativePriority);
</del><ins>+            Thread::current().changePriority(m_relativePriority);
</ins><span class="cx">         
</span><span class="cx">         m_compilationScope = std::make_unique&lt;CompilationScope&gt;();
</span><span class="cx">         m_longLivedState = std::make_unique&lt;LongLivedState&gt;();
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredisassemblerDisassemblercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/disassembler/Disassembler.cpp (215264 => 215265)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/disassembler/Disassembler.cpp        2017-04-12 10:14:30 UTC (rev 215264)
+++ trunk/Source/JavaScriptCore/disassembler/Disassembler.cpp        2017-04-12 12:08:29 UTC (rev 215265)
</span><span class="lines">@@ -73,7 +73,7 @@
</span><span class="cx"> public:
</span><span class="cx">     AsynchronousDisassembler()
</span><span class="cx">     {
</span><del>-        createThread(&quot;Asynchronous Disassembler&quot;, [&amp;] () { run(); });
</del><ins>+        Thread::create(&quot;Asynchronous Disassembler&quot;, [&amp;] () { run(); });
</ins><span class="cx">     }
</span><span class="cx">     
</span><span class="cx">     void enqueue(std::unique_ptr&lt;DisassemblyTask&gt; task)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreheapHeapcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/heap/Heap.cpp (215264 => 215265)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/heap/Heap.cpp        2017-04-12 10:14:30 UTC (rev 215264)
+++ trunk/Source/JavaScriptCore/heap/Heap.cpp        2017-04-12 12:08:29 UTC (rev 215265)
</span><span class="lines">@@ -349,7 +349,7 @@
</span><span class="cx">             m_shouldStopCollectingContinuously = true;
</span><span class="cx">             m_collectContinuouslyCondition.notifyOne();
</span><span class="cx">         }
</span><del>-        waitForThreadCompletion(m_collectContinuouslyThread);
</del><ins>+        m_collectContinuouslyThread-&gt;waitForCompletion();
</ins><span class="cx">     }
</span><span class="cx">     
</span><span class="cx">     if (Options::logGC())
</span><span class="lines">@@ -2681,7 +2681,7 @@
</span><span class="cx">     m_isSafeToCollect = true;
</span><span class="cx">     
</span><span class="cx">     if (Options::collectContinuously()) {
</span><del>-        m_collectContinuouslyThread = createThread(
</del><ins>+        m_collectContinuouslyThread = WTF::Thread::create(
</ins><span class="cx">             &quot;JSC DEBUG Continuous GC&quot;,
</span><span class="cx">             [this] () {
</span><span class="cx">                 MonotonicTime initialTime = MonotonicTime::now();
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreheapHeaph"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/heap/Heap.h (215264 => 215265)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/heap/Heap.h        2017-04-12 10:14:30 UTC (rev 215264)
+++ trunk/Source/JavaScriptCore/heap/Heap.h        2017-04-12 12:08:29 UTC (rev 215265)
</span><span class="lines">@@ -49,6 +49,7 @@
</span><span class="cx"> #include &lt;wtf/HashCountedSet.h&gt;
</span><span class="cx"> #include &lt;wtf/HashSet.h&gt;
</span><span class="cx"> #include &lt;wtf/ParallelHelperPool.h&gt;
</span><ins>+#include &lt;wtf/Threading.h&gt;
</ins><span class="cx"> 
</span><span class="cx"> namespace JSC {
</span><span class="cx"> 
</span><span class="lines">@@ -666,7 +667,7 @@
</span><span class="cx">     Lock m_collectContinuouslyLock;
</span><span class="cx">     Condition m_collectContinuouslyCondition;
</span><span class="cx">     bool m_shouldStopCollectingContinuously { false };
</span><del>-    ThreadIdentifier m_collectContinuouslyThread { 0 };
</del><ins>+    RefPtr&lt;WTF::Thread&gt; m_collectContinuouslyThread { nullptr };
</ins><span class="cx">     
</span><span class="cx">     MonotonicTime m_lastGCStartTime;
</span><span class="cx">     MonotonicTime m_lastGCEndTime;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreheapMachineStackMarkercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/heap/MachineStackMarker.cpp (215264 => 215265)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/heap/MachineStackMarker.cpp        2017-04-12 10:14:30 UTC (rev 215264)
+++ trunk/Source/JavaScriptCore/heap/MachineStackMarker.cpp        2017-04-12 12:08:29 UTC (rev 215265)
</span><span class="lines">@@ -36,92 +36,10 @@
</span><span class="cx"> #include &lt;wtf/NeverDestroyed.h&gt;
</span><span class="cx"> #include &lt;wtf/StdLibExtras.h&gt;
</span><span class="cx"> 
</span><del>-#if OS(DARWIN)
-
-#include &lt;mach/mach_init.h&gt;
-#include &lt;mach/mach_port.h&gt;
-#include &lt;mach/task.h&gt;
-#include &lt;mach/thread_act.h&gt;
-#include &lt;mach/vm_map.h&gt;
-
-#elif OS(WINDOWS)
-
-#include &lt;windows.h&gt;
-#include &lt;malloc.h&gt;
-
-#elif OS(UNIX)
-
-#include &lt;sys/mman.h&gt;
-#include &lt;unistd.h&gt;
-
-#if OS(SOLARIS)
-#include &lt;thread.h&gt;
-#else
-#include &lt;pthread.h&gt;
-#endif
-
-#if HAVE(PTHREAD_NP_H)
-#include &lt;pthread_np.h&gt;
-#endif
-
-#if USE(PTHREADS) &amp;&amp; !OS(WINDOWS) &amp;&amp; !OS(DARWIN)
-#include &lt;signal.h&gt;
-
-// We use SIGUSR2 to suspend and resume machine threads in JavaScriptCore.
-static const int SigThreadSuspendResume = SIGUSR2;
-static StaticLock globalSignalLock;
-thread_local static std::atomic&lt;JSC::MachineThreads::ThreadData*&gt; threadLocalCurrentThread { nullptr };
-
-static void pthreadSignalHandlerSuspendResume(int, siginfo_t*, void* ucontext)
-{
-    // Touching thread local atomic types from signal handlers is allowed.
-    JSC::MachineThreads::ThreadData* threadData = threadLocalCurrentThread.load();
-
-    if (threadData-&gt;suspended.load(std::memory_order_acquire)) {
-        // This is signal handler invocation that is intended to be used to resume sigsuspend.
-        // So this handler invocation itself should not process.
-        //
-        // When signal comes, first, the system calls signal handler. And later, sigsuspend will be resumed. Signal handler invocation always precedes.
-        // So, the problem never happens that suspended.store(true, ...) will be executed before the handler is called.
-        // http://pubs.opengroup.org/onlinepubs/009695399/functions/sigsuspend.html
-        return;
-    }
-
-    ucontext_t* userContext = static_cast&lt;ucontext_t*&gt;(ucontext);
-#if CPU(PPC)
-    threadData-&gt;suspendedMachineContext = *userContext-&gt;uc_mcontext.uc_regs;
-#else
-    threadData-&gt;suspendedMachineContext = userContext-&gt;uc_mcontext;
-#endif
-
-    // Allow suspend caller to see that this thread is suspended.
-    // sem_post is async-signal-safe function. It means that we can call this from a signal handler.
-    // http://pubs.opengroup.org/onlinepubs/009695399/functions/xsh_chap02_04.html#tag_02_04_03
-    //
-    // And sem_post emits memory barrier that ensures that suspendedMachineContext is correctly saved.
-    // http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap04.html#tag_04_11
-    sem_post(&amp;threadData-&gt;semaphoreForSuspendResume);
-
-    // Reaching here, SigThreadSuspendResume is blocked in this handler (this is configured by sigaction's sa_mask).
-    // So before calling sigsuspend, SigThreadSuspendResume to this thread is deferred. This ensures that the handler is not executed recursively.
-    sigset_t blockedSignalSet;
-    sigfillset(&amp;blockedSignalSet);
-    sigdelset(&amp;blockedSignalSet, SigThreadSuspendResume);
-    sigsuspend(&amp;blockedSignalSet);
-
-    // Allow resume caller to see that this thread is resumed.
-    sem_post(&amp;threadData-&gt;semaphoreForSuspendResume);
-}
-#endif // USE(PTHREADS) &amp;&amp; !OS(WINDOWS) &amp;&amp; !OS(DARWIN)
-
-#endif
-
</del><span class="cx"> using namespace WTF;
</span><span class="cx"> 
</span><span class="cx"> namespace JSC {
</span><span class="cx"> 
</span><del>-using Thread = MachineThreads::Thread;
-
</del><span class="cx"> class ActiveMachineThreadsManager;
</span><span class="cx"> static ActiveMachineThreadsManager&amp; activeMachineThreadsManager();
</span><span class="cx"> 
</span><span class="lines">@@ -194,41 +112,13 @@
</span><span class="cx">     threadSpecificKeyDelete(m_threadSpecificForMachineThreads);
</span><span class="cx"> 
</span><span class="cx">     LockHolder registeredThreadsLock(m_registeredThreadsMutex);
</span><del>-    for (Thread* t = m_registeredThreads; t;) {
-        Thread* next = t-&gt;next;
</del><ins>+    for (MachineThread* t = m_registeredThreads; t;) {
+        MachineThread* next = t-&gt;next;
</ins><span class="cx">         delete t;
</span><span class="cx">         t = next;
</span><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-static MachineThreads::ThreadData* threadData()
-{
-    static NeverDestroyed&lt;ThreadSpecific&lt;MachineThreads::ThreadData, CanBeGCThread::True&gt;&gt; threadData;
-    return threadData.get();
-}
-
-MachineThreads::Thread::Thread(ThreadData* threadData)
-    : data(threadData)
-{
-    ASSERT(threadData);
-}
-
-Thread* MachineThreads::Thread::createForCurrentThread()
-{
-    return new Thread(threadData());
-}
-
-bool MachineThreads::Thread::operator==(const PlatformThread&amp; other) const
-{
-#if OS(DARWIN) || OS(WINDOWS)
-    return data-&gt;platformThread == other;
-#elif USE(PTHREADS)
-    return !!pthread_equal(data-&gt;platformThread, other);
-#else
-#error Need a way to compare threads on this platform
-#endif
-}
-
</del><span class="cx"> void MachineThreads::addCurrentThread()
</span><span class="cx"> {
</span><span class="cx">     if (threadSpecificGet(m_threadSpecificForMachineThreads)) {
</span><span class="lines">@@ -239,7 +129,7 @@
</span><span class="cx">         return;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    Thread* thread = Thread::createForCurrentThread();
</del><ins>+    MachineThread* thread = new MachineThread();
</ins><span class="cx">     threadSpecificSet(m_threadSpecificForMachineThreads, this);
</span><span class="cx"> 
</span><span class="cx">     LockHolder lock(m_registeredThreadsMutex);
</span><span class="lines">@@ -248,12 +138,12 @@
</span><span class="cx">     m_registeredThreads = thread;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-Thread* MachineThreads::machineThreadForCurrentThread()
</del><ins>+auto MachineThreads::machineThreadForCurrentThread() -&gt; MachineThread*
</ins><span class="cx"> {
</span><span class="cx">     LockHolder lock(m_registeredThreadsMutex);
</span><del>-    PlatformThread platformThread = currentPlatformThread();
-    for (Thread* thread = m_registeredThreads; thread; thread = thread-&gt;next) {
-        if (*thread == platformThread)
</del><ins>+    ThreadIdentifier id = currentThread();
+    for (MachineThread* thread = m_registeredThreads; thread; thread = thread-&gt;next) {
+        if (thread-&gt;threadID() == id)
</ins><span class="cx">             return thread;
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="lines">@@ -283,22 +173,21 @@
</span><span class="cx">             return;
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><del>-        machineThreads-&gt;removeThreadIfFound(currentPlatformThread());
</del><ins>+        machineThreads-&gt;removeThreadIfFound(currentThread());
</ins><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-template&lt;typename PlatformThread&gt;
-void MachineThreads::removeThreadIfFound(PlatformThread platformThread)
</del><ins>+void MachineThreads::removeThreadIfFound(ThreadIdentifier id)
</ins><span class="cx"> {
</span><span class="cx">     LockHolder lock(m_registeredThreadsMutex);
</span><del>-    Thread* t = m_registeredThreads;
-    if (*t == platformThread) {
</del><ins>+    MachineThread* t = m_registeredThreads;
+    if (t-&gt;threadID() == id) {
</ins><span class="cx">         m_registeredThreads = m_registeredThreads-&gt;next;
</span><span class="cx">         delete t;
</span><span class="cx">     } else {
</span><del>-        Thread* last = m_registeredThreads;
</del><ins>+        MachineThread* last = m_registeredThreads;
</ins><span class="cx">         for (t = m_registeredThreads-&gt;next; t; t = t-&gt;next) {
</span><del>-            if (*t == platformThread) {
</del><ins>+            if (t-&gt;threadID() == id) {
</ins><span class="cx">                 last-&gt;next = t-&gt;next;
</span><span class="cx">                 break;
</span><span class="cx">             }
</span><span class="lines">@@ -320,206 +209,34 @@
</span><span class="cx">     conservativeRoots.add(currentThreadState.stackTop, currentThreadState.stackOrigin, jitStubRoutines, codeBlocks);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-MachineThreads::ThreadData::ThreadData()
</del><ins>+MachineThreads::MachineThread::MachineThread()
+    : next(nullptr)
+    , m_thread(WTF::Thread::current())
</ins><span class="cx"> {
</span><span class="cx">     auto stackBounds = wtfThreadData().stack();
</span><del>-    platformThread = currentPlatformThread();
-    stackBase = stackBounds.origin();
-    stackEnd = stackBounds.end();
-
-#if OS(WINDOWS)
-    ASSERT(platformThread == GetCurrentThreadId());
-    bool isSuccessful =
-        DuplicateHandle(GetCurrentProcess(), GetCurrentThread(), GetCurrentProcess(),
-            &amp;platformThreadHandle, 0, FALSE, DUPLICATE_SAME_ACCESS);
-    RELEASE_ASSERT(isSuccessful);
-#elif USE(PTHREADS) &amp;&amp; !OS(DARWIN)
-    threadLocalCurrentThread.store(this);
-
-    // Signal handlers are process global configuration.
-    static std::once_flag initializeSignalHandler;
-    std::call_once(initializeSignalHandler, [] {
-        // Intentionally block SigThreadSuspendResume in the handler.
-        // SigThreadSuspendResume will be allowed in the handler by sigsuspend.
-        struct sigaction action;
-        sigemptyset(&amp;action.sa_mask);
-        sigaddset(&amp;action.sa_mask, SigThreadSuspendResume);
-
-        action.sa_sigaction = pthreadSignalHandlerSuspendResume;
-        action.sa_flags = SA_RESTART | SA_SIGINFO;
-        sigaction(SigThreadSuspendResume, &amp;action, 0);
-    });
-
-    sigset_t mask;
-    sigemptyset(&amp;mask);
-    sigaddset(&amp;mask, SigThreadSuspendResume);
-    pthread_sigmask(SIG_UNBLOCK, &amp;mask, 0);
-
-    sem_init(&amp;semaphoreForSuspendResume, /* Only available in this process. */ 0, /* Initial value for the semaphore. */ 0);
-#endif
</del><ins>+    m_stackBase = stackBounds.origin();
+    m_stackEnd = stackBounds.end();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-MachineThreads::ThreadData::~ThreadData()
</del><ins>+size_t MachineThreads::MachineThread::getRegisters(MachineThread::Registers&amp; registers)
</ins><span class="cx"> {
</span><del>-#if OS(WINDOWS)
-    CloseHandle(platformThreadHandle);
-#elif USE(PTHREADS) &amp;&amp; !OS(DARWIN)
-    sem_destroy(&amp;semaphoreForSuspendResume);
-#endif
</del><ins>+    WTF::PlatformRegisters&amp; regs = registers.regs;
+    return m_thread-&gt;getRegisters(regs);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-bool MachineThreads::ThreadData::suspend()
</del><ins>+void* MachineThreads::MachineThread::Registers::stackPointer() const
</ins><span class="cx"> {
</span><del>-#if OS(DARWIN)
-    kern_return_t result = thread_suspend(platformThread);
-    return result == KERN_SUCCESS;
-#elif OS(WINDOWS)
-    bool threadIsSuspended = (SuspendThread(platformThreadHandle) != (DWORD)-1);
-    ASSERT(threadIsSuspended);
-    return threadIsSuspended;
-#elif USE(PTHREADS)
-    ASSERT_WITH_MESSAGE(currentPlatformThread() != platformThread, &quot;Currently we don't support suspend the current thread itself.&quot;);
-    {
-        // During suspend, suspend or resume should not be executed from the other threads.
-        // We use global lock instead of per thread lock.
-        // Consider the following case, there are threads A and B.
-        // And A attempt to suspend B and B attempt to suspend A.
-        // A and B send signals. And later, signals are delivered to A and B.
-        // In that case, both will be suspended.
-        LockHolder lock(globalSignalLock);
-        if (!suspendCount) {
-            // Ideally, we would like to use pthread_sigqueue. It allows us to pass the argument to the signal handler.
-            // But it can be used in a few platforms, like Linux.
-            // Instead, we use Thread* stored in the thread local storage to pass it to the signal handler.
-            if (pthread_kill(platformThread, SigThreadSuspendResume) == ESRCH)
-                return false;
-            sem_wait(&amp;semaphoreForSuspendResume);
-            // Release barrier ensures that this operation is always executed after all the above processing is done.
-            suspended.store(true, std::memory_order_release);
-        }
-        ++suspendCount;
-    }
-    return true;
-#else
-#error Need a way to suspend threads on this platform
-#endif
-}
-
-void MachineThreads::ThreadData::resume()
-{
-#if OS(DARWIN)
-    thread_resume(platformThread);
-#elif OS(WINDOWS)
-    ResumeThread(platformThreadHandle);
-#elif USE(PTHREADS)
-    {
-        // During resume, suspend or resume should not be executed from the other threads.
-        LockHolder lock(globalSignalLock);
-        if (suspendCount == 1) {
-            // When allowing SigThreadSuspendResume interrupt in the signal handler by sigsuspend and SigThreadSuspendResume is actually issued,
-            // the signal handler itself will be called once again.
-            // There are several ways to distinguish the handler invocation for suspend and resume.
-            // 1. Use different signal numbers. And check the signal number in the handler.
-            // 2. Use some arguments to distinguish suspend and resume in the handler. If pthread_sigqueue can be used, we can take this.
-            // 3. Use thread local storage with atomic variables in the signal handler.
-            // In this implementaiton, we take (3). suspended flag is used to distinguish it.
-            if (pthread_kill(platformThread, SigThreadSuspendResume) == ESRCH)
-                return;
-            sem_wait(&amp;semaphoreForSuspendResume);
-            // Release barrier ensures that this operation is always executed after all the above processing is done.
-            suspended.store(false, std::memory_order_release);
-        }
-        --suspendCount;
-    }
-#else
-#error Need a way to resume threads on this platform
-#endif
-}
-
-size_t MachineThreads::ThreadData::getRegisters(ThreadData::Registers&amp; registers)
-{
-    ThreadData::Registers::PlatformRegisters&amp; regs = registers.regs;
-#if OS(DARWIN)
-#if CPU(X86)
-    unsigned user_count = sizeof(regs)/sizeof(int);
-    thread_state_flavor_t flavor = i386_THREAD_STATE;
-#elif CPU(X86_64)
-    unsigned user_count = x86_THREAD_STATE64_COUNT;
-    thread_state_flavor_t flavor = x86_THREAD_STATE64;
-#elif CPU(PPC) 
-    unsigned user_count = PPC_THREAD_STATE_COUNT;
-    thread_state_flavor_t flavor = PPC_THREAD_STATE;
-#elif CPU(PPC64)
-    unsigned user_count = PPC_THREAD_STATE64_COUNT;
-    thread_state_flavor_t flavor = PPC_THREAD_STATE64;
-#elif CPU(ARM)
-    unsigned user_count = ARM_THREAD_STATE_COUNT;
-    thread_state_flavor_t flavor = ARM_THREAD_STATE;
-#elif CPU(ARM64)
-    unsigned user_count = ARM_THREAD_STATE64_COUNT;
-    thread_state_flavor_t flavor = ARM_THREAD_STATE64;
-#else
-#error Unknown Architecture
-#endif
-
-    kern_return_t result = thread_get_state(platformThread, flavor, (thread_state_t)&amp;regs, &amp;user_count);
-    if (result != KERN_SUCCESS) {
-        WTFReportFatalError(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, 
-                            &quot;JavaScript garbage collection failed because thread_get_state returned an error (%d). This is probably the result of running inside Rosetta, which is not supported.&quot;, result);
-        CRASH();
-    }
-    return user_count * sizeof(uintptr_t);
-// end OS(DARWIN)
-
-#elif OS(WINDOWS)
-    regs.ContextFlags = CONTEXT_INTEGER | CONTEXT_CONTROL;
-    GetThreadContext(platformThreadHandle, &amp;regs);
-    return sizeof(CONTEXT);
-#elif ((OS(FREEBSD) || defined(__GLIBC__)) &amp;&amp; ENABLE(JIT))
-    regs = suspendedMachineContext;
-    return sizeof(Registers::PlatformRegisters);
-#elif USE(PTHREADS)
-    pthread_attr_init(&amp;regs.attribute);
-#if HAVE(PTHREAD_NP_H) || OS(NETBSD)
-#if !OS(OPENBSD)
-    // e.g. on FreeBSD 5.4, neundorf@kde.org
-    pthread_attr_get_np(platformThread, &amp;regs.attribute);
-#endif
-#else
-    // FIXME: this function is non-portable; other POSIX systems may have different np alternatives
-    pthread_getattr_np(platformThread, &amp;regs.attribute);
-#endif
-    return 0;
-#else
-#error Need a way to get thread registers on this platform
-#endif
-}
-
-void* MachineThreads::ThreadData::Registers::stackPointer() const
-{
</del><span class="cx"> #if OS(DARWIN) || OS(WINDOWS) || ((OS(FREEBSD) || defined(__GLIBC__)) &amp;&amp; ENABLE(JIT))
</span><span class="cx">     return MachineContext::stackPointer(regs);
</span><span class="cx"> #elif USE(PTHREADS)
</span><del>-    void* stackBase = 0;
-    size_t stackSize = 0;
-#if OS(OPENBSD)
-    stack_t ss;
-    int rc = pthread_stackseg_np(pthread_self(), &amp;ss);
-    stackBase = (void*)((size_t) ss.ss_sp - ss.ss_size);
-    stackSize = ss.ss_size;
</del><ins>+    return regs.stackPointer;
</ins><span class="cx"> #else
</span><del>-    int rc = pthread_attr_getstack(&amp;regs.attribute, &amp;stackBase, &amp;stackSize);
-#endif
-    (void)rc; // FIXME: Deal with error code somehow? Seems fatal.
-    ASSERT(stackBase);
-    return static_cast&lt;char*&gt;(stackBase) + stackSize;
-#else
</del><span class="cx"> #error Need a way to get the stack pointer for another thread on this platform
</span><span class="cx"> #endif
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> #if ENABLE(SAMPLING_PROFILER)
</span><del>-void* MachineThreads::ThreadData::Registers::framePointer() const
</del><ins>+void* MachineThreads::MachineThread::Registers::framePointer() const
</ins><span class="cx"> {
</span><span class="cx"> #if OS(DARWIN) || OS(WINDOWS) || (OS(FREEBSD) || defined(__GLIBC__))
</span><span class="cx">     return MachineContext::framePointer(regs);
</span><span class="lines">@@ -528,7 +245,7 @@
</span><span class="cx"> #endif
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void* MachineThreads::ThreadData::Registers::instructionPointer() const
</del><ins>+void* MachineThreads::MachineThread::Registers::instructionPointer() const
</ins><span class="cx"> {
</span><span class="cx"> #if OS(DARWIN) || OS(WINDOWS) || (OS(FREEBSD) || defined(__GLIBC__))
</span><span class="cx">     return MachineContext::instructionPointer(regs);
</span><span class="lines">@@ -537,7 +254,7 @@
</span><span class="cx"> #endif
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void* MachineThreads::ThreadData::Registers::llintPC() const
</del><ins>+void* MachineThreads::MachineThread::Registers::llintPC() const
</ins><span class="cx"> {
</span><span class="cx">     // LLInt uses regT4 as PC.
</span><span class="cx"> #if OS(DARWIN) || OS(WINDOWS) || (OS(FREEBSD) || defined(__GLIBC__))
</span><span class="lines">@@ -548,16 +265,6 @@
</span><span class="cx"> }
</span><span class="cx"> #endif // ENABLE(SAMPLING_PROFILER)
</span><span class="cx"> 
</span><del>-void MachineThreads::ThreadData::freeRegisters(ThreadData::Registers&amp; registers)
-{
-    ThreadData::Registers::PlatformRegisters&amp; regs = registers.regs;
-#if USE(PTHREADS) &amp;&amp; !OS(WINDOWS) &amp;&amp; !OS(DARWIN) &amp;&amp; !((OS(FREEBSD) || defined(__GLIBC__)) &amp;&amp; ENABLE(JIT))
-    pthread_attr_destroy(&amp;regs.attribute);
-#else
-    UNUSED_PARAM(regs);
-#endif
-}
-
</del><span class="cx"> static inline int osRedZoneAdjustment()
</span><span class="cx"> {
</span><span class="cx">     int redZoneAdjustment = 0;
</span><span class="lines">@@ -573,9 +280,9 @@
</span><span class="cx">     return redZoneAdjustment;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-std::pair&lt;void*, size_t&gt; MachineThreads::ThreadData::captureStack(void* stackTop)
</del><ins>+std::pair&lt;void*, size_t&gt; MachineThreads::MachineThread::captureStack(void* stackTop)
</ins><span class="cx"> {
</span><del>-    char* begin = reinterpret_cast_ptr&lt;char*&gt;(stackBase);
</del><ins>+    char* begin = reinterpret_cast_ptr&lt;char*&gt;(m_stackBase);
</ins><span class="cx">     char* end = bitwise_cast&lt;char*&gt;(WTF::roundUpToMultipleOf&lt;sizeof(void*)&gt;(reinterpret_cast&lt;uintptr_t&gt;(stackTop)));
</span><span class="cx">     ASSERT(begin &gt;= end);
</span><span class="cx"> 
</span><span class="lines">@@ -582,8 +289,8 @@
</span><span class="cx">     char* endWithRedZone = end + osRedZoneAdjustment();
</span><span class="cx">     ASSERT(WTF::roundUpToMultipleOf&lt;sizeof(void*)&gt;(reinterpret_cast&lt;uintptr_t&gt;(endWithRedZone)) == reinterpret_cast&lt;uintptr_t&gt;(endWithRedZone));
</span><span class="cx"> 
</span><del>-    if (endWithRedZone &lt; stackEnd)
-        endWithRedZone = reinterpret_cast_ptr&lt;char*&gt;(stackEnd);
</del><ins>+    if (endWithRedZone &lt; m_stackEnd)
+        endWithRedZone = reinterpret_cast_ptr&lt;char*&gt;(m_stackEnd);
</ins><span class="cx"> 
</span><span class="cx">     std::swap(begin, endWithRedZone);
</span><span class="cx">     return std::make_pair(begin, endWithRedZone - begin);
</span><span class="lines">@@ -616,9 +323,9 @@
</span><span class="cx"> // significant performance loss as tryCopyOtherThreadStack is only called as part of an O(heapsize)
</span><span class="cx"> // operation. As the heap is generally much larger than the stack the performance hit is minimal.
</span><span class="cx"> // See: https://bugs.webkit.org/show_bug.cgi?id=146297
</span><del>-void MachineThreads::tryCopyOtherThreadStack(Thread* thread, void* buffer, size_t capacity, size_t* size)
</del><ins>+void MachineThreads::tryCopyOtherThreadStack(MachineThread* thread, void* buffer, size_t capacity, size_t* size)
</ins><span class="cx"> {
</span><del>-    Thread::Registers registers;
</del><ins>+    MachineThread::Registers registers;
</ins><span class="cx">     size_t registersSize = thread-&gt;getRegisters(registers);
</span><span class="cx">     std::pair&lt;void*, size_t&gt; stack = thread-&gt;captureStack(registers.stackPointer());
</span><span class="cx"> 
</span><span class="lines">@@ -631,8 +338,6 @@
</span><span class="cx">     if (canCopy)
</span><span class="cx">         copyMemory(static_cast&lt;char*&gt;(buffer) + *size, stack.first, stack.second);
</span><span class="cx">     *size += stack.second;
</span><del>-
-    thread-&gt;freeRegisters(registers);
</del><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> bool MachineThreads::tryCopyOtherThreadStacks(const AbstractLocker&amp;, void* buffer, size_t capacity, size_t* size)
</span><span class="lines">@@ -644,29 +349,27 @@
</span><span class="cx"> 
</span><span class="cx">     *size = 0;
</span><span class="cx"> 
</span><del>-    PlatformThread platformThread = currentPlatformThread();
</del><ins>+    ThreadIdentifier id = currentThread();
</ins><span class="cx">     int numberOfThreads = 0; // Using 0 to denote that we haven't counted the number of threads yet.
</span><span class="cx">     int index = 1;
</span><del>-    Thread* threadsToBeDeleted = nullptr;
</del><ins>+    MachineThread* threadsToBeDeleted = nullptr;
</ins><span class="cx"> 
</span><del>-    Thread* previousThread = nullptr;
-    for (Thread* thread = m_registeredThreads; thread; index++) {
-        if (*thread != platformThread) {
-            bool success = thread-&gt;suspend();
</del><ins>+    MachineThread* previousThread = nullptr;
+    for (MachineThread* thread = m_registeredThreads; thread; index++) {
+        if (thread-&gt;threadID() != id) {
+            auto result = thread-&gt;suspend();
</ins><span class="cx"> #if OS(DARWIN)
</span><del>-            if (!success) {
</del><ins>+            if (!result) {
</ins><span class="cx">                 if (!numberOfThreads) {
</span><del>-                    for (Thread* countedThread = m_registeredThreads; countedThread; countedThread = countedThread-&gt;next)
</del><ins>+                    for (MachineThread* countedThread = m_registeredThreads; countedThread; countedThread = countedThread-&gt;next)
</ins><span class="cx">                         numberOfThreads++;
</span><span class="cx">                 }
</span><del>-                
-                // Re-do the suspension to get the actual failure result for logging.
-                kern_return_t error = thread_suspend(thread-&gt;platformThread());
-                ASSERT(error != KERN_SUCCESS);
</del><span class="cx"> 
</span><ins>+                ASSERT(result.error() != KERN_SUCCESS);
+
</ins><span class="cx">                 WTFReportError(__FILE__, __LINE__, WTF_PRETTY_FUNCTION,
</span><del>-                    &quot;JavaScript garbage collection encountered an invalid thread (err 0x%x): Thread [%d/%d: %p] platformThread %p.&quot;,
-                    error, index, numberOfThreads, thread, reinterpret_cast&lt;void*&gt;(thread-&gt;platformThread()));
</del><ins>+                    &quot;JavaScript garbage collection encountered an invalid thread (err 0x%x): Thread [%d/%d: %p] id %u.&quot;,
+                    result.error(), index, numberOfThreads, thread, thread-&gt;threadID());
</ins><span class="cx"> 
</span><span class="cx">                 // Put the invalid thread on the threadsToBeDeleted list.
</span><span class="cx">                 // We can't just delete it here because we have suspended other
</span><span class="lines">@@ -673,7 +376,7 @@
</span><span class="cx">                 // threads, and they may still be holding the C heap lock which
</span><span class="cx">                 // we need for deleting the invalid thread. Hence, we need to
</span><span class="cx">                 // defer the deletion till after we have resumed all threads.
</span><del>-                Thread* nextThread = thread-&gt;next;
</del><ins>+                MachineThread* nextThread = thread-&gt;next;
</ins><span class="cx">                 thread-&gt;next = threadsToBeDeleted;
</span><span class="cx">                 threadsToBeDeleted = thread;
</span><span class="cx"> 
</span><span class="lines">@@ -687,7 +390,7 @@
</span><span class="cx"> #else
</span><span class="cx">             UNUSED_PARAM(numberOfThreads);
</span><span class="cx">             UNUSED_PARAM(previousThread);
</span><del>-            ASSERT_UNUSED(success, success);
</del><ins>+            ASSERT_UNUSED(result, result);
</ins><span class="cx"> #endif
</span><span class="cx">         }
</span><span class="cx">         previousThread = thread;
</span><span class="lines">@@ -694,18 +397,18 @@
</span><span class="cx">         thread = thread-&gt;next;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    for (Thread* thread = m_registeredThreads; thread; thread = thread-&gt;next) {
-        if (*thread != platformThread)
</del><ins>+    for (MachineThread* thread = m_registeredThreads; thread; thread = thread-&gt;next) {
+        if (thread-&gt;threadID() != id)
</ins><span class="cx">             tryCopyOtherThreadStack(thread, buffer, capacity, size);
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    for (Thread* thread = m_registeredThreads; thread; thread = thread-&gt;next) {
-        if (*thread != platformThread)
</del><ins>+    for (MachineThread* thread = m_registeredThreads; thread; thread = thread-&gt;next) {
+        if (thread-&gt;threadID() != id)
</ins><span class="cx">             thread-&gt;resume();
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    for (Thread* thread = threadsToBeDeleted; thread; ) {
-        Thread* nextThread = thread-&gt;next;
</del><ins>+    for (MachineThread* thread = threadsToBeDeleted; thread; ) {
+        MachineThread* nextThread = thread-&gt;next;
</ins><span class="cx">         delete thread;
</span><span class="cx">         thread = nextThread;
</span><span class="cx">     }
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreheapMachineStackMarkerh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/heap/MachineStackMarker.h (215264 => 215265)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/heap/MachineStackMarker.h        2017-04-12 10:14:30 UTC (rev 215264)
+++ trunk/Source/JavaScriptCore/heap/MachineStackMarker.h        2017-04-12 12:08:29 UTC (rev 215265)
</span><span class="lines">@@ -22,7 +22,6 @@
</span><span class="cx"> #pragma once
</span><span class="cx"> 
</span><span class="cx"> #include &quot;MachineContext.h&quot;
</span><del>-#include &quot;PlatformThread.h&quot;
</del><span class="cx"> #include &quot;RegisterState.h&quot;
</span><span class="cx"> #include &lt;wtf/Lock.h&gt;
</span><span class="cx"> #include &lt;wtf/Noncopyable.h&gt;
</span><span class="lines">@@ -29,18 +28,6 @@
</span><span class="cx"> #include &lt;wtf/ScopedLambda.h&gt;
</span><span class="cx"> #include &lt;wtf/ThreadSpecific.h&gt;
</span><span class="cx"> 
</span><del>-#if USE(PTHREADS) &amp;&amp; !OS(WINDOWS) &amp;&amp; !OS(DARWIN)
-#include &lt;semaphore.h&gt;
-#include &lt;signal.h&gt;
-// Using signal.h didn't make mcontext_t and ucontext_t available on FreeBSD.
-// This bug has been fixed in FreeBSD 11.0-CURRENT, so this workaround can be
-// removed after FreeBSD 10.x goes EOL.
-// https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=207079
-#if OS(FREEBSD)
-#include &lt;ucontext.h&gt;
-#endif
-#endif
-
</del><span class="cx"> namespace JSC {
</span><span class="cx"> 
</span><span class="cx"> class CodeBlockSet;
</span><span class="lines">@@ -64,14 +51,11 @@
</span><span class="cx"> 
</span><span class="cx">     JS_EXPORT_PRIVATE void addCurrentThread(); // Only needs to be called by clients that can use the same heap from multiple threads.
</span><span class="cx"> 
</span><del>-    class ThreadData {
</del><ins>+    class MachineThread {
</ins><span class="cx">         WTF_MAKE_FAST_ALLOCATED;
</span><span class="cx">     public:
</span><del>-        ThreadData();
-        ~ThreadData();
</del><ins>+        MachineThread();
</ins><span class="cx"> 
</span><del>-        static ThreadData* createForCurrentThread();
-
</del><span class="cx">         struct Registers {
</span><span class="cx">             void* stackPointer() const;
</span><span class="cx"> #if ENABLE(SAMPLING_PROFILER)
</span><span class="lines">@@ -79,84 +63,40 @@
</span><span class="cx">             void* instructionPointer() const;
</span><span class="cx">             void* llintPC() const;
</span><span class="cx"> #endif // ENABLE(SAMPLING_PROFILER)
</span><del>-            
-#if OS(DARWIN) || OS(WINDOWS)
-            using PlatformRegisters = MachineContext::PlatformRegisters;
-#elif (OS(FREEBSD) || defined(__GLIBC__)) &amp;&amp; ENABLE(JIT)
-            using PlatformRegisters = mcontext_t;
-#elif USE(PTHREADS)
-            struct PlatformRegisters {
-                pthread_attr_t attribute;
-            };
-#else
-#error Need a thread register struct for this platform
-#endif
-
-            PlatformRegisters regs;
</del><ins>+            WTF::PlatformRegisters regs;
</ins><span class="cx">         };
</span><span class="cx"> 
</span><del>-        bool suspend();
-        void resume();
-        size_t getRegisters(Registers&amp;);
-        void freeRegisters(Registers&amp;);
</del><ins>+        Expected&lt;void, Thread::PlatformSuspendError&gt; suspend() { return m_thread-&gt;suspend(); }
+        void resume() { m_thread-&gt;resume(); }
+        size_t getRegisters(Registers&amp; regs);
</ins><span class="cx">         std::pair&lt;void*, size_t&gt; captureStack(void* stackTop);
</span><span class="cx"> 
</span><del>-        PlatformThread platformThread;
-        void* stackBase;
-        void* stackEnd;
-#if OS(WINDOWS)
-        HANDLE platformThreadHandle;
-#elif USE(PTHREADS) &amp;&amp; !OS(DARWIN)
-        sem_t semaphoreForSuspendResume;
-        mcontext_t suspendedMachineContext;
-        int suspendCount { 0 };
-        std::atomic&lt;bool&gt; suspended { false };
-#endif
-    };
</del><ins>+        WTF::ThreadIdentifier threadID() const { return m_thread-&gt;id(); }
+        void* stackBase() const { return m_stackBase; }
+        void* stackEnd() const { return m_stackEnd; }
</ins><span class="cx"> 
</span><del>-    class Thread {
-        WTF_MAKE_FAST_ALLOCATED;
-        Thread(ThreadData*);
-
-    public:
-        using Registers = ThreadData::Registers;
-
-        static Thread* createForCurrentThread();
-
-        bool operator==(const PlatformThread&amp; other) const;
-        bool operator!=(const PlatformThread&amp; other) const { return !(*this == other); }
-
-        bool suspend() { return data-&gt;suspend(); }
-        void resume() { data-&gt;resume(); }
-        size_t getRegisters(Registers&amp; regs) { return data-&gt;getRegisters(regs); }
-        void freeRegisters(Registers&amp; regs) { data-&gt;freeRegisters(regs); }
-        std::pair&lt;void*, size_t&gt; captureStack(void* stackTop) { return data-&gt;captureStack(stackTop); }
-
-        const PlatformThread&amp; platformThread() { return data-&gt;platformThread; }
-        void* stackBase() const { return data-&gt;stackBase; }
-        void* stackEnd() const { return data-&gt;stackEnd; }
-
-        Thread* next;
-        ThreadData* data;
</del><ins>+        MachineThread* next;
+        Ref&lt;WTF::Thread&gt; m_thread;
+        void* m_stackBase;
+        void* m_stackEnd;
</ins><span class="cx">     };
</span><span class="cx"> 
</span><span class="cx">     Lock&amp; getLock() { return m_registeredThreadsMutex; }
</span><del>-    Thread* threadsListHead(const AbstractLocker&amp;) const { ASSERT(m_registeredThreadsMutex.isLocked()); return m_registeredThreads; }
-    Thread* machineThreadForCurrentThread();
</del><ins>+    MachineThread* threadsListHead(const AbstractLocker&amp;) const { ASSERT(m_registeredThreadsMutex.isLocked()); return m_registeredThreads; }
+    MachineThread* machineThreadForCurrentThread();
</ins><span class="cx"> 
</span><span class="cx"> private:
</span><span class="cx">     void gatherFromCurrentThread(ConservativeRoots&amp;, JITStubRoutineSet&amp;, CodeBlockSet&amp;, CurrentThreadState&amp;);
</span><span class="cx"> 
</span><del>-    void tryCopyOtherThreadStack(Thread*, void*, size_t capacity, size_t*);
</del><ins>+    void tryCopyOtherThreadStack(MachineThread*, void*, size_t capacity, size_t*);
</ins><span class="cx">     bool tryCopyOtherThreadStacks(const AbstractLocker&amp;, void*, size_t capacity, size_t*);
</span><span class="cx"> 
</span><span class="cx">     static void THREAD_SPECIFIC_CALL removeThread(void*);
</span><span class="cx"> 
</span><del>-    template&lt;typename PlatformThread&gt;
-    void removeThreadIfFound(PlatformThread);
</del><ins>+    void removeThreadIfFound(ThreadIdentifier);
</ins><span class="cx"> 
</span><span class="cx">     Lock m_registeredThreadsMutex;
</span><del>-    Thread* m_registeredThreads;
</del><ins>+    MachineThread* m_registeredThreads;
</ins><span class="cx">     WTF::ThreadSpecificKey m_threadSpecificForMachineThreads;
</span><span class="cx"> };
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitICStatscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/ICStats.cpp (215264 => 215265)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/ICStats.cpp        2017-04-12 10:14:30 UTC (rev 215264)
+++ trunk/Source/JavaScriptCore/jit/ICStats.cpp        2017-04-12 12:08:29 UTC (rev 215265)
</span><span class="lines">@@ -58,7 +58,7 @@
</span><span class="cx"> 
</span><span class="cx"> ICStats::ICStats()
</span><span class="cx"> {
</span><del>-    m_thread = createThread(
</del><ins>+    m_thread = Thread::create(
</ins><span class="cx">         &quot;JSC ICStats&quot;,
</span><span class="cx">         [this] () {
</span><span class="cx">             LockHolder locker(m_lock);
</span><span class="lines">@@ -84,7 +84,7 @@
</span><span class="cx">         m_condition.notifyAll();
</span><span class="cx">     }
</span><span class="cx">     
</span><del>-    waitForThreadCompletion(m_thread);
</del><ins>+    m_thread-&gt;waitForCompletion();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void ICStats::add(const ICEvent&amp; event)
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejitICStatsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jit/ICStats.h (215264 => 215265)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jit/ICStats.h        2017-04-12 10:14:30 UTC (rev 215264)
+++ trunk/Source/JavaScriptCore/jit/ICStats.h        2017-04-12 12:08:29 UTC (rev 215265)
</span><span class="lines">@@ -179,7 +179,7 @@
</span><span class="cx"> private:
</span><span class="cx"> 
</span><span class="cx">     Spectrum&lt;ICEvent, uint64_t&gt; m_spectrum;
</span><del>-    ThreadIdentifier m_thread;
</del><ins>+    RefPtr&lt;Thread&gt; m_thread;
</ins><span class="cx">     Lock m_lock;
</span><span class="cx">     Condition m_condition;
</span><span class="cx">     bool m_shouldStop { false };
</span></span></pre></div>
<a id="trunkSourceJavaScriptCorejsccpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/jsc.cpp (215264 => 215265)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/jsc.cpp        2017-04-12 10:14:30 UTC (rev 215264)
+++ trunk/Source/JavaScriptCore/jsc.cpp        2017-04-12 12:08:29 UTC (rev 215265)
</span><span class="lines">@@ -2544,7 +2544,7 @@
</span><span class="cx">     Condition didStartCondition;
</span><span class="cx">     bool didStart = false;
</span><span class="cx">     
</span><del>-    ThreadIdentifier thread = createThread(
</del><ins>+    RefPtr&lt;Thread&gt; thread = Thread::create(
</ins><span class="cx">         &quot;JSC Agent&quot;,
</span><span class="cx">         [sourceCode, &amp;didStartLock, &amp;didStartCondition, &amp;didStart] () {
</span><span class="cx">             CommandLine commandLine(0, nullptr);
</span><span class="lines">@@ -2571,7 +2571,7 @@
</span><span class="cx">                     return success;
</span><span class="cx">                 });
</span><span class="cx">         });
</span><del>-    detachThread(thread);
</del><ins>+    thread-&gt;detach();
</ins><span class="cx">     
</span><span class="cx">     {
</span><span class="cx">         auto locker = holdLock(didStartLock);
</span><span class="lines">@@ -3311,7 +3311,7 @@
</span><span class="cx">             dataLog(&quot;WARNING: timeout string is malformed, got &quot;, timeoutString,
</span><span class="cx">                 &quot; but expected a number. Not using a timeout.\n&quot;);
</span><span class="cx">         } else
</span><del>-            createThread(timeoutThreadMain, 0, &quot;jsc Timeout Thread&quot;);
</del><ins>+            Thread::create(timeoutThreadMain, 0, &quot;jsc Timeout Thread&quot;);
</ins><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeJSLockcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/JSLock.cpp (215264 => 215265)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/JSLock.cpp        2017-04-12 10:14:30 UTC (rev 215264)
+++ trunk/Source/JavaScriptCore/runtime/JSLock.cpp        2017-04-12 12:08:29 UTC (rev 215265)
</span><span class="lines">@@ -109,7 +109,7 @@
</span><span class="cx">         m_lock.lock();
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    m_ownerThread = currentThread();
</del><ins>+    m_ownerThread = &amp;Thread::current();
</ins><span class="cx">     WTF::storeStoreFence();
</span><span class="cx">     m_hasOwnerThread = true;
</span><span class="cx">     ASSERT(!m_lockCount);
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeJSLockh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/JSLock.h (215264 => 215265)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/JSLock.h        2017-04-12 10:14:30 UTC (rev 215264)
+++ trunk/Source/JavaScriptCore/runtime/JSLock.h        2017-04-12 12:08:29 UTC (rev 215265)
</span><span class="lines">@@ -92,13 +92,13 @@
</span><span class="cx"> 
</span><span class="cx">     VM* vm() { return m_vm; }
</span><span class="cx"> 
</span><del>-    std::optional&lt;ThreadIdentifier&gt; ownerThread() const
</del><ins>+    std::optional&lt;RefPtr&lt;Thread&gt;&gt; ownerThread() const
</ins><span class="cx">     {
</span><span class="cx">         if (m_hasOwnerThread)
</span><span class="cx">             return m_ownerThread;
</span><span class="cx">         return std::nullopt;
</span><span class="cx">     }
</span><del>-    bool currentThreadIsHoldingLock() { return m_hasOwnerThread &amp;&amp; m_ownerThread == currentThread(); }
</del><ins>+    bool currentThreadIsHoldingLock() { return m_hasOwnerThread &amp;&amp; m_ownerThread-&gt;id() == currentThread(); }
</ins><span class="cx"> 
</span><span class="cx">     void willDestroyVM(VM*);
</span><span class="cx"> 
</span><span class="lines">@@ -135,7 +135,7 @@
</span><span class="cx">     // different thread, and an optional is vulnerable to races.
</span><span class="cx">     // See https://bugs.webkit.org/show_bug.cgi?id=169042#c6
</span><span class="cx">     bool m_hasOwnerThread { false };
</span><del>-    ThreadIdentifier m_ownerThread;
</del><ins>+    RefPtr&lt;Thread&gt; m_ownerThread;
</ins><span class="cx">     intptr_t m_lockCount;
</span><span class="cx">     unsigned m_lockDropDepth;
</span><span class="cx">     bool m_shouldReleaseHeapAccess;
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimePlatformThreadh"></a>
<div class="delfile"><h4>Deleted: trunk/Source/JavaScriptCore/runtime/PlatformThread.h (215264 => 215265)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/PlatformThread.h        2017-04-12 10:14:30 UTC (rev 215264)
+++ trunk/Source/JavaScriptCore/runtime/PlatformThread.h        2017-04-12 12:08:29 UTC (rev 215265)
</span><span class="lines">@@ -1,63 +0,0 @@
</span><del>-/*
- * Copyright (C) 2017 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#pragma once
-
-#if OS(DARWIN) || OS(UNIX)
-#include &lt;pthread.h&gt;
-#endif
-
-#if USE(PTHREADS) &amp;&amp; !OS(WINDOWS) &amp;&amp; !OS(DARWIN)
-#include &lt;signal.h&gt;
-#endif
-
-#if OS(DARWIN)
-#include &lt;mach/thread_act.h&gt;
-#elif OS(WINDOWS)
-#include &lt;windows.h&gt;
-#endif
-
-namespace JSC {
-
-#if OS(DARWIN)
-typedef mach_port_t PlatformThread;
-#elif OS(WINDOWS)
-typedef DWORD PlatformThread;
-#elif USE(PTHREADS)
-typedef pthread_t PlatformThread;
-#endif // OS(DARWIN)
-    
-inline PlatformThread currentPlatformThread()
-{
-#if OS(DARWIN)
-    return pthread_mach_thread_np(pthread_self());
-#elif OS(WINDOWS)
-    return GetCurrentThreadId();
-#elif USE(PTHREADS)
-    return pthread_self();
-#endif
-}
-
-} // namespace JSC
</del></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeSamplingProfilercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/SamplingProfiler.cpp (215264 => 215265)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/SamplingProfiler.cpp        2017-04-12 10:14:30 UTC (rev 215264)
+++ trunk/Source/JavaScriptCore/runtime/SamplingProfiler.cpp        2017-04-12 12:08:29 UTC (rev 215265)
</span><span class="lines">@@ -167,7 +167,7 @@
</span><span class="cx">     bool isValidFramePointer(void* exec)
</span><span class="cx">     {
</span><span class="cx">         uint8_t* fpCast = bitwise_cast&lt;uint8_t*&gt;(exec);
</span><del>-        for (MachineThreads::Thread* thread = m_vm.heap.machineThreads().threadsListHead(m_machineThreadsLocker); thread; thread = thread-&gt;next) {
</del><ins>+        for (MachineThreads::MachineThread* thread = m_vm.heap.machineThreads().threadsListHead(m_machineThreadsLocker); thread; thread = thread-&gt;next) {
</ins><span class="cx">             uint8_t* stackBase = static_cast&lt;uint8_t*&gt;(thread-&gt;stackBase());
</span><span class="cx">             uint8_t* stackLimit = static_cast&lt;uint8_t*&gt;(thread-&gt;stackEnd());
</span><span class="cx">             RELEASE_ASSERT(stackBase);
</span><span class="lines">@@ -279,7 +279,6 @@
</span><span class="cx">     , m_weakRandom()
</span><span class="cx">     , m_stopwatch(WTFMove(stopwatch))
</span><span class="cx">     , m_timingInterval(std::chrono::microseconds(Options::sampleInterval()))
</span><del>-    , m_threadIdentifier(0)
</del><span class="cx">     , m_jscExecutionThread(nullptr)
</span><span class="cx">     , m_isPaused(false)
</span><span class="cx">     , m_isShutDown(false)
</span><span class="lines">@@ -300,11 +299,11 @@
</span><span class="cx"> {
</span><span class="cx">     ASSERT(m_lock.isLocked());
</span><span class="cx"> 
</span><del>-    if (m_threadIdentifier)
</del><ins>+    if (m_thread)
</ins><span class="cx">         return;
</span><span class="cx"> 
</span><span class="cx">     RefPtr&lt;SamplingProfiler&gt; profiler = this;
</span><del>-    m_threadIdentifier = createThread(&quot;jsc.sampling-profiler.thread&quot;, [profiler] {
</del><ins>+    m_thread = Thread::create(&quot;jsc.sampling-profiler.thread&quot;, [profiler] {
</ins><span class="cx">         profiler-&gt;timerLoop();
</span><span class="cx">     });
</span><span class="cx"> }
</span><span class="lines">@@ -344,7 +343,7 @@
</span><span class="cx">         LockHolder codeBlockSetLocker(m_vm.heap.codeBlockSet().getLock());
</span><span class="cx">         LockHolder executableAllocatorLocker(ExecutableAllocator::singleton().getLock());
</span><span class="cx"> 
</span><del>-        bool didSuspend = m_jscExecutionThread-&gt;suspend();
</del><ins>+        auto didSuspend = m_jscExecutionThread-&gt;suspend();
</ins><span class="cx">         if (didSuspend) {
</span><span class="cx">             // While the JSC thread is suspended, we can't do things like malloc because the JSC thread
</span><span class="cx">             // may be holding the malloc lock.
</span><span class="lines">@@ -354,13 +353,12 @@
</span><span class="cx">             bool topFrameIsLLInt = false;
</span><span class="cx">             void* llintPC;
</span><span class="cx">             {
</span><del>-                MachineThreads::Thread::Registers registers;
</del><ins>+                MachineThreads::MachineThread::Registers registers;
</ins><span class="cx">                 m_jscExecutionThread-&gt;getRegisters(registers);
</span><span class="cx">                 machineFrame = registers.framePointer();
</span><span class="cx">                 callFrame = static_cast&lt;ExecState*&gt;(machineFrame);
</span><span class="cx">                 machinePC = registers.instructionPointer();
</span><span class="cx">                 llintPC = registers.llintPC();
</span><del>-                m_jscExecutionThread-&gt;freeRegisters(registers);
</del><span class="cx">             }
</span><span class="cx">             // FIXME: Lets have a way of detecting when we're parsing code.
</span><span class="cx">             // https://bugs.webkit.org/show_bug.cgi?id=152761
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeSamplingProfilerh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/SamplingProfiler.h (215264 => 215265)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/SamplingProfiler.h        2017-04-12 10:14:30 UTC (rev 215264)
+++ trunk/Source/JavaScriptCore/runtime/SamplingProfiler.h        2017-04-12 12:08:29 UTC (rev 215265)
</span><span class="lines">@@ -195,8 +195,8 @@
</span><span class="cx">     std::chrono::microseconds m_timingInterval;
</span><span class="cx">     double m_lastTime;
</span><span class="cx">     Lock m_lock;
</span><del>-    ThreadIdentifier m_threadIdentifier;
-    MachineThreads::Thread* m_jscExecutionThread;
</del><ins>+    RefPtr&lt;Thread&gt; m_thread;
+    MachineThreads::MachineThread* m_jscExecutionThread;
</ins><span class="cx">     bool m_isPaused;
</span><span class="cx">     bool m_isShutDown;
</span><span class="cx">     bool m_needsReportAtExit { false };
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeVMh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/VM.h (215264 => 215265)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/VM.h        2017-04-12 10:14:30 UTC (rev 215264)
+++ trunk/Source/JavaScriptCore/runtime/VM.h        2017-04-12 12:08:29 UTC (rev 215265)
</span><span class="lines">@@ -659,7 +659,7 @@
</span><span class="cx">     template&lt;typename Func&gt;
</span><span class="cx">     void logEvent(CodeBlock*, const char* summary, const Func&amp; func);
</span><span class="cx"> 
</span><del>-    std::optional&lt;ThreadIdentifier&gt; ownerThread() const { return m_apiLock-&gt;ownerThread(); }
</del><ins>+    std::optional&lt;RefPtr&lt;Thread&gt;&gt; ownerThread() const { return m_apiLock-&gt;ownerThread(); }
</ins><span class="cx"> 
</span><span class="cx">     VMTraps&amp; traps() { return m_traps; }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeVMTrapscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/VMTraps.cpp (215264 => 215265)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/VMTraps.cpp        2017-04-12 10:14:30 UTC (rev 215264)
+++ trunk/Source/JavaScriptCore/runtime/VMTraps.cpp        2017-04-12 12:08:29 UTC (rev 215265)
</span><span class="lines">@@ -110,7 +110,7 @@
</span><span class="cx">             return VMInspector::FunctorStatus::Continue; // Try next VM.
</span><span class="cx">         }
</span><span class="cx"> 
</span><del>-        for (MachineThreads::Thread* thread = machineThreads.threadsListHead(machineThreadsLocker); thread; thread = thread-&gt;next) {
</del><ins>+        for (MachineThreads::MachineThread* thread = machineThreads.threadsListHead(machineThreadsLocker); thread; thread = thread-&gt;next) {
</ins><span class="cx">             RELEASE_ASSERT(thread-&gt;stackBase());
</span><span class="cx">             RELEASE_ASSERT(thread-&gt;stackEnd());
</span><span class="cx">             if (stackPointer &lt;= thread-&gt;stackBase() &amp;&amp; stackPointer &gt;= thread-&gt;stackEnd()) {
</span><span class="lines">@@ -455,7 +455,7 @@
</span><span class="cx">             VM&amp; vm = *m_vm;
</span><span class="cx">             auto optionalOwnerThread = vm.ownerThread();
</span><span class="cx">             if (optionalOwnerThread) {
</span><del>-                signalThread(optionalOwnerThread.value(), SIGUSR1);
</del><ins>+                optionalOwnerThread.value()-&gt;signal(SIGUSR1);
</ins><span class="cx">                 break;
</span><span class="cx">             }
</span><span class="cx"> 
</span><span class="lines">@@ -493,7 +493,7 @@
</span><span class="cx">         // fireTrap() does not block.
</span><span class="cx">         RefPtr&lt;SignalSender&gt; sender = adoptRef(new SignalSender(vm(), eventType));
</span><span class="cx">         addSignalSender(sender.get());
</span><del>-        createThread(&quot;jsc.vmtraps.signalling.thread&quot;, [sender] {
</del><ins>+        Thread::create(&quot;jsc.vmtraps.signalling.thread&quot;, [sender] {
</ins><span class="cx">             sender-&gt;send();
</span><span class="cx">         });
</span><span class="cx">     }
</span></span></pre></div>
<a id="trunkSourceWTFChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/ChangeLog (215264 => 215265)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/ChangeLog        2017-04-12 10:14:30 UTC (rev 215264)
+++ trunk/Source/WTF/ChangeLog        2017-04-12 12:08:29 UTC (rev 215265)
</span><span class="lines">@@ -1,3 +1,192 @@
</span><ins>+2017-04-12  Yusuke Suzuki  &lt;utatane.tea@gmail.com&gt;
+
+        [WTF] Introduce Thread class and use RefPtr&lt;Thread&gt; and align Windows Threading implementation semantics to Pthread one
+        https://bugs.webkit.org/show_bug.cgi?id=170502
+
+        Reviewed by Mark Lam.
+
+        This patch is refactoring of WTF Threading mechanism to merge JavaScriptCore's threading extension to WTF Threading.
+        Previously, JavaScriptCore requires richer threading features (such as suspending and resuming threads), and they
+        are implemented for PlatformThread in JavaScriptCore. But these features should be implemented in WTF Threading side
+        instead of maintaining JSC's own threading features too. This patch removes these features from JSC and move it to
+        WTF Threading.
+
+        However, current WTF Threading has one problem: Windows version of WTF Threading has different semantics from Pthreads
+        one. In Windows WTF Threading, we cannot perform any operation after the target thread is detached: WTF Threading stop
+        tracking the state of the thread once the thread is detached. But this is not the same to Pthreads one. In Pthreads,
+        pthread_detach just means that the resource of the thread will be destroyed automatically. While some operations like
+        pthread_join will be rejected, some operations like pthread_kill will be accepted.
+
+        The problem is that detached thread can be suspended and resumed in JSC. For example, in jsc.cpp, we start the worker
+        thread and detach it immediately. In worker thread, we will create VM and thus concurrent GC will suspend and resume
+        the detached thread. However, in Windows WTF Threading, we have no reference to the detached thread. Thus we cannot
+        perform suspend and resume operations onto the detached thread.
+
+        To solve the problem, we change Windows Threading mechanism drastically to align it to the Pthread semantics. In the
+        new Threading, we have RefPtr&lt;Thread&gt; class. It holds a handle to a platform thread. We can perform threading operations
+        with this class. For example, Thread::suspend is offered. And we use destructor of the thread local variable to release
+        the resources held by RefPtr&lt;Thread&gt;. In Windows, Thread::detach does nothing because the resource will be destroyed
+        automatically by RefPtr&lt;Thread&gt;.
+
+        To do so, we introduce ThreadHolder for Windows. This is similar to the previous ThreadIdentifierData for Pthreads.
+        It holds RefPtr&lt;Thread&gt; in the thread local storage (technically, it is Fiber Local Storage in Windows). Thread::current()
+        will return this reference.
+
+        The problematic situation is that the order of the deallocation of the thread local storage is not defined. So we should
+        not touch thread local storage in the destructor of the thread local storage. To avoid such edge cases, we have
+        currentThread() / Thread::currentID() APIs. They are safe to be called even in the destructor of the other thread local
+        storage. And in Windows, in the FLS destructor, we will create the thread_local variable to defer the destruction of
+        the ThreadHolder. We ensure that this destructor is called after the other FLS destructors are called in Windows 10.
+
+        This patch is performance neutral.
+
+        * WTF.xcodeproj/project.pbxproj:
+        * benchmarks/ConditionSpeedTest.cpp:
+        * benchmarks/LockFairnessTest.cpp:
+        * benchmarks/LockSpeedTest.cpp:
+        * wtf/AutomaticThread.cpp:
+        (WTF::AutomaticThread::start):
+        * wtf/CMakeLists.txt:
+        * wtf/MainThread.h:
+        * wtf/MemoryPressureHandler.h:
+        * wtf/ParallelJobsGeneric.cpp:
+        (WTF::ParallelEnvironment::ThreadPrivate::tryLockFor):
+        (WTF::ParallelEnvironment::ThreadPrivate::workerThread):
+        * wtf/ParallelJobsGeneric.h:
+        (WTF::ParallelEnvironment::ThreadPrivate::ThreadPrivate): Deleted.
+        * wtf/ParkingLot.cpp:
+        (WTF::ParkingLot::forEachImpl):
+        * wtf/ParkingLot.h:
+        (WTF::ParkingLot::forEach):
+        * wtf/PlatformRegisters.h: Renamed from Source/JavaScriptCore/runtime/PlatformThread.h.
+        * wtf/RefPtr.h:
+        (WTF::RefPtr::RefPtr):
+        * wtf/ThreadFunctionInvocation.h:
+        (WTF::ThreadFunctionInvocation::ThreadFunctionInvocation):
+        * wtf/ThreadHolder.cpp: Added.
+        (WTF::ThreadHolder::~ThreadHolder):
+        (WTF::ThreadHolder::initialize):
+        * wtf/ThreadHolder.h: Renamed from Source/WTF/wtf/ThreadIdentifierDataPthreads.h.
+        (WTF::ThreadHolder::thread):
+        (WTF::ThreadHolder::ThreadHolder):
+        * wtf/ThreadHolderPthreads.cpp: Renamed from Source/WTF/wtf/ThreadIdentifierDataPthreads.cpp.
+        (WTF::ThreadHolder::initializeOnce):
+        (WTF::ThreadHolder::current):
+        (WTF::ThreadHolder::destruct):
+        * wtf/ThreadHolderWin.cpp: Added.
+        (WTF::threadMapMutex):
+        (WTF::threadMap):
+        (WTF::ThreadHolder::initializeOnce):
+        (WTF::ThreadHolder::current):
+        (WTF::ThreadHolder::destruct):
+        * wtf/ThreadSpecific.h:
+        * wtf/Threading.cpp:
+        (WTF::Thread::normalizeThreadName):
+        (WTF::threadEntryPoint):
+        (WTF::Thread::create):
+        (WTF::Thread::setCurrentThreadIsUserInteractive):
+        (WTF::Thread::setCurrentThreadIsUserInitiated):
+        (WTF::Thread::setGlobalMaxQOSClass):
+        (WTF::Thread::adjustedQOSClass):
+        (WTF::Thread::dump):
+        (WTF::initializeThreading):
+        (WTF::normalizeThreadName): Deleted.
+        (WTF::createThread): Deleted.
+        (WTF::setCurrentThreadIsUserInteractive): Deleted.
+        (WTF::setCurrentThreadIsUserInitiated): Deleted.
+        (WTF::setGlobalMaxQOSClass): Deleted.
+        (WTF::adjustedQOSClass): Deleted.
+        * wtf/Threading.h:
+        (WTF::Thread::id):
+        (WTF::Thread::operator==):
+        (WTF::Thread::operator!=):
+        (WTF::Thread::joinableState):
+        (WTF::Thread::didBecomeDetached):
+        (WTF::Thread::didJoin):
+        (WTF::Thread::hasExited):
+        (WTF::currentThread):
+        * wtf/ThreadingPthreads.cpp:
+        (WTF::Thread::Thread):
+        (WTF::Thread::~Thread):
+        (WTF::Thread::signalHandlerSuspendResume):
+        (WTF::Thread::initializePlatformThreading):
+        (WTF::initializeCurrentThreadEvenIfNonWTFCreated):
+        (WTF::wtfThreadEntryPoint):
+        (WTF::Thread::createInternal):
+        (WTF::Thread::initializeCurrentThreadInternal):
+        (WTF::Thread::changePriority):
+        (WTF::Thread::waitForCompletion):
+        (WTF::Thread::detach):
+        (WTF::Thread::current):
+        (WTF::Thread::currentID):
+        (WTF::Thread::signal):
+        (WTF::Thread::resume):
+        (WTF::Thread::getRegisters):
+        (WTF::Thread::didExit):
+        (WTF::Thread::establish):
+        (WTF::PthreadState::PthreadState): Deleted.
+        (WTF::PthreadState::joinableState): Deleted.
+        (WTF::PthreadState::pthreadHandle): Deleted.
+        (WTF::PthreadState::didBecomeDetached): Deleted.
+        (WTF::PthreadState::didExit): Deleted.
+        (WTF::PthreadState::didJoin): Deleted.
+        (WTF::PthreadState::hasExited): Deleted.
+        (WTF::threadMapMutex): Deleted.
+        (WTF::initializeThreading): Deleted.
+        (WTF::threadMap): Deleted.
+        (WTF::identifierByPthreadHandle): Deleted.
+        (WTF::establishIdentifierForPthreadHandle): Deleted.
+        (WTF::pthreadHandleForIdentifierWithLockAlreadyHeld): Deleted.
+        (WTF::createThreadInternal): Deleted.
+        (WTF::initializeCurrentThreadInternal): Deleted.
+        (WTF::changeThreadPriority): Deleted.
+        (WTF::waitForThreadCompletion): Deleted.
+        (WTF::detachThread): Deleted.
+        (WTF::threadDidExit): Deleted.
+        (WTF::currentThread): Deleted.
+        (WTF::signalThread): Deleted.
+        * wtf/ThreadingWin.cpp:
+        (WTF::Thread::Thread):
+        (WTF::Thread::~Thread):
+        (WTF::Thread::initializeCurrentThreadInternal):
+        (WTF::Thread::initializePlatformThreading):
+        (WTF::wtfThreadEntryPoint):
+        (WTF::Thread::createInternal):
+        (WTF::Thread::changePriority):
+        (WTF::Thread::waitForCompletion):
+        (WTF::Thread::detach):
+        (WTF::Thread::resume):
+        (WTF::Thread::getRegisters):
+        (WTF::Thread::current):
+        (WTF::Thread::currentID):
+        (WTF::Thread::didExit):
+        (WTF::Thread::establish):
+        (WTF::initializeCurrentThreadInternal): Deleted.
+        (WTF::threadMapMutex): Deleted.
+        (WTF::initializeThreading): Deleted.
+        (WTF::threadMap): Deleted.
+        (WTF::storeThreadHandleByIdentifier): Deleted.
+        (WTF::threadHandleForIdentifier): Deleted.
+        (WTF::clearThreadHandleForIdentifier): Deleted.
+        (WTF::createThreadInternal): Deleted.
+        (WTF::changeThreadPriority): Deleted.
+        (WTF::waitForThreadCompletion): Deleted.
+        (WTF::detachThread): Deleted.
+        (WTF::currentThread): Deleted.
+        * wtf/WorkQueue.cpp:
+        (WTF::WorkQueue::concurrentApply):
+        * wtf/WorkQueue.h:
+        * wtf/cocoa/WorkQueueCocoa.cpp:
+        (WTF::dispatchQOSClass):
+        * wtf/generic/WorkQueueGeneric.cpp:
+        (WorkQueue::platformInitialize):
+        (WorkQueue::platformInvalidate):
+        * wtf/linux/MemoryPressureHandlerLinux.cpp:
+        (WTF::MemoryPressureHandler::EventFDPoller::EventFDPoller):
+        (WTF::MemoryPressureHandler::EventFDPoller::~EventFDPoller):
+        * wtf/win/MainThreadWin.cpp:
+        (WTF::initializeMainThreadPlatform):
+
</ins><span class="cx"> 2017-04-11  Zan Dobersek  &lt;zdobersek@igalia.com&gt;
</span><span class="cx"> 
</span><span class="cx">         [GTK] Use the DisplayRefreshMonitor facilities
</span></span></pre></div>
<a id="trunkSourceWTFWTFxcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/WTF.xcodeproj/project.pbxproj (215264 => 215265)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/WTF.xcodeproj/project.pbxproj        2017-04-12 10:14:30 UTC (rev 215264)
+++ trunk/Source/WTF/WTF.xcodeproj/project.pbxproj        2017-04-12 12:08:29 UTC (rev 215265)
</span><span class="lines">@@ -327,8 +327,7 @@
</span><span class="cx">                 A8A47445151A825B004123FF /* WTFString.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A8A4732D151A825B004123FF /* WTFString.cpp */; };
</span><span class="cx">                 A8A47446151A825B004123FF /* WTFString.h in Headers */ = {isa = PBXBuildFile; fileRef = A8A4732E151A825B004123FF /* WTFString.h */; };
</span><span class="cx">                 A8A47447151A825B004123FF /* ThreadFunctionInvocation.h in Headers */ = {isa = PBXBuildFile; fileRef = A8A4732F151A825B004123FF /* ThreadFunctionInvocation.h */; };
</span><del>-                A8A47448151A825B004123FF /* ThreadIdentifierDataPthreads.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A8A47330151A825B004123FF /* ThreadIdentifierDataPthreads.cpp */; };
-                A8A47449151A825B004123FF /* ThreadIdentifierDataPthreads.h in Headers */ = {isa = PBXBuildFile; fileRef = A8A47331151A825B004123FF /* ThreadIdentifierDataPthreads.h */; };
</del><ins>+                A8A47448151A825B004123FF /* ThreadHolderPthreads.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A8A47330151A825B004123FF /* ThreadHolderPthreads.cpp */; };
</ins><span class="cx">                 A8A4744A151A825B004123FF /* Threading.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A8A47332151A825B004123FF /* Threading.cpp */; };
</span><span class="cx">                 A8A4744B151A825B004123FF /* Threading.h in Headers */ = {isa = PBXBuildFile; fileRef = A8A47333151A825B004123FF /* Threading.h */; };
</span><span class="cx">                 A8A4744D151A825B004123FF /* ThreadingPrimitives.h in Headers */ = {isa = PBXBuildFile; fileRef = A8A47335151A825B004123FF /* ThreadingPrimitives.h */; };
</span><span class="lines">@@ -374,6 +373,9 @@
</span><span class="cx">                 DE5A09FC1BA36992003D4424 /* CommonCryptoSPI.h in Headers */ = {isa = PBXBuildFile; fileRef = DE5A09FB1BA36992003D4424 /* CommonCryptoSPI.h */; };
</span><span class="cx">                 E15556F518A0CC18006F48FB /* CryptographicUtilities.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E15556F318A0CC18006F48FB /* CryptographicUtilities.cpp */; };
</span><span class="cx">                 E15556F618A0CC18006F48FB /* CryptographicUtilities.h in Headers */ = {isa = PBXBuildFile; fileRef = E15556F418A0CC18006F48FB /* CryptographicUtilities.h */; };
</span><ins>+                E3200AB71E9A536D003B59D2 /* PlatformRegisters.h in Headers */ = {isa = PBXBuildFile; fileRef = E3200AB41E9A536D003B59D2 /* PlatformRegisters.h */; };
+                E3200AB81E9A536D003B59D2 /* ThreadHolder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E3200AB51E9A536D003B59D2 /* ThreadHolder.cpp */; };
+                E3200AB91E9A536D003B59D2 /* ThreadHolder.h in Headers */ = {isa = PBXBuildFile; fileRef = E3200AB61E9A536D003B59D2 /* ThreadHolder.h */; };
</ins><span class="cx">                 E43A46951E228B9100276B05 /* Decoder.h in Headers */ = {isa = PBXBuildFile; fileRef = E43A46901E228B9100276B05 /* Decoder.h */; };
</span><span class="cx">                 E43A46961E228B9100276B05 /* Encoder.h in Headers */ = {isa = PBXBuildFile; fileRef = E43A46911E228B9100276B05 /* Encoder.h */; };
</span><span class="cx">                 E43A46971E228B9100276B05 /* Decoder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E43A46921E228B9100276B05 /* Decoder.cpp */; };
</span><span class="lines">@@ -731,8 +733,7 @@
</span><span class="cx">                 A8A4732D151A825B004123FF /* WTFString.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WTFString.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 A8A4732E151A825B004123FF /* WTFString.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WTFString.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 A8A4732F151A825B004123FF /* ThreadFunctionInvocation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ThreadFunctionInvocation.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><del>-                A8A47330151A825B004123FF /* ThreadIdentifierDataPthreads.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ThreadIdentifierDataPthreads.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
-                A8A47331151A825B004123FF /* ThreadIdentifierDataPthreads.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ThreadIdentifierDataPthreads.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</del><ins>+                A8A47330151A825B004123FF /* ThreadHolderPthreads.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ThreadHolderPthreads.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</ins><span class="cx">                 A8A47332151A825B004123FF /* Threading.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Threading.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 A8A47333151A825B004123FF /* Threading.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Threading.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 A8A47335151A825B004123FF /* ThreadingPrimitives.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ThreadingPrimitives.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -777,6 +778,9 @@
</span><span class="cx">                 DE5A09FB1BA36992003D4424 /* CommonCryptoSPI.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CommonCryptoSPI.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 E15556F318A0CC18006F48FB /* CryptographicUtilities.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CryptographicUtilities.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 E15556F418A0CC18006F48FB /* CryptographicUtilities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CryptographicUtilities.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><ins>+                E3200AB41E9A536D003B59D2 /* PlatformRegisters.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PlatformRegisters.h; sourceTree = &quot;&lt;group&gt;&quot;; };
+                E3200AB51E9A536D003B59D2 /* ThreadHolder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ThreadHolder.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
+                E3200AB61E9A536D003B59D2 /* ThreadHolder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ThreadHolder.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</ins><span class="cx">                 E43A46901E228B9100276B05 /* Decoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Decoder.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 E43A46911E228B9100276B05 /* Encoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Encoder.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 E43A46921E228B9100276B05 /* Decoder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Decoder.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -1100,6 +1104,7 @@
</span><span class="cx">                                 0F824A651B7443A0002E345D /* ParkingLot.h */,
</span><span class="cx">                                 A8A472ED151A825B004123FF /* PassRefPtr.h */,
</span><span class="cx">                                 A876DBD7151816E500DADB95 /* Platform.h */,
</span><ins>+                                E3200AB41E9A536D003B59D2 /* PlatformRegisters.h */,
</ins><span class="cx">                                 DCEE21FE1CEA7551000C2396 /* PlatformUserPreferredLanguages.h */,
</span><span class="cx">                                 DCEE21FF1CEA7551000C2396 /* PlatformUserPreferredLanguagesMac.mm */,
</span><span class="cx">                                 0FF860941BCCBD740045127F /* PointerComparison.h */,
</span><span class="lines">@@ -1167,8 +1172,9 @@
</span><span class="cx">                                 5597F82C1D94B9970066BC21 /* SynchronizedFixedQueue.h */,
</span><span class="cx">                                 0FB317C31C488001007E395A /* SystemTracing.h */,
</span><span class="cx">                                 A8A4732F151A825B004123FF /* ThreadFunctionInvocation.h */,
</span><del>-                                A8A47330151A825B004123FF /* ThreadIdentifierDataPthreads.cpp */,
-                                A8A47331151A825B004123FF /* ThreadIdentifierDataPthreads.h */,
</del><ins>+                                E3200AB51E9A536D003B59D2 /* ThreadHolder.cpp */,
+                                E3200AB61E9A536D003B59D2 /* ThreadHolder.h */,
+                                A8A47330151A825B004123FF /* ThreadHolderPthreads.cpp */,
</ins><span class="cx">                                 A8A47332151A825B004123FF /* Threading.cpp */,
</span><span class="cx">                                 A8A47333151A825B004123FF /* Threading.h */,
</span><span class="cx">                                 A8A47335151A825B004123FF /* ThreadingPrimitives.h */,
</span><span class="lines">@@ -1556,6 +1562,7 @@
</span><span class="cx">                                 A8A4740C151A825B004123FF /* PassRefPtr.h in Headers */,
</span><span class="cx">                                 A876DBD8151816E500DADB95 /* Platform.h in Headers */,
</span><span class="cx">                                 DCEE22021CEA7551000C2396 /* PlatformUserPreferredLanguages.h in Headers */,
</span><ins>+                                E3200AB91E9A536D003B59D2 /* ThreadHolder.h in Headers */,
</ins><span class="cx">                                 0FF860951BCCBD740045127F /* PointerComparison.h in Headers */,
</span><span class="cx">                                 0F9D3363165DBA73005AD387 /* PrintStream.h in Headers */,
</span><span class="cx">                                 0FC4488316FE9FE100844BE9 /* ProcessID.h in Headers */,
</span><span class="lines">@@ -1622,7 +1629,6 @@
</span><span class="cx">                                 1CCDB14F1E566898006C73C0 /* TextBreakIteratorICU.h in Headers */,
</span><span class="cx">                                 A8A47444151A825B004123FF /* TextPosition.h in Headers */,
</span><span class="cx">                                 A8A47447151A825B004123FF /* ThreadFunctionInvocation.h in Headers */,
</span><del>-                                A8A47449151A825B004123FF /* ThreadIdentifierDataPthreads.h in Headers */,
</del><span class="cx">                                 A8A4744B151A825B004123FF /* Threading.h in Headers */,
</span><span class="cx">                                 A8A4744D151A825B004123FF /* ThreadingPrimitives.h in Headers */,
</span><span class="cx">                                 A8A47454151A825B004123FF /* ThreadSafeRefCounted.h in Headers */,
</span><span class="lines">@@ -1648,6 +1654,7 @@
</span><span class="cx">                                 A8A47480151A825B004123FF /* VMTags.h in Headers */,
</span><span class="cx">                                 0F66B2931DC97BAB004A1D3F /* WallTime.h in Headers */,
</span><span class="cx">                                 974CFC8E16A4F327006D5404 /* WeakPtr.h in Headers */,
</span><ins>+                                E3200AB71E9A536D003B59D2 /* PlatformRegisters.h in Headers */,
</ins><span class="cx">                                 0F3501641BB258D500F0A2A3 /* WeakRandom.h in Headers */,
</span><span class="cx">                                 1FA47C8B152502DA00568D1B /* WebCoreThread.h in Headers */,
</span><span class="cx">                                 0FE4479D1B7AAA03009498EB /* WordLock.h in Headers */,
</span><span class="lines">@@ -1830,6 +1837,7 @@
</span><span class="cx">                                 A748745217A0BDAE00FA04CB /* SixCharacterHash.cpp in Sources */,
</span><span class="cx">                                 A8A47425151A825B004123FF /* SizeLimits.cpp in Sources */,
</span><span class="cx">                                 A8A47427151A825B004123FF /* StackBounds.cpp in Sources */,
</span><ins>+                                E3200AB81E9A536D003B59D2 /* ThreadHolder.cpp in Sources */,
</ins><span class="cx">                                 FEDACD3D1630F83F00C69634 /* StackStats.cpp in Sources */,
</span><span class="cx">                                 A8A4743C151A825B004123FF /* StringBuilder.cpp in Sources */,
</span><span class="cx">                                 A5BA15FB182435A600A82E69 /* StringCF.cpp in Sources */,
</span><span class="lines">@@ -1847,7 +1855,7 @@
</span><span class="cx">                                 70A993FE1AD7151300FA615B /* SymbolRegistry.cpp in Sources */,
</span><span class="cx">                                 1C181C7F1D3078DA00F5FA16 /* TextBreakIterator.cpp in Sources */,
</span><span class="cx">                                 1C181C961D30800A00F5FA16 /* TextBreakIteratorInternalICUMac.mm in Sources */,
</span><del>-                                A8A47448151A825B004123FF /* ThreadIdentifierDataPthreads.cpp in Sources */,
</del><ins>+                                A8A47448151A825B004123FF /* ThreadHolderPthreads.cpp in Sources */,
</ins><span class="cx">                                 A8A4744A151A825B004123FF /* Threading.cpp in Sources */,
</span><span class="cx">                                 A8A4744E151A825B004123FF /* ThreadingPthreads.cpp in Sources */,
</span><span class="cx">                                 0F66B2901DC97BAB004A1D3F /* TimeWithDynamicClockType.cpp in Sources */,
</span></span></pre></div>
<a id="trunkSourceWTFbenchmarksConditionSpeedTestcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/benchmarks/ConditionSpeedTest.cpp (215264 => 215265)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/benchmarks/ConditionSpeedTest.cpp        2017-04-12 10:14:30 UTC (rev 215264)
+++ trunk/Source/WTF/benchmarks/ConditionSpeedTest.cpp        2017-04-12 12:08:29 UTC (rev 215265)
</span><span class="lines">@@ -79,14 +79,14 @@
</span><span class="cx">     ConditionType emptyCondition;
</span><span class="cx">     ConditionType fullCondition;
</span><span class="cx"> 
</span><del>-    Vector&lt;ThreadIdentifier&gt; consumerThreads;
-    Vector&lt;ThreadIdentifier&gt; producerThreads;
</del><ins>+    Vector&lt;RefPtr&lt;Thread&gt;&gt; consumerThreads;
+    Vector&lt;RefPtr&lt;Thread&gt;&gt; producerThreads;
</ins><span class="cx"> 
</span><span class="cx">     Vector&lt;unsigned&gt; received;
</span><span class="cx">     LockType receivedLock;
</span><span class="cx">     
</span><span class="cx">     for (unsigned i = numConsumers; i--;) {
</span><del>-        ThreadIdentifier threadIdentifier = createThread(
</del><ins>+        RefPtr&lt;Thread&gt; thread = Thread::create(
</ins><span class="cx">             &quot;Consumer thread&quot;,
</span><span class="cx">             [&amp;] () {
</span><span class="cx">                 for (;;) {
</span><span class="lines">@@ -98,7 +98,7 @@
</span><span class="cx">                             emptyCondition, lock,
</span><span class="cx">                             [&amp;] () {
</span><span class="cx">                                 if (verbose)
</span><del>-                                    dataLog(toString(currentThread(), &quot;: Checking consumption predicate with shouldContinue = &quot;, shouldContinue, &quot;, queue.size() == &quot;, queue.size(), &quot;\n&quot;));
</del><ins>+                                    dataLog(toString(Thread::current(), &quot;: Checking consumption predicate with shouldContinue = &quot;, shouldContinue, &quot;, queue.size() == &quot;, queue.size(), &quot;\n&quot;));
</ins><span class="cx">                                 return !shouldContinue || !queue.isEmpty();
</span><span class="cx">                             });
</span><span class="cx">                         if (!shouldContinue &amp;&amp; queue.isEmpty())
</span><span class="lines">@@ -114,11 +114,11 @@
</span><span class="cx">                     }
</span><span class="cx">                 }
</span><span class="cx">             });
</span><del>-        consumerThreads.append(threadIdentifier);
</del><ins>+        consumerThreads.append(thread);
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     for (unsigned i = numProducers; i--;) {
</span><del>-        ThreadIdentifier threadIdentifier = createThread(
</del><ins>+        RefPtr&lt;Thread&gt; thread = Thread::create(
</ins><span class="cx">             &quot;Producer Thread&quot;,
</span><span class="cx">             [&amp;] () {
</span><span class="cx">                 for (unsigned i = 0; i &lt; numMessagesPerProducer; ++i) {
</span><span class="lines">@@ -129,7 +129,7 @@
</span><span class="cx">                             fullCondition, lock,
</span><span class="cx">                             [&amp;] () {
</span><span class="cx">                                 if (verbose)
</span><del>-                                    dataLog(toString(currentThread(), &quot;: Checking production predicate with shouldContinue = &quot;, shouldContinue, &quot;, queue.size() == &quot;, queue.size(), &quot;\n&quot;));
</del><ins>+                                    dataLog(toString(Thread::current(), &quot;: Checking production predicate with shouldContinue = &quot;, shouldContinue, &quot;, queue.size() == &quot;, queue.size(), &quot;\n&quot;));
</ins><span class="cx">                                 return queue.size() &lt; maxQueueSize;
</span><span class="cx">                             });
</span><span class="cx">                         mustNotify = queue.isEmpty();
</span><span class="lines">@@ -138,11 +138,11 @@
</span><span class="cx">                     notify(emptyCondition, mustNotify);
</span><span class="cx">                 }
</span><span class="cx">             });
</span><del>-        producerThreads.append(threadIdentifier);
</del><ins>+        producerThreads.append(thread);
</ins><span class="cx">     }
</span><span class="cx"> 
</span><del>-    for (ThreadIdentifier threadIdentifier : producerThreads)
-        waitForThreadCompletion(threadIdentifier);
</del><ins>+    for (RefPtr&lt;Thread&gt;&amp; thread : producerThreads)
+        thread-&gt;waitForCompletion();
</ins><span class="cx"> 
</span><span class="cx">     {
</span><span class="cx">         std::lock_guard&lt;LockType&gt; locker(lock);
</span></span></pre></div>
<a id="trunkSourceWTFbenchmarksLockFairnessTestcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/benchmarks/LockFairnessTest.cpp (215264 => 215265)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/benchmarks/LockFairnessTest.cpp        2017-04-12 10:14:30 UTC (rev 215264)
+++ trunk/Source/WTF/benchmarks/LockFairnessTest.cpp        2017-04-12 12:08:29 UTC (rev 215265)
</span><span class="lines">@@ -62,7 +62,7 @@
</span><span class="cx">     {
</span><span class="cx">         LockType lock;
</span><span class="cx">         std::unique_ptr&lt;unsigned[]&gt; counts = std::make_unique&lt;unsigned[]&gt;(numThreads);
</span><del>-        std::unique_ptr&lt;ThreadIdentifier[]&gt; threads = std::make_unique&lt;ThreadIdentifier[]&gt;(numThreads);
</del><ins>+        std::unique_ptr&lt;RefPtr&lt;Thread&gt;[]&gt; threads = std::make_unique&lt;RefPtr&lt;Thread&gt;[]&gt;(numThreads);
</ins><span class="cx">     
</span><span class="cx">         volatile bool keepGoing = true;
</span><span class="cx">     
</span><span class="lines">@@ -70,7 +70,7 @@
</span><span class="cx">     
</span><span class="cx">         for (unsigned threadIndex = numThreads; threadIndex--;) {
</span><span class="cx">             counts[threadIndex] = 0;
</span><del>-            threads[threadIndex] = createThread(
</del><ins>+            threads[threadIndex] = Thread::create(
</ins><span class="cx">                 &quot;Benchmark Thread&quot;,
</span><span class="cx">                 [&amp;, threadIndex] () {
</span><span class="cx">                     if (!microsecondsInCriticalSection) {
</span><span class="lines">@@ -107,7 +107,7 @@
</span><span class="cx">     
</span><span class="cx">         lock.unlock();
</span><span class="cx">         for (unsigned threadIndex = numThreads; threadIndex--;)
</span><del>-            waitForThreadCompletion(threads[threadIndex]);
</del><ins>+            threads[threadIndex]-&gt;waitForCompletion();
</ins><span class="cx">     }
</span><span class="cx"> };
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWTFbenchmarksLockSpeedTestcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/benchmarks/LockSpeedTest.cpp (215264 => 215265)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/benchmarks/LockSpeedTest.cpp        2017-04-12 10:14:30 UTC (rev 215264)
+++ trunk/Source/WTF/benchmarks/LockSpeedTest.cpp        2017-04-12 12:08:29 UTC (rev 215265)
</span><span class="lines">@@ -77,7 +77,7 @@
</span><span class="cx">     {
</span><span class="cx">         std::unique_ptr&lt;WithPadding&lt;LockType&gt;[]&gt; locks = std::make_unique&lt;WithPadding&lt;LockType&gt;[]&gt;(numThreadGroups);
</span><span class="cx">         std::unique_ptr&lt;WithPadding&lt;double&gt;[]&gt; words = std::make_unique&lt;WithPadding&lt;double&gt;[]&gt;(numThreadGroups);
</span><del>-        std::unique_ptr&lt;ThreadIdentifier[]&gt; threads = std::make_unique&lt;ThreadIdentifier[]&gt;(numThreadGroups * numThreadsPerGroup);
</del><ins>+        std::unique_ptr&lt;RefPtr&lt;Thread&gt;[]&gt; threads = std::make_unique&lt;Refptr&lt;Thread&gt;[]&gt;(numThreadGroups * numThreadsPerGroup);
</ins><span class="cx"> 
</span><span class="cx">         volatile bool keepGoing = true;
</span><span class="cx"> 
</span><span class="lines">@@ -90,7 +90,7 @@
</span><span class="cx">             words[threadGroupIndex].value = 0;
</span><span class="cx"> 
</span><span class="cx">             for (unsigned threadIndex = numThreadsPerGroup; threadIndex--;) {
</span><del>-                threads[threadGroupIndex * numThreadsPerGroup + threadIndex] = createThread(
</del><ins>+                threads[threadGroupIndex * numThreadsPerGroup + threadIndex] = Thread::create(
</ins><span class="cx">                     &quot;Benchmark thread&quot;,
</span><span class="cx">                     [threadGroupIndex, &amp;locks, &amp;words, &amp;keepGoing, &amp;numIterationsLock, &amp;numIterations] () {
</span><span class="cx">                         double localWord = 0;
</span><span class="lines">@@ -121,7 +121,7 @@
</span><span class="cx">         keepGoing = false;
</span><span class="cx">     
</span><span class="cx">         for (unsigned threadIndex = numThreadGroups * numThreadsPerGroup; threadIndex--;)
</span><del>-            waitForThreadCompletion(threads[threadIndex]);
</del><ins>+            threads[threadIndex]-&gt;waitForCompletion();
</ins><span class="cx"> 
</span><span class="cx">         double after = monotonicallyIncreasingTime();
</span><span class="cx">     
</span></span></pre></div>
<a id="trunkSourceWTFwtfAutomaticThreadcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/wtf/AutomaticThread.cpp (215264 => 215265)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/wtf/AutomaticThread.cpp        2017-04-12 10:14:30 UTC (rev 215264)
+++ trunk/Source/WTF/wtf/AutomaticThread.cpp        2017-04-12 12:08:29 UTC (rev 215265)
</span><span class="lines">@@ -155,7 +155,7 @@
</span><span class="cx">     
</span><span class="cx">     m_hasUnderlyingThread = true;
</span><span class="cx">     
</span><del>-    ThreadIdentifier thread = createThread(
</del><ins>+    RefPtr&lt;Thread&gt; thread = Thread::create(
</ins><span class="cx">         &quot;WTF::AutomaticThread&quot;,
</span><span class="cx">         [=] () {
</span><span class="cx">             if (verbose)
</span><span class="lines">@@ -220,7 +220,7 @@
</span><span class="cx">                 RELEASE_ASSERT(result == WorkResult::Continue);
</span><span class="cx">             }
</span><span class="cx">         });
</span><del>-    detachThread(thread);
</del><ins>+    thread-&gt;detach();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void AutomaticThread::threadDidStart()
</span></span></pre></div>
<a id="trunkSourceWTFwtfCMakeListstxt"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/wtf/CMakeLists.txt (215264 => 215265)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/wtf/CMakeLists.txt        2017-04-12 10:14:30 UTC (rev 215264)
+++ trunk/Source/WTF/wtf/CMakeLists.txt        2017-04-12 12:08:29 UTC (rev 215265)
</span><span class="lines">@@ -95,6 +95,7 @@
</span><span class="cx">     ParkingLot.h
</span><span class="cx">     PassRefPtr.h
</span><span class="cx">     Platform.h
</span><ins>+    PlatformRegisters.h
</ins><span class="cx">     PrintStream.h
</span><span class="cx">     ProcessID.h
</span><span class="cx">     RAMSize.h
</span><span class="lines">@@ -128,7 +129,7 @@
</span><span class="cx">     StringExtras.h
</span><span class="cx">     StringPrintStream.h
</span><span class="cx">     SystemTracing.h
</span><del>-    ThreadIdentifierDataPthreads.h
</del><ins>+    ThreadHolder.cpp
</ins><span class="cx">     ThreadSafeRefCounted.h
</span><span class="cx">     ThreadSpecific.h
</span><span class="cx">     Threading.h
</span><span class="lines">@@ -329,16 +330,14 @@
</span><span class="cx"> if (WIN32)
</span><span class="cx">     list(APPEND WTF_SOURCES
</span><span class="cx">         OSAllocatorWin.cpp
</span><ins>+        ThreadHolderWin.cpp
</ins><span class="cx">         ThreadSpecificWin.cpp
</span><span class="cx">         ThreadingWin.cpp
</span><span class="cx">     )
</span><span class="cx"> else ()
</span><del>-    list(APPEND WTF_HEADERS
-        ThreadIdentifierDataPthreads.h
-    )
</del><span class="cx">     list(APPEND WTF_SOURCES
</span><span class="cx">         OSAllocatorPosix.cpp
</span><del>-        ThreadIdentifierDataPthreads.cpp
</del><ins>+        ThreadHolderPthreads.cpp
</ins><span class="cx">         ThreadingPthreads.cpp
</span><span class="cx">     )
</span><span class="cx"> endif ()
</span></span></pre></div>
<a id="trunkSourceWTFwtfMainThreadh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/wtf/MainThread.h (215264 => 215265)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/wtf/MainThread.h        2017-04-12 10:14:30 UTC (rev 215264)
+++ trunk/Source/WTF/wtf/MainThread.h        2017-04-12 12:08:29 UTC (rev 215265)
</span><span class="lines">@@ -34,13 +34,12 @@
</span><span class="cx"> #include &lt;stdint.h&gt;
</span><span class="cx"> #include &lt;wtf/Function.h&gt;
</span><span class="cx"> #include &lt;wtf/Optional.h&gt;
</span><ins>+#include &lt;wtf/Threading.h&gt;
</ins><span class="cx"> 
</span><span class="cx"> namespace WTF {
</span><span class="cx"> 
</span><span class="cx"> class PrintStream;
</span><span class="cx"> 
</span><del>-typedef uint32_t ThreadIdentifier;
-
</del><span class="cx"> // Must be called from the main thread.
</span><span class="cx"> WTF_EXPORT_PRIVATE void initializeMainThread();
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWTFwtfMemoryPressureHandlerh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/wtf/MemoryPressureHandler.h (215264 => 215265)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/wtf/MemoryPressureHandler.h        2017-04-12 10:14:30 UTC (rev 215264)
+++ trunk/Source/WTF/wtf/MemoryPressureHandler.h        2017-04-12 12:08:29 UTC (rev 215265)
</span><span class="lines">@@ -173,7 +173,7 @@
</span><span class="cx"> #if USE(GLIB)
</span><span class="cx">         GRefPtr&lt;GSource&gt; m_source;
</span><span class="cx"> #else
</span><del>-        ThreadIdentifier m_threadID;
</del><ins>+        RefPtr&lt;Thread&gt; m_thread;
</ins><span class="cx"> #endif
</span><span class="cx">     };
</span><span class="cx"> #endif
</span></span></pre></div>
<a id="trunkSourceWTFwtfParallelJobsGenericcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/wtf/ParallelJobsGeneric.cpp (215264 => 215265)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/wtf/ParallelJobsGeneric.cpp        2017-04-12 10:14:30 UTC (rev 215264)
+++ trunk/Source/WTF/wtf/ParallelJobsGeneric.cpp        2017-04-12 12:08:29 UTC (rev 215265)
</span><span class="lines">@@ -93,14 +93,14 @@
</span><span class="cx">         return false;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    if (!m_threadID)
-        m_threadID = createThread(&amp;ParallelEnvironment::ThreadPrivate::workerThread, this, &quot;Parallel worker&quot;);
</del><ins>+    if (!m_thread)
+        m_thread = Thread::create(&amp;ParallelEnvironment::ThreadPrivate::workerThread, this, &quot;Parallel worker&quot;);
</ins><span class="cx"> 
</span><del>-    if (m_threadID)
</del><ins>+    if (m_thread)
</ins><span class="cx">         m_parent = parent;
</span><span class="cx"> 
</span><span class="cx">     m_mutex.unlock();
</span><del>-    return m_threadID;
</del><ins>+    return m_thread;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void ParallelEnvironment::ThreadPrivate::execute(ThreadFunction threadFunction, void* parameters)
</span><span class="lines">@@ -126,7 +126,7 @@
</span><span class="cx">     ThreadPrivate* sharedThread = reinterpret_cast&lt;ThreadPrivate*&gt;(threadData);
</span><span class="cx">     LockHolder lock(sharedThread-&gt;m_mutex);
</span><span class="cx"> 
</span><del>-    while (sharedThread-&gt;m_threadID) {
</del><ins>+    while (sharedThread-&gt;m_thread) {
</ins><span class="cx">         if (sharedThread-&gt;m_running) {
</span><span class="cx">             (*sharedThread-&gt;m_threadFunction)(sharedThread-&gt;m_parameters);
</span><span class="cx">             sharedThread-&gt;m_running = false;
</span></span></pre></div>
<a id="trunkSourceWTFwtfParallelJobsGenerich"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/wtf/ParallelJobsGeneric.h (215264 => 215265)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/wtf/ParallelJobsGeneric.h        2017-04-12 10:14:30 UTC (rev 215264)
+++ trunk/Source/WTF/wtf/ParallelJobsGeneric.h        2017-04-12 12:08:29 UTC (rev 215265)
</span><span class="lines">@@ -53,13 +53,6 @@
</span><span class="cx"> 
</span><span class="cx">     class ThreadPrivate : public RefCounted&lt;ThreadPrivate&gt; {
</span><span class="cx">     public:
</span><del>-        ThreadPrivate()
-            : m_threadID(0)
-            , m_running(false)
-            , m_parent(0)
-        {
-        }
-
</del><span class="cx">         bool tryLockFor(ParallelEnvironment*);
</span><span class="cx"> 
</span><span class="cx">         void execute(ThreadFunction, void*);
</span><span class="lines">@@ -74,9 +67,9 @@
</span><span class="cx">         static void workerThread(void*);
</span><span class="cx"> 
</span><span class="cx">     private:
</span><del>-        ThreadIdentifier m_threadID;
-        bool m_running;
-        ParallelEnvironment* m_parent;
</del><ins>+        RefPtr&lt;Thread&gt; m_thread;
+        bool m_running { false };
+        ParallelEnvironment* m_parent { nullptr };
</ins><span class="cx"> 
</span><span class="cx">         mutable Lock m_mutex;
</span><span class="cx">         Condition m_threadCondition;
</span></span></pre></div>
<a id="trunkSourceWTFwtfParkingLotcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/wtf/ParkingLot.cpp (215264 => 215265)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/wtf/ParkingLot.cpp        2017-04-12 10:14:30 UTC (rev 215264)
+++ trunk/Source/WTF/wtf/ParkingLot.cpp        2017-04-12 12:08:29 UTC (rev 215265)
</span><span class="lines">@@ -52,7 +52,7 @@
</span><span class="cx">     ThreadData();
</span><span class="cx">     ~ThreadData();
</span><span class="cx"> 
</span><del>-    ThreadIdentifier threadIdentifier;
</del><ins>+    Ref&lt;Thread&gt; thread;
</ins><span class="cx">     
</span><span class="cx">     Mutex parkingLock;
</span><span class="cx">     ThreadCondition parkingCondition;
</span><span class="lines">@@ -423,7 +423,7 @@
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> ThreadData::ThreadData()
</span><del>-    : threadIdentifier(currentThread())
</del><ins>+    : thread(Thread::current())
</ins><span class="cx"> {
</span><span class="cx">     unsigned currentNumThreads;
</span><span class="cx">     for (;;) {
</span><span class="lines">@@ -793,7 +793,7 @@
</span><span class="cx">     unparkCount(address, UINT_MAX);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-NEVER_INLINE void ParkingLot::forEachImpl(const ScopedLambda&lt;void(ThreadIdentifier, const void*)&gt;&amp; callback)
</del><ins>+NEVER_INLINE void ParkingLot::forEachImpl(const ScopedLambda&lt;void(Thread&amp;, const void*)&gt;&amp; callback)
</ins><span class="cx"> {
</span><span class="cx">     Vector&lt;Bucket*&gt; bucketsToUnlock = lockHashtable();
</span><span class="cx"> 
</span><span class="lines">@@ -803,7 +803,7 @@
</span><span class="cx">         if (!bucket)
</span><span class="cx">             continue;
</span><span class="cx">         for (ThreadData* currentThreadData = bucket-&gt;queueHead; currentThreadData; currentThreadData = currentThreadData-&gt;nextInQueue)
</span><del>-            callback(currentThreadData-&gt;threadIdentifier, currentThreadData-&gt;address);
</del><ins>+            callback(currentThreadData-&gt;thread.get(), currentThreadData-&gt;address);
</ins><span class="cx">     }
</span><span class="cx">     
</span><span class="cx">     unlockHashtable(bucketsToUnlock);
</span></span></pre></div>
<a id="trunkSourceWTFwtfParkingLoth"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/wtf/ParkingLot.h (215264 => 215265)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/wtf/ParkingLot.h        2017-04-12 10:14:30 UTC (rev 215264)
+++ trunk/Source/WTF/wtf/ParkingLot.h        2017-04-12 12:08:29 UTC (rev 215265)
</span><span class="lines">@@ -158,7 +158,7 @@
</span><span class="cx">     template&lt;typename Func&gt;
</span><span class="cx">     static void forEach(const Func&amp; func)
</span><span class="cx">     {
</span><del>-        forEachImpl(scopedLambdaRef&lt;void(ThreadIdentifier, const void*)&gt;(func));
</del><ins>+        forEachImpl(scopedLambdaRef&lt;void(Thread&amp;, const void*)&gt;(func));
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx"> private:
</span><span class="lines">@@ -171,7 +171,7 @@
</span><span class="cx">     WTF_EXPORT_PRIVATE static void unparkOneImpl(
</span><span class="cx">         const void* address, const ScopedLambda&lt;intptr_t(UnparkResult)&gt;&amp; callback);
</span><span class="cx"> 
</span><del>-    WTF_EXPORT_PRIVATE static void forEachImpl(const ScopedLambda&lt;void(ThreadIdentifier, const void*)&gt;&amp;);
</del><ins>+    WTF_EXPORT_PRIVATE static void forEachImpl(const ScopedLambda&lt;void(Thread&amp;, const void*)&gt;&amp;);
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> } // namespace WTF
</span></span></pre></div>
<a id="trunkSourceWTFwtfPlatformRegistershfromrev215264trunkSourceJavaScriptCoreruntimePlatformThreadh"></a>
<div class="copfile"><h4>Copied: trunk/Source/WTF/wtf/PlatformRegisters.h (from rev 215264, trunk/Source/JavaScriptCore/runtime/PlatformThread.h) (0 => 215265)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/wtf/PlatformRegisters.h                                (rev 0)
+++ trunk/Source/WTF/wtf/PlatformRegisters.h        2017-04-12 12:08:29 UTC (rev 215265)
</span><span class="lines">@@ -0,0 +1,74 @@
</span><ins>+/*
+ * Copyright (C) 2017 Yusuke Suzuki &lt;utatane.tea@gmail.com&gt;
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GOOGLE, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include &lt;wtf/Platform.h&gt;
+
+#if OS(DARWIN)
+#include &lt;mach/thread_act.h&gt;
+#elif OS(WINDOWS)
+#include &lt;windows.h&gt;
+#else
+#include &lt;ucontext.h&gt;
+#endif
+
+namespace WTF {
+
+#if OS(DARWIN)
+
+#if CPU(X86)
+typedef i386_thread_state_t PlatformRegisters;
+#elif CPU(X86_64)
+typedef x86_thread_state64_t PlatformRegisters;
+#elif CPU(PPC)
+typedef ppc_thread_state_t PlatformRegisters;
+#elif CPU(PPC64)
+typedef ppc_thread_state64_t PlatformRegisters;
+#elif CPU(ARM)
+typedef arm_thread_state_t PlatformRegisters;
+#elif CPU(ARM64)
+typedef arm_thread_state64_t PlatformRegisters;
+#else
+#error Unknown Architecture
+#endif
+
+#elif OS(WINDOWS)
+
+using PlatformRegisters = CONTEXT;
+
+#elif (OS(FREEBSD) || defined(__GLIBC__)) &amp;&amp; (CPU(X86) || CPU(X86_64) || CPU(ARM) || CPU(ARM64) || CPU(MIPS))
+
+using PlatformRegisters = mcontext_t;
+
+#else
+
+struct PlatformRegisters {
+    void* stackPointer;
+};
+
+#endif
+
+} // namespace WTF
</ins></span></pre></div>
<a id="trunkSourceWTFwtfRefPtrh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/wtf/RefPtr.h (215264 => 215265)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/wtf/RefPtr.h        2017-04-12 10:14:30 UTC (rev 215264)
+++ trunk/Source/WTF/wtf/RefPtr.h        2017-04-12 12:08:29 UTC (rev 215265)
</span><span class="lines">@@ -42,7 +42,7 @@
</span><span class="cx"> 
</span><span class="cx">     static constexpr bool isRefPtr = true;
</span><span class="cx"> 
</span><del>-    ALWAYS_INLINE RefPtr() : m_ptr(nullptr) { }
</del><ins>+    ALWAYS_INLINE constexpr RefPtr() : m_ptr(nullptr) { }
</ins><span class="cx">     ALWAYS_INLINE RefPtr(T* ptr) : m_ptr(ptr) { refIfNotNull(ptr); }
</span><span class="cx">     ALWAYS_INLINE RefPtr(const RefPtr&amp; o) : m_ptr(o.m_ptr) { refIfNotNull(m_ptr); }
</span><span class="cx">     template&lt;typename U&gt; RefPtr(const RefPtr&lt;U&gt;&amp; o) : m_ptr(o.get()) { refIfNotNull(m_ptr); }
</span></span></pre></div>
<a id="trunkSourceWTFwtfThreadFunctionInvocationh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/wtf/ThreadFunctionInvocation.h (215264 => 215265)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/wtf/ThreadFunctionInvocation.h        2017-04-12 10:14:30 UTC (rev 215264)
+++ trunk/Source/WTF/wtf/ThreadFunctionInvocation.h        2017-04-12 12:08:29 UTC (rev 215265)
</span><span class="lines">@@ -29,6 +29,8 @@
</span><span class="cx"> #ifndef ThreadFunctionInvocation_h
</span><span class="cx"> #define ThreadFunctionInvocation_h
</span><span class="cx"> 
</span><ins>+#include &quot;Threading.h&quot;
+
</ins><span class="cx"> namespace WTF {
</span><span class="cx"> 
</span><span class="cx"> typedef void (*ThreadFunction)(void* argument);
</span><span class="lines">@@ -36,13 +38,15 @@
</span><span class="cx"> struct ThreadFunctionInvocation {
</span><span class="cx">     WTF_MAKE_FAST_ALLOCATED;
</span><span class="cx"> public:
</span><del>-    ThreadFunctionInvocation(ThreadFunction function, void* data)
</del><ins>+    ThreadFunctionInvocation(ThreadFunction function, RefPtr&lt;Thread&gt;&amp;&amp; thread, void* data)
</ins><span class="cx">         : function(function)
</span><ins>+        , thread(WTFMove(thread))
</ins><span class="cx">         , data(data)
</span><span class="cx">     {
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     ThreadFunction function;
</span><ins>+    RefPtr&lt;Thread&gt; thread;
</ins><span class="cx">     void* data;
</span><span class="cx"> };
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWTFwtfThreadHoldercpp"></a>
<div class="addfile"><h4>Added: trunk/Source/WTF/wtf/ThreadHolder.cpp (0 => 215265)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/wtf/ThreadHolder.cpp                                (rev 0)
+++ trunk/Source/WTF/wtf/ThreadHolder.cpp        2017-04-12 12:08:29 UTC (rev 215265)
</span><span class="lines">@@ -0,0 +1,57 @@
</span><ins>+/*
+ * Copyright (C) 2009, 2011 Google Inc. All rights reserved.
+ * Copyright (C) 2017 Yusuke Suzuki &lt;utatane.tea@gmail.com&gt;.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * &quot;AS IS&quot; AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include &quot;config.h&quot;
+#include &quot;ThreadHolder.h&quot;
+
+#include &quot;Threading.h&quot;
+
+namespace WTF {
+
+ThreadSpecificKey ThreadHolder::m_key = InvalidThreadSpecificKey;
+
+ThreadHolder::~ThreadHolder()
+{
+    m_thread-&gt;didExit();
+}
+
+void ThreadHolder::initialize(Thread&amp; thread)
+{
+    if (!current()) {
+        // Ideally we'd have this as a release assert everywhere, but that would hurt performance.
+        // Having this release assert here means that we will catch &quot;didn't call
+        // WTF::initializeThreading() soon enough&quot; bugs in release mode.
+        ASSERT(m_key != InvalidThreadSpecificKey);
+        threadSpecificSet(m_key, new ThreadHolder(thread));
+    }
+}
+
+} // namespace WTF
</ins></span></pre></div>
<a id="trunkSourceWTFwtfThreadHolderhfromrev215264trunkSourceWTFwtfThreadIdentifierDataPthreadsh"></a>
<div class="copfile"><h4>Copied: trunk/Source/WTF/wtf/ThreadHolder.h (from rev 215264, trunk/Source/WTF/wtf/ThreadIdentifierDataPthreads.h) (0 => 215265)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/wtf/ThreadHolder.h                                (rev 0)
+++ trunk/Source/WTF/wtf/ThreadHolder.h        2017-04-12 12:08:29 UTC (rev 215265)
</span><span class="lines">@@ -0,0 +1,79 @@
</span><ins>+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ * Copyright (C) 2017 Yusuke Suzuki &lt;utatane.tea@gmail.com&gt;.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * &quot;AS IS&quot; AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include &lt;wtf/ThreadSpecific.h&gt;
+#include &lt;wtf/Threading.h&gt;
+
+namespace WTF {
+
+// Holds Thread in the thread-specific storage. The destructor of this holder reliably destroy Thread.
+// For pthread, it employs pthreads-specific 2-pass destruction to reliably remove Thread.
+// For Windows, we use thread_local to defer thread holder destruction. It assumes regular ThreadSpecific
+// types don't use multiple-pass destruction.
+class ThreadHolder {
+    WTF_MAKE_NONCOPYABLE(ThreadHolder);
+public:
+    ~ThreadHolder();
+
+    // One time initialization for this class as a whole.
+    // This method must be called before initialize() and it is not thread-safe.
+    static void initializeOnce();
+
+    // Creates and puts an instance of ThreadHolder into thread-specific storage.
+    static void initialize(Thread&amp;);
+
+    // Returns 0 if thread-specific storage was not initialized.
+    static ThreadHolder* current();
+
+    Thread&amp; thread() { return m_thread.get(); }
+
+private:
+    ThreadHolder(Thread&amp; thread)
+        : m_thread(thread)
+        , m_isDestroyedOnce(false)
+    {
+    }
+
+    // This thread-specific destructor is called 2 times when thread terminates:
+    // - first, when all the other thread-specific destructors are called, it simply remembers it was 'destroyed once'
+    // and (1) re-sets itself into the thread-specific slot or (2) constructs thread local value to call it again later.
+    // - second, after all thread-specific destructors were invoked, it gets called again - this time, we remove the
+    // Thread from the threadMap, completing the cleanup.
+    static void THREAD_SPECIFIC_CALL destruct(void* data);
+
+    Ref&lt;Thread&gt; m_thread;
+    bool m_isDestroyedOnce;
+    static ThreadSpecificKey m_key;
+};
+
+} // namespace WTF
</ins></span></pre></div>
<a id="trunkSourceWTFwtfThreadHolderPthreadscppfromrev215264trunkSourceWTFwtfThreadIdentifierDataPthreadscpp"></a>
<div class="copfile"><h4>Copied: trunk/Source/WTF/wtf/ThreadHolderPthreads.cpp (from rev 215264, trunk/Source/WTF/wtf/ThreadIdentifierDataPthreads.cpp) (0 => 215265)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/wtf/ThreadHolderPthreads.cpp                                (rev 0)
+++ trunk/Source/WTF/wtf/ThreadHolderPthreads.cpp        2017-04-12 12:08:29 UTC (rev 215265)
</span><span class="lines">@@ -0,0 +1,65 @@
</span><ins>+/*
+ * Copyright (C) 2009, 2011 Google Inc. All rights reserved.
+ * Copyright (C) 2017 Yusuke Suzuki &lt;utatane.tea@gmail.com&gt;.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * &quot;AS IS&quot; AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include &quot;config.h&quot;
+#include &quot;ThreadHolder.h&quot;
+
+#include &lt;wtf/Threading.h&gt;
+
+namespace WTF {
+
+void ThreadHolder::initializeOnce()
+{
+    threadSpecificKeyCreate(&amp;m_key, destruct);
+}
+
+ThreadHolder* ThreadHolder::current()
+{
+    ASSERT(m_key != InvalidThreadSpecificKey);
+    return static_cast&lt;ThreadHolder*&gt;(threadSpecificGet(m_key));
+}
+
+void ThreadHolder::destruct(void* data)
+{
+    ThreadHolder* threadIdentifierData = static_cast&lt;ThreadHolder*&gt;(data);
+    ASSERT(threadIdentifierData);
+
+    if (threadIdentifierData-&gt;m_isDestroyedOnce) {
+        delete threadIdentifierData;
+        return;
+    }
+
+    threadIdentifierData-&gt;m_isDestroyedOnce = true;
+    // Re-setting the value for key causes another destruct() call after all other thread-specific destructors were called.
+    threadSpecificSet(m_key, threadIdentifierData);
+}
+
+} // namespace WTF
</ins></span></pre></div>
<a id="trunkSourceWTFwtfThreadHolderWincpp"></a>
<div class="addfile"><h4>Added: trunk/Source/WTF/wtf/ThreadHolderWin.cpp (0 => 215265)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/wtf/ThreadHolderWin.cpp                                (rev 0)
+++ trunk/Source/WTF/wtf/ThreadHolderWin.cpp        2017-04-12 12:08:29 UTC (rev 215265)
</span><span class="lines">@@ -0,0 +1,122 @@
</span><ins>+/*
+ * Copyright (C) 2017 Yusuke Suzuki &lt;utatane.tea@gmail.com&gt;.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * &quot;AS IS&quot; AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include &quot;config.h&quot;
+#include &quot;ThreadHolder.h&quot;
+
+#include &lt;mutex&gt;
+#include &lt;wtf/HashMap.h&gt;
+#include &lt;wtf/NeverDestroyed.h&gt;
+#include &lt;wtf/Threading.h&gt;
+
+namespace WTF {
+
+#define InvalidThreadHolder ((ThreadHolder*)(0xbbadbeef))
+
+static std::mutex&amp; threadMapMutex()
+{
+    static NeverDestroyed&lt;std::mutex&gt; mutex;
+    return mutex.get();
+}
+
+static HashMap&lt;ThreadIdentifier, ThreadHolder*&gt;&amp; threadMap()
+{
+    static NeverDestroyed&lt;HashMap&lt;ThreadIdentifier, ThreadHolder*&gt;&gt; map;
+    return map.get();
+}
+
+void ThreadHolder::initializeOnce()
+{
+    threadMapMutex();
+    threadMap();
+    threadSpecificKeyCreate(&amp;m_key, destruct);
+}
+
+ThreadHolder* ThreadHolder::current()
+{
+    ASSERT(m_key != InvalidThreadSpecificKey);
+    ThreadHolder* holder = static_cast&lt;ThreadHolder*&gt;(threadSpecificGet(m_key));
+    if (holder) {
+        ASSERT(holder != InvalidThreadHolder);
+        return holder;
+    }
+
+    // After FLS is destroyed, this map offers the value until the second thread exit callback is called.
+    std::unique_lock&lt;std::mutex&gt; locker(threadMapMutex());
+    return threadMap().get(currentThread());
+}
+
+void ThreadHolder::destruct(void* data)
+{
+    if (data == InvalidThreadHolder)
+        return;
+
+    ThreadHolder* holder = static_cast&lt;ThreadHolder*&gt;(data);
+    ASSERT(holder);
+
+    // Delay the deallocation of ThreadHolder more.
+    // It defers ThreadHolder deallocation after the other ThreadSpecific values are deallocated.
+    static thread_local class ThreadExitCallback {
+    public:
+        ThreadExitCallback(ThreadHolder* holder)
+            : m_holder(holder)
+        {
+        }
+
+        ~ThreadExitCallback()
+        {
+            ThreadHolder::destruct(m_holder);
+        }
+
+    private:
+        ThreadHolder* m_holder;
+    } callback(holder);
+
+    if (holder-&gt;m_isDestroyedOnce) {
+        {
+            std::unique_lock&lt;std::mutex&gt; locker(threadMapMutex());
+            ASSERT(threadMap().contains(holder-&gt;m_thread-&gt;id()));
+            threadMap().remove(holder-&gt;m_thread-&gt;id());
+        }
+        delete holder;
+
+        // Fill the FLS with the non-nullptr value. While FLS destructor won't be called for that,
+        // non-nullptr value tells us that we already destructed ThreadHolder. This allows us to
+        // detect incorrect use of Thread::current() after this point because it will crash.
+        threadSpecificSet(m_key, InvalidThreadHolder);
+        return;
+    }
+
+    {
+        std::unique_lock&lt;std::mutex&gt; locker(threadMapMutex());
+        threadMap().add(holder-&gt;m_thread-&gt;id(), holder);
+    }
+    threadSpecificSet(m_key, InvalidThreadHolder);
+    holder-&gt;m_isDestroyedOnce = true;
+}
+
+} // namespace WTF
</ins></span></pre></div>
<a id="trunkSourceWTFwtfThreadIdentifierDataPthreadscpp"></a>
<div class="delfile"><h4>Deleted: trunk/Source/WTF/wtf/ThreadIdentifierDataPthreads.cpp (215264 => 215265)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/wtf/ThreadIdentifierDataPthreads.cpp        2017-04-12 10:14:30 UTC (rev 215264)
+++ trunk/Source/WTF/wtf/ThreadIdentifierDataPthreads.cpp        2017-04-12 12:08:29 UTC (rev 215265)
</span><span class="lines">@@ -1,99 +0,0 @@
</span><del>-/*
- * Copyright (C) 2009, 2011 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * &quot;AS IS&quot; AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include &quot;config.h&quot;
-
-#if USE(PTHREADS)
-
-#include &quot;ThreadIdentifierDataPthreads.h&quot;
-
-#include &quot;Threading.h&quot;
-
-#if OS(HURD)
-// PTHREAD_KEYS_MAX is not defined in bionic nor in Hurd, so explicitly define it here.
-#define PTHREAD_KEYS_MAX 1024
-#else
-#include &lt;limits.h&gt;
-#endif
-
-namespace WTF {
-
-pthread_key_t ThreadIdentifierData::m_key = PTHREAD_KEYS_MAX;
-
-void threadDidExit(ThreadIdentifier);
-
-ThreadIdentifierData::~ThreadIdentifierData()
-{
-    threadDidExit(m_identifier);
-}
-
-void ThreadIdentifierData::initializeOnce()
-{
-    int error = pthread_key_create(&amp;m_key, destruct);
-    if (error)
-        CRASH();
-}
-
-ThreadIdentifier ThreadIdentifierData::identifier()
-{
-    ASSERT(m_key != PTHREAD_KEYS_MAX);
-    ThreadIdentifierData* threadIdentifierData = static_cast&lt;ThreadIdentifierData*&gt;(pthread_getspecific(m_key));
-
-    return threadIdentifierData ? threadIdentifierData-&gt;m_identifier : 0;
-}
-
-void ThreadIdentifierData::initialize(ThreadIdentifier id)
-{
-    ASSERT(!identifier());
-    // Ideally we'd have this as a release assert everywhere, but that would hurt performane.
-    // Having this release assert here means that we will catch &quot;didn't call
-    // WTF::initializeThreading() soon enough&quot; bugs in release mode.
-    RELEASE_ASSERT(m_key != PTHREAD_KEYS_MAX);
-    pthread_setspecific(m_key, new ThreadIdentifierData(id));
-}
-
-void ThreadIdentifierData::destruct(void* data)
-{
-    ThreadIdentifierData* threadIdentifierData = static_cast&lt;ThreadIdentifierData*&gt;(data);
-    ASSERT(threadIdentifierData);
-
-    if (threadIdentifierData-&gt;m_isDestroyedOnce) {
-        delete threadIdentifierData;
-        return;
-    }
-
-    threadIdentifierData-&gt;m_isDestroyedOnce = true;
-    // Re-setting the value for key causes another destruct() call after all other thread-specific destructors were called.
-    pthread_setspecific(m_key, threadIdentifierData);
-}
-
-} // namespace WTF
-
-#endif // USE(PTHREADS)
</del></span></pre></div>
<a id="trunkSourceWTFwtfThreadIdentifierDataPthreadsh"></a>
<div class="delfile"><h4>Deleted: trunk/Source/WTF/wtf/ThreadIdentifierDataPthreads.h (215264 => 215265)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/wtf/ThreadIdentifierDataPthreads.h        2017-04-12 10:14:30 UTC (rev 215264)
+++ trunk/Source/WTF/wtf/ThreadIdentifierDataPthreads.h        2017-04-12 12:08:29 UTC (rev 215265)
</span><span class="lines">@@ -1,78 +0,0 @@
</span><del>-/*
- * Copyright (C) 2009 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * &quot;AS IS&quot; AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef ThreadIdentifierDataPthreads_h
-#define ThreadIdentifierDataPthreads_h
-
-#include &lt;wtf/Threading.h&gt;
-
-namespace WTF {
-
-// Holds ThreadIdentifier in the thread-specific storage and employs pthreads-specific 2-pass destruction to reliably remove
-// ThreadIdentifier from threadMap. It assumes regular ThreadSpecific types don't use multiple-pass destruction.
-class ThreadIdentifierData {
-    WTF_MAKE_NONCOPYABLE(ThreadIdentifierData);
-public:
-    ~ThreadIdentifierData();
-
-    // One time initialization for this class as a whole.
-    // This method must be called before initialize() and it is not thread-safe.
-    static void initializeOnce();
-
-    // Creates and puts an instance of ThreadIdentifierData into thread-specific storage.
-    static void initialize(ThreadIdentifier identifier);
-
-    // Returns 0 if thread-specific storage was not initialized.
-    static ThreadIdentifier identifier();
-
-private:
-    ThreadIdentifierData(ThreadIdentifier identifier)
-        : m_identifier(identifier)
-        , m_isDestroyedOnce(false)
-    {
-    }
-
-    // This thread-specific destructor is called 2 times when thread terminates:
-    // - first, when all the other thread-specific destructors are called, it simply remembers it was 'destroyed once'
-    // and re-sets itself into the thread-specific slot to make Pthreads to call it again later.
-    // - second, after all thread-specific destructors were invoked, it gets called again - this time, we remove the
-    // ThreadIdentifier from the threadMap, completing the cleanup.
-    static void destruct(void* data);
-
-    ThreadIdentifier m_identifier;
-    bool m_isDestroyedOnce;
-    static pthread_key_t m_key;
-};
-
-} // namespace WTF
-
-#endif // ThreadIdentifierDataPthreads_h
-
-
</del></span></pre></div>
<a id="trunkSourceWTFwtfThreadSpecifich"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/wtf/ThreadSpecific.h (215264 => 215265)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/wtf/ThreadSpecific.h        2017-04-12 10:14:30 UTC (rev 215264)
+++ trunk/Source/WTF/wtf/ThreadSpecific.h        2017-04-12 12:08:29 UTC (rev 215265)
</span><span class="lines">@@ -48,6 +48,14 @@
</span><span class="cx"> 
</span><span class="cx"> #if USE(PTHREADS)
</span><span class="cx"> #include &lt;pthread.h&gt;
</span><ins>+
+#if OS(HURD)
+// PTHREAD_KEYS_MAX is not defined in bionic nor in Hurd, so explicitly define it here.
+#define PTHREAD_KEYS_MAX 1024
+#else
+#include &lt;limits.h&gt;
+#endif
+
</ins><span class="cx"> #elif OS(WINDOWS)
</span><span class="cx"> #include &lt;windows.h&gt;
</span><span class="cx"> #endif
</span><span class="lines">@@ -109,6 +117,8 @@
</span><span class="cx"> 
</span><span class="cx"> typedef pthread_key_t ThreadSpecificKey;
</span><span class="cx"> 
</span><ins>+static const constexpr ThreadSpecificKey InvalidThreadSpecificKey = PTHREAD_KEYS_MAX;
+
</ins><span class="cx"> inline void threadSpecificKeyCreate(ThreadSpecificKey* key, void (*destructor)(void *))
</span><span class="cx"> {
</span><span class="cx">     int error = pthread_key_create(key, destructor);
</span><span class="lines">@@ -171,6 +181,8 @@
</span><span class="cx"> 
</span><span class="cx"> typedef DWORD ThreadSpecificKey;
</span><span class="cx"> 
</span><ins>+static const constexpr ThreadSpecificKey InvalidThreadSpecificKey = FLS_OUT_OF_INDEXES;
+
</ins><span class="cx"> inline void threadSpecificKeyCreate(ThreadSpecificKey* key, void (THREAD_SPECIFIC_CALL *destructor)(void *))
</span><span class="cx"> {
</span><span class="cx">     DWORD flsKey = FlsAlloc(destructor);
</span></span></pre></div>
<a id="trunkSourceWTFwtfThreadingcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/wtf/Threading.cpp (215264 => 215265)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/wtf/Threading.cpp        2017-04-12 10:14:30 UTC (rev 215264)
+++ trunk/Source/WTF/wtf/Threading.cpp        2017-04-12 12:08:29 UTC (rev 215265)
</span><span class="lines">@@ -26,9 +26,15 @@
</span><span class="cx"> #include &quot;config.h&quot;
</span><span class="cx"> #include &quot;Threading.h&quot;
</span><span class="cx"> 
</span><ins>+#include &quot;dtoa.h&quot;
+#include &quot;dtoa/cached-powers.h&quot;
</ins><span class="cx"> #include &lt;algorithm&gt;
</span><span class="cx"> #include &lt;cmath&gt;
</span><span class="cx"> #include &lt;cstring&gt;
</span><ins>+#include &lt;wtf/DateMath.h&gt;
+#include &lt;wtf/RandomNumberSeed.h&gt;
+#include &lt;wtf/ThreadHolder.h&gt;
+#include &lt;wtf/WTFThreadData.h&gt;
</ins><span class="cx"> #include &lt;wtf/text/StringView.h&gt;
</span><span class="cx"> 
</span><span class="cx"> #if HAVE(QOS_CLASSES)
</span><span class="lines">@@ -45,7 +51,7 @@
</span><span class="cx">     Mutex creationMutex;
</span><span class="cx"> };
</span><span class="cx"> 
</span><del>-const char* normalizeThreadName(const char* threadName)
</del><ins>+const char* Thread::normalizeThreadName(const char* threadName)
</ins><span class="cx"> {
</span><span class="cx"> #if HAVE(PTHREAD_SETNAME_NP)
</span><span class="cx">     return threadName;
</span><span class="lines">@@ -82,7 +88,7 @@
</span><span class="cx">         MutexLocker locker(context-&gt;creationMutex);
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    initializeCurrentThreadInternal(context-&gt;name);
</del><ins>+    Thread::initializeCurrentThreadInternal(context-&gt;name);
</ins><span class="cx"> 
</span><span class="cx">     auto entryPoint = WTFMove(context-&gt;entryPoint);
</span><span class="cx"> 
</span><span class="lines">@@ -92,7 +98,7 @@
</span><span class="cx">     entryPoint();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-ThreadIdentifier createThread(const char* name, std::function&lt;void()&gt; entryPoint)
</del><ins>+RefPtr&lt;Thread&gt; Thread::create(const char* name, std::function&lt;void()&gt; entryPoint)
</ins><span class="cx"> {
</span><span class="cx">     NewThreadContext* context = new NewThreadContext { name, WTFMove(entryPoint), { } };
</span><span class="cx"> 
</span><span class="lines">@@ -99,18 +105,24 @@
</span><span class="cx">     // Prevent the thread body from executing until we've established the thread identifier.
</span><span class="cx">     MutexLocker locker(context-&gt;creationMutex);
</span><span class="cx"> 
</span><del>-    return createThreadInternal(threadEntryPoint, context, name);
</del><ins>+    return Thread::createInternal(threadEntryPoint, context, name);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-ThreadIdentifier createThread(ThreadFunction entryPoint, void* data, const char* name)
</del><ins>+RefPtr&lt;Thread&gt; Thread::create(ThreadFunction entryPoint, void* data, const char* name)
</ins><span class="cx"> {
</span><del>-    return createThread(name, [entryPoint, data] {
</del><ins>+    return Thread::create(name, [entryPoint, data] {
</ins><span class="cx">         entryPoint(data);
</span><span class="cx">     });
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void setCurrentThreadIsUserInteractive(int relativePriority)
</del><ins>+void Thread::didExit()
</ins><span class="cx"> {
</span><ins>+    std::unique_lock&lt;std::mutex&gt; locker(m_mutex);
+    m_didExit = true;
+}
+
+void Thread::setCurrentThreadIsUserInteractive(int relativePriority)
+{
</ins><span class="cx"> #if HAVE(QOS_CLASSES)
</span><span class="cx">     ASSERT(relativePriority &lt;= 0);
</span><span class="cx">     ASSERT(relativePriority &gt;= QOS_MIN_RELATIVE_PRIORITY);
</span><span class="lines">@@ -120,7 +132,7 @@
</span><span class="cx"> #endif
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void setCurrentThreadIsUserInitiated(int relativePriority)
</del><ins>+void Thread::setCurrentThreadIsUserInitiated(int relativePriority)
</ins><span class="cx"> {
</span><span class="cx"> #if HAVE(QOS_CLASSES)
</span><span class="cx">     ASSERT(relativePriority &lt;= 0);
</span><span class="lines">@@ -134,13 +146,13 @@
</span><span class="cx"> #if HAVE(QOS_CLASSES)
</span><span class="cx"> static qos_class_t globalMaxQOSclass { QOS_CLASS_UNSPECIFIED };
</span><span class="cx"> 
</span><del>-void setGlobalMaxQOSClass(qos_class_t maxClass)
</del><ins>+void Thread::setGlobalMaxQOSClass(qos_class_t maxClass)
</ins><span class="cx"> {
</span><span class="cx">     bmalloc::api::setScavengerThreadQOSClass(maxClass);
</span><span class="cx">     globalMaxQOSclass = maxClass;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-qos_class_t adjustedQOSClass(qos_class_t originalClass)
</del><ins>+qos_class_t Thread::adjustedQOSClass(qos_class_t originalClass)
</ins><span class="cx"> {
</span><span class="cx">     if (globalMaxQOSclass != QOS_CLASS_UNSPECIFIED)
</span><span class="cx">         return std::min(originalClass, globalMaxQOSclass);
</span><span class="lines">@@ -148,4 +160,25 @@
</span><span class="cx"> }
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><ins>+void Thread::dump(PrintStream&amp; out) const
+{
+    out.print(m_id);
+}
+
+void initializeThreading()
+{
+    static std::once_flag initializeKey;
+    std::call_once(initializeKey, [] {
+        WTF::double_conversion::initialize();
+        ThreadHolder::initializeOnce();
+        // StringImpl::empty() does not construct its static string in a threadsafe fashion,
+        // so ensure it has been initialized from here.
+        StringImpl::empty();
+        initializeRandomNumberGenerator();
+        wtfThreadData();
+        initializeDates();
+        Thread::initializePlatformThreading();
+    });
+}
+
</ins><span class="cx"> } // namespace WTF
</span></span></pre></div>
<a id="trunkSourceWTFwtfThreadingh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/wtf/Threading.h (215264 => 215265)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/wtf/Threading.h        2017-04-12 10:14:30 UTC (rev 215264)
+++ trunk/Source/WTF/wtf/Threading.h        2017-04-12 12:08:29 UTC (rev 215265)
</span><span class="lines">@@ -1,6 +1,7 @@
</span><span class="cx"> /*
</span><span class="cx">  * Copyright (C) 2007, 2008, 2010, 2014 Apple Inc. All rights reserved.
</span><del>- * Copyright (C) 2007 Justin Haygood (jhaygood@reaktix.com)
</del><ins>+ * Copyright (C) 2007 Justin Haygood &lt;jhaygood@reaktix.com&gt;
+ * Copyright (C) 2017 Yusuke Suzuki &lt;utatane.tea@gmail.com&gt;
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -35,75 +36,176 @@
</span><span class="cx"> // Nothing in this header depends on Assertions, Atomics, Locker, Noncopyable, ThreadSafeRefCounted, or ThreadingPrimitives.
</span><span class="cx"> 
</span><span class="cx"> #include &lt;functional&gt;
</span><ins>+#include &lt;mutex&gt;
</ins><span class="cx"> #include &lt;stdint.h&gt;
</span><span class="cx"> #include &lt;wtf/Assertions.h&gt;
</span><span class="cx"> #include &lt;wtf/Atomics.h&gt;
</span><ins>+#include &lt;wtf/Expected.h&gt;
</ins><span class="cx"> #include &lt;wtf/Locker.h&gt;
</span><span class="cx"> #include &lt;wtf/Noncopyable.h&gt;
</span><ins>+#include &lt;wtf/PlatformRegisters.h&gt;
+#include &lt;wtf/PrintStream.h&gt;
+#include &lt;wtf/RefPtr.h&gt;
</ins><span class="cx"> #include &lt;wtf/ThreadSafeRefCounted.h&gt;
</span><span class="cx"> #include &lt;wtf/ThreadingPrimitives.h&gt;
</span><span class="cx"> 
</span><ins>+#if USE(PTHREADS) &amp;&amp; !OS(DARWIN)
+#include &lt;semaphore.h&gt;
+#include &lt;signal.h&gt;
+#endif
+
</ins><span class="cx"> namespace WTF {
</span><span class="cx"> 
</span><del>-typedef uint32_t ThreadIdentifier;
</del><ins>+using ThreadIdentifier = uint32_t;
</ins><span class="cx"> typedef void (*ThreadFunction)(void* argument);
</span><span class="cx"> 
</span><del>-// This function must be called from the main thread. It is safe to call it repeatedly.
-// Darwin is an exception to this rule: it is OK to call it from any thread, the only 
-// requirement is that the calls are not reentrant.
-WTF_EXPORT_PRIVATE void initializeThreading();
</del><ins>+class ThreadHolder;
+class PrintStream;
</ins><span class="cx"> 
</span><del>-// Returns 0 if thread creation failed.
-// The thread name must be a literal since on some platforms it's passed in to the thread.
-WTF_EXPORT_PRIVATE ThreadIdentifier createThread(const char* threadName, std::function&lt;void()&gt;);
</del><ins>+class Thread : public ThreadSafeRefCounted&lt;Thread&gt; {
+public:
+    friend class ThreadHolder;
</ins><span class="cx"> 
</span><del>-// Mark the current thread as requiring UI responsiveness.
-// relativePriority is a value in the range [-15, 0] where a lower value indicates a lower priority.
-WTF_EXPORT_PRIVATE void setCurrentThreadIsUserInteractive(int relativePriority = 0);
-WTF_EXPORT_PRIVATE void setCurrentThreadIsUserInitiated(int relativePriority = 0);
</del><ins>+    WTF_EXPORT_PRIVATE ~Thread();
</ins><span class="cx"> 
</span><del>-WTF_EXPORT_PRIVATE ThreadIdentifier currentThread();
-WTF_EXPORT_PRIVATE void changeThreadPriority(ThreadIdentifier, int);
-WTF_EXPORT_PRIVATE int waitForThreadCompletion(ThreadIdentifier);
-WTF_EXPORT_PRIVATE void detachThread(ThreadIdentifier);
</del><ins>+    // Returns nullptr if thread creation failed.
+    // The thread name must be a literal since on some platforms it's passed in to the thread.
+    WTF_EXPORT_PRIVATE static RefPtr&lt;Thread&gt; create(const char* threadName, std::function&lt;void()&gt;);
+    WTF_EXPORT_PRIVATE static RefPtr&lt;Thread&gt; create(ThreadFunction entryPoint, void* data, const char* name);
</ins><span class="cx"> 
</span><del>-// Deprecated function-pointer-based thread creation.
-WTF_EXPORT_PRIVATE ThreadIdentifier createThread(ThreadFunction, void*, const char* threadName);
</del><ins>+    // Returns Thread object.
+    WTF_EXPORT_PRIVATE static Thread&amp; current();
</ins><span class="cx"> 
</span><del>-// Internal platform-specific createThread implementation.
-ThreadIdentifier createThreadInternal(ThreadFunction, void*, const char* threadName);
</del><ins>+    // Returns ThreadIdentifier directly. It is useful if the user only cares about identity
+    // of threads. At that time, users should know that holding this ThreadIdentifier does not ensure
+    // that the thread information is alive. While Thread::current() is not safe if it is called
+    // from the destructor of the other TLS data, currentID() always returns meaningful thread ID.
+    WTF_EXPORT_PRIVATE static ThreadIdentifier currentID();
</ins><span class="cx"> 
</span><del>-// Called in the thread during initialization.
-// Helpful for platforms where the thread name must be set from within the thread.
-void initializeCurrentThreadInternal(const char* threadName);
</del><ins>+    WTF_EXPORT_PRIVATE void changePriority(int);
+    WTF_EXPORT_PRIVATE int waitForCompletion();
+    WTF_EXPORT_PRIVATE void detach();
</ins><span class="cx"> 
</span><del>-const char* normalizeThreadName(const char* threadName);
</del><ins>+#if OS(DARWIN)
+    using PlatformSuspendError = kern_return_t;
+#elif USE(PTHREADS)
+    using PlatformSuspendError = int;
+#elif OS(WINDOWS)
+    using PlatformSuspendError = DWORD;
+#endif
</ins><span class="cx"> 
</span><ins>+    WTF_EXPORT_PRIVATE Expected&lt;void, PlatformSuspendError&gt; suspend();
+    WTF_EXPORT_PRIVATE void resume();
+    WTF_EXPORT_PRIVATE size_t getRegisters(PlatformRegisters&amp;);
+
</ins><span class="cx"> #if USE(PTHREADS)
</span><del>-bool signalThread(ThreadIdentifier, int signalNumber);
</del><ins>+    WTF_EXPORT_PRIVATE bool signal(int signalNumber);
</ins><span class="cx"> #endif
</span><span class="cx"> 
</span><ins>+    // Mark the current thread as requiring UI responsiveness.
+    // relativePriority is a value in the range [-15, 0] where a lower value indicates a lower priority.
+    WTF_EXPORT_PRIVATE static void setCurrentThreadIsUserInteractive(int relativePriority = 0);
+    WTF_EXPORT_PRIVATE static void setCurrentThreadIsUserInitiated(int relativePriority = 0);
+
</ins><span class="cx"> #if HAVE(QOS_CLASSES)
</span><del>-WTF_EXPORT_PRIVATE void setGlobalMaxQOSClass(qos_class_t);
-WTF_EXPORT_PRIVATE qos_class_t adjustedQOSClass(qos_class_t);
</del><ins>+    WTF_EXPORT_PRIVATE static void setGlobalMaxQOSClass(qos_class_t);
+    WTF_EXPORT_PRIVATE static qos_class_t adjustedQOSClass(qos_class_t);
</ins><span class="cx"> #endif
</span><span class="cx"> 
</span><del>-} // namespace WTF
</del><ins>+    // Called in the thread during initialization.
+    // Helpful for platforms where the thread name must be set from within the thread.
+    static void initializeCurrentThreadInternal(const char* threadName);
</ins><span class="cx"> 
</span><del>-using WTF::ThreadIdentifier;
-using WTF::createThread;
-using WTF::currentThread;
-using WTF::changeThreadPriority;
-using WTF::detachThread;
-using WTF::waitForThreadCompletion;
</del><ins>+    WTF_EXPORT_PRIVATE void dump(PrintStream&amp; out) const;
</ins><span class="cx"> 
</span><ins>+    ThreadIdentifier id() const { return m_id; }
+
+    bool operator==(const Thread&amp; thread)
+    {
+        return id() == thread.id();
+    }
+
+    bool operator!=(const Thread&amp; thread)
+    {
+        return id() != thread.id();
+    }
+
+    static void initializePlatformThreading();
+
+private:
+    Thread();
+
+    // Internal platform-specific Thread::create implementation.
+    static RefPtr&lt;Thread&gt; createInternal(ThreadFunction, void*, const char* threadName);
+
</ins><span class="cx"> #if USE(PTHREADS)
</span><del>-using WTF::signalThread;
</del><ins>+    void establish(pthread_t);
+#else
+    void establish(HANDLE, ThreadIdentifier);
</ins><span class="cx"> #endif
</span><span class="cx"> 
</span><del>-#if HAVE(QOS_CLASSES)
-using WTF::setGlobalMaxQOSClass;
-using WTF::adjustedQOSClass;
</del><ins>+#if USE(PTHREADS) &amp;&amp; !OS(DARWIN)
+    static void signalHandlerSuspendResume(int, siginfo_t*, void* ucontext);
</ins><span class="cx"> #endif
</span><span class="cx"> 
</span><ins>+    static const char* normalizeThreadName(const char* threadName);
+
+    enum JoinableState {
+        // The default thread state. The thread can be joined on.
+        Joinable,
+
+        // Somebody waited on this thread to exit and this thread finally exited. This state is here because there can be a
+        // period of time between when the thread exits (which causes pthread_join to return and the remainder of waitOnThreadCompletion to run)
+        // and when threadDidExit is called. We need threadDidExit to take charge and delete the thread data since there's
+        // nobody else to pick up the slack in this case (since waitOnThreadCompletion has already returned).
+        Joined,
+
+        // The thread has been detached and can no longer be joined on. At this point, the thread must take care of cleaning up after itself.
+        Detached,
+    };
+
+    JoinableState joinableState() { return m_joinableState; }
+    void didBecomeDetached() { m_joinableState = Detached; }
+    void didExit();
+    void didJoin() { m_joinableState = Joined; }
+    bool hasExited() { return m_didExit; }
+
+    // WordLock &amp; Lock rely on ThreadSpecific. But Thread object can be destroyed even after ThreadSpecific things are destroyed.
+    std::mutex m_mutex;
+    ThreadIdentifier m_id { 0 };
+    JoinableState m_joinableState { Joinable };
+    bool m_didExit { false };
+#if USE(PTHREADS)
+    pthread_t m_handle;
+#if OS(DARWIN)
+    mach_port_t m_platformThread;
+#else
+    sem_t m_semaphoreForSuspendResume;
+    mcontext_t m_suspendedMachineContext;
+    unsigned m_suspendCount { 0 };
+    std::atomic&lt;bool&gt; m_suspended { false };
+#endif
+#elif OS(WINDOWS)
+    HANDLE m_handle { INVALID_HANDLE_VALUE };
+#else
+#error Unknown System
+#endif
+};
+
+// This function must be called from the main thread. It is safe to call it repeatedly.
+// Darwin is an exception to this rule: it is OK to call it from any thread, the only
+// requirement is that the calls are not reentrant.
+WTF_EXPORT_PRIVATE void initializeThreading();
+
+inline ThreadIdentifier currentThread()
+{
+    return Thread::currentID();
+}
+
+} // namespace WTF
+
+using WTF::ThreadIdentifier;
+using WTF::Thread;
+using WTF::currentThread;
+
</ins><span class="cx"> #endif // Threading_h
</span></span></pre></div>
<a id="trunkSourceWTFwtfThreadingPthreadscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/wtf/ThreadingPthreads.cpp (215264 => 215265)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/wtf/ThreadingPthreads.cpp        2017-04-12 10:14:30 UTC (rev 215264)
+++ trunk/Source/WTF/wtf/ThreadingPthreads.cpp        2017-04-12 12:08:29 UTC (rev 215265)
</span><span class="lines">@@ -1,7 +1,8 @@
</span><span class="cx"> /*
</span><span class="cx">  * Copyright (C) 2007, 2009, 2015 Apple Inc. All rights reserved.
</span><del>- * Copyright (C) 2007 Justin Haygood (jhaygood@reaktix.com)
</del><ins>+ * Copyright (C) 2007 Justin Haygood &lt;jhaygood@reaktix.com&gt;
</ins><span class="cx">  * Copyright (C) 2011 Research In Motion Limited. All rights reserved.
</span><ins>+ * Copyright (C) 2017 Yusuke Suzuki &lt;utatane.tea@gmail.com&gt;
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -33,22 +34,20 @@
</span><span class="cx"> 
</span><span class="cx"> #if USE(PTHREADS)
</span><span class="cx"> 
</span><del>-#include &quot;CurrentTime.h&quot;
-#include &quot;DateMath.h&quot;
-#include &quot;dtoa.h&quot;
-#include &quot;dtoa/cached-powers.h&quot;
-#include &quot;HashMap.h&quot;
-#include &quot;RandomNumberSeed.h&quot;
-#include &quot;StdLibExtras.h&quot;
-#include &quot;ThreadFunctionInvocation.h&quot;
-#include &quot;ThreadIdentifierDataPthreads.h&quot;
-#include &quot;ThreadSpecific.h&quot;
</del><ins>+#include &lt;errno.h&gt;
+#include &lt;wtf/CurrentTime.h&gt;
</ins><span class="cx"> #include &lt;wtf/DataLog.h&gt;
</span><span class="cx"> #include &lt;wtf/NeverDestroyed.h&gt;
</span><span class="cx"> #include &lt;wtf/RawPointer.h&gt;
</span><del>-#include &lt;wtf/WTFThreadData.h&gt;
-#include &lt;errno.h&gt;
</del><ins>+#include &lt;wtf/StdLibExtras.h&gt;
+#include &lt;wtf/ThreadFunctionInvocation.h&gt;
+#include &lt;wtf/ThreadHolder.h&gt;
+#include &lt;wtf/WordLock.h&gt;
</ins><span class="cx"> 
</span><ins>+#if OS(LINUX)
+#include &lt;sys/prctl.h&gt;
+#endif
+
</ins><span class="cx"> #if !COMPILER(MSVC)
</span><span class="cx"> #include &lt;limits.h&gt;
</span><span class="cx"> #include &lt;sched.h&gt;
</span><span class="lines">@@ -55,127 +54,131 @@
</span><span class="cx"> #include &lt;sys/time.h&gt;
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><del>-#if OS(LINUX)
-#include &lt;sys/prctl.h&gt;
</del><ins>+#if !OS(DARWIN) &amp;&amp; OS(UNIX)
+
+#include &lt;sys/mman.h&gt;
+#include &lt;unistd.h&gt;
+
+#if OS(SOLARIS)
+#include &lt;thread.h&gt;
+#else
+#include &lt;pthread.h&gt;
</ins><span class="cx"> #endif
</span><span class="cx"> 
</span><del>-#if !OS(DARWIN)
-#include &lt;signal.h&gt;
</del><ins>+#if HAVE(PTHREAD_NP_H)
+#include &lt;pthread_np.h&gt;
</ins><span class="cx"> #endif
</span><span class="cx"> 
</span><ins>+#endif
+
</ins><span class="cx"> namespace WTF {
</span><span class="cx"> 
</span><del>-class PthreadState {
-    WTF_MAKE_FAST_ALLOCATED;
-public:
-    enum JoinableState {
-        Joinable, // The default thread state. The thread can be joined on.
</del><ins>+Thread::Thread()
+{
+#if !OS(DARWIN)
+    sem_init(&amp;m_semaphoreForSuspendResume, /* Only available in this process. */ 0, /* Initial value for the semaphore. */ 0);
+#endif
+}
</ins><span class="cx"> 
</span><del>-        Joined, // Somebody waited on this thread to exit and this thread finally exited. This state is here because there can be a 
-                // period of time between when the thread exits (which causes pthread_join to return and the remainder of waitOnThreadCompletion to run) 
-                // and when threadDidExit is called. We need threadDidExit to take charge and delete the thread data since there's 
-                // nobody else to pick up the slack in this case (since waitOnThreadCompletion has already returned).
</del><ins>+Thread::~Thread()
+{
+#if !OS(DARWIN)
+    sem_destroy(&amp;m_semaphoreForSuspendResume);
+#endif
+}
</ins><span class="cx"> 
</span><del>-        Detached // The thread has been detached and can no longer be joined on. At this point, the thread must take care of cleaning up after itself.
-    };
</del><ins>+#if !OS(DARWIN)
</ins><span class="cx"> 
</span><del>-    // Currently all threads created by WTF start out as joinable. 
-    PthreadState(pthread_t handle)
-        : m_joinableState(Joinable)
-        , m_didExit(false)
-        , m_pthreadHandle(handle)
-    {
-    }
</del><ins>+// We use SIGUSR2 to suspend and resume machine threads in JavaScriptCore.
+static constexpr const int SigThreadSuspendResume = SIGUSR2;
+static std::atomic&lt;Thread*&gt; targetThread { nullptr };
+static StaticWordLock globalSuspendLock;
</ins><span class="cx"> 
</span><del>-    JoinableState joinableState() { return m_joinableState; }
-    pthread_t pthreadHandle() { return m_pthreadHandle; }
-    void didBecomeDetached() { m_joinableState = Detached; }
-    void didExit() { m_didExit = true; }
-    void didJoin() { m_joinableState = Joined; }
-    bool hasExited() { return m_didExit; }
-
-private:
-    JoinableState m_joinableState;
-    bool m_didExit;
-    pthread_t m_pthreadHandle;
-};
-
-typedef HashMap&lt;ThreadIdentifier, std::unique_ptr&lt;PthreadState&gt;&gt; ThreadMap;
-
-void unsafeThreadWasDetached(ThreadIdentifier);
-void threadDidExit(ThreadIdentifier);
-void threadWasJoined(ThreadIdentifier);
-
-static Mutex&amp; threadMapMutex()
</del><ins>+void Thread::signalHandlerSuspendResume(int, siginfo_t*, void* ucontext)
</ins><span class="cx"> {
</span><del>-    static NeverDestroyed&lt;Mutex&gt; mutex;
-    return mutex;
-}
</del><ins>+    // Touching thread local atomic types from signal handlers is allowed.
+    Thread* thread = targetThread.load();
</ins><span class="cx"> 
</span><del>-void initializeThreading()
-{
-    static bool isInitialized;
-
-    if (isInitialized)
</del><ins>+    if (thread-&gt;m_suspended.load(std::memory_order_acquire)) {
+        // This is signal handler invocation that is intended to be used to resume sigsuspend.
+        // So this handler invocation itself should not process.
+        //
+        // When signal comes, first, the system calls signal handler. And later, sigsuspend will be resumed. Signal handler invocation always precedes.
+        // So, the problem never happens that suspended.store(true, ...) will be executed before the handler is called.
+        // http://pubs.opengroup.org/onlinepubs/009695399/functions/sigsuspend.html
</ins><span class="cx">         return;
</span><ins>+    }
</ins><span class="cx"> 
</span><del>-    isInitialized = true;
</del><ins>+    ucontext_t* userContext = static_cast&lt;ucontext_t*&gt;(ucontext);
+#if CPU(PPC)
+    thread-&gt;m_suspendedMachineContext = *userContext-&gt;uc_mcontext.uc_regs;
+#else
+    thread-&gt;m_suspendedMachineContext = userContext-&gt;uc_mcontext;
+#endif
</ins><span class="cx"> 
</span><del>-    WTF::double_conversion::initialize();
-    // StringImpl::empty() does not construct its static string in a threadsafe fashion,
-    // so ensure it has been initialized from here.
-    StringImpl::empty();
-    threadMapMutex();
-    initializeRandomNumberGenerator();
-    ThreadIdentifierData::initializeOnce();
-    wtfThreadData();
-    initializeDates();
-}
</del><ins>+    // Allow suspend caller to see that this thread is suspended.
+    // sem_post is async-signal-safe function. It means that we can call this from a signal handler.
+    // http://pubs.opengroup.org/onlinepubs/009695399/functions/xsh_chap02_04.html#tag_02_04_03
+    //
+    // And sem_post emits memory barrier that ensures that suspendedMachineContext is correctly saved.
+    // http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap04.html#tag_04_11
+    sem_post(&amp;thread-&gt;m_semaphoreForSuspendResume);
</ins><span class="cx"> 
</span><del>-static ThreadMap&amp; threadMap()
-{
-    static NeverDestroyed&lt;ThreadMap&gt; map;
-    return map;
</del><ins>+    // Reaching here, SigThreadSuspendResume is blocked in this handler (this is configured by sigaction's sa_mask).
+    // So before calling sigsuspend, SigThreadSuspendResume to this thread is deferred. This ensures that the handler is not executed recursively.
+    sigset_t blockedSignalSet;
+    sigfillset(&amp;blockedSignalSet);
+    sigdelset(&amp;blockedSignalSet, SigThreadSuspendResume);
+    sigsuspend(&amp;blockedSignalSet);
+
+    // Allow resume caller to see that this thread is resumed.
+    sem_post(&amp;thread-&gt;m_semaphoreForSuspendResume);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-static ThreadIdentifier identifierByPthreadHandle(const pthread_t&amp; pthreadHandle)
</del><ins>+#endif // !OS(DARWIN)
+
+void Thread::initializePlatformThreading()
</ins><span class="cx"> {
</span><del>-    MutexLocker locker(threadMapMutex());
</del><ins>+#if !OS(DARWIN)
+    // Signal handlers are process global configuration.
+    // Intentionally block SigThreadSuspendResume in the handler.
+    // SigThreadSuspendResume will be allowed in the handler by sigsuspend.
+    struct sigaction action;
+    sigemptyset(&amp;action.sa_mask);
+    sigaddset(&amp;action.sa_mask, SigThreadSuspendResume);
</ins><span class="cx"> 
</span><del>-    ThreadMap::iterator i = threadMap().begin();
-    for (; i != threadMap().end(); ++i) {
-        if (pthread_equal(i-&gt;value-&gt;pthreadHandle(), pthreadHandle) &amp;&amp; !i-&gt;value-&gt;hasExited())
-            return i-&gt;key;
-    }
-
-    return 0;
</del><ins>+    action.sa_sigaction = &amp;signalHandlerSuspendResume;
+    action.sa_flags = SA_RESTART | SA_SIGINFO;
+    sigaction(SigThreadSuspendResume, &amp;action, 0);
+#endif
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-static ThreadIdentifier establishIdentifierForPthreadHandle(const pthread_t&amp; pthreadHandle)
</del><ins>+static void initializeCurrentThreadEvenIfNonWTFCreated()
</ins><span class="cx"> {
</span><del>-    ASSERT(!identifierByPthreadHandle(pthreadHandle));
-    MutexLocker locker(threadMapMutex());
-    static ThreadIdentifier identifierCount = 1;
-    threadMap().add(identifierCount, std::make_unique&lt;PthreadState&gt;(pthreadHandle));
-    return identifierCount++;
</del><ins>+#if !OS(DARWIN)
+    sigset_t mask;
+    sigemptyset(&amp;mask);
+    sigaddset(&amp;mask, SigThreadSuspendResume);
+    pthread_sigmask(SIG_UNBLOCK, &amp;mask, 0);
+#endif
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-static pthread_t pthreadHandleForIdentifierWithLockAlreadyHeld(ThreadIdentifier id)
-{
-    return threadMap().get(id)-&gt;pthreadHandle();
-}
-
</del><span class="cx"> static void* wtfThreadEntryPoint(void* param)
</span><span class="cx"> {
</span><del>-    // Balanced by .leakPtr() in createThreadInternal.
</del><ins>+    // Balanced by .leakPtr() in Thread::createInternal.
</ins><span class="cx">     auto invocation = std::unique_ptr&lt;ThreadFunctionInvocation&gt;(static_cast&lt;ThreadFunctionInvocation*&gt;(param));
</span><ins>+
+    ThreadHolder::initialize(*invocation-&gt;thread);
+    invocation-&gt;thread = nullptr;
+
</ins><span class="cx">     invocation-&gt;function(invocation-&gt;data);
</span><span class="cx">     return nullptr;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-ThreadIdentifier createThreadInternal(ThreadFunction entryPoint, void* data, const char*)
</del><ins>+RefPtr&lt;Thread&gt; Thread::createInternal(ThreadFunction entryPoint, void* data, const char*)
</ins><span class="cx"> {
</span><del>-    auto invocation = std::make_unique&lt;ThreadFunctionInvocation&gt;(entryPoint, data);
</del><ins>+    RefPtr&lt;Thread&gt; thread = adoptRef(new Thread());
+    auto invocation = std::make_unique&lt;ThreadFunctionInvocation&gt;(entryPoint, thread.get(), data);
</ins><span class="cx">     pthread_t threadHandle;
</span><span class="cx">     pthread_attr_t attr;
</span><span class="cx">     pthread_attr_init(&amp;attr);
</span><span class="lines">@@ -186,7 +189,7 @@
</span><span class="cx">     pthread_attr_destroy(&amp;attr);
</span><span class="cx">     if (error) {
</span><span class="cx">         LOG_ERROR(&quot;Failed to create pthread at entry point %p with data %p&quot;, wtfThreadEntryPoint, invocation.get());
</span><del>-        return 0;
</del><ins>+        return nullptr;
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     // Balanced by std::unique_ptr constructor in wtfThreadEntryPoint.
</span><span class="lines">@@ -193,10 +196,11 @@
</span><span class="cx">     ThreadFunctionInvocation* leakedInvocation = invocation.release();
</span><span class="cx">     UNUSED_PARAM(leakedInvocation);
</span><span class="cx"> 
</span><del>-    return establishIdentifierForPthreadHandle(threadHandle);
</del><ins>+    thread-&gt;establish(threadHandle);
+    return thread;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-void initializeCurrentThreadInternal(const char* threadName)
</del><ins>+void Thread::initializeCurrentThreadInternal(const char* threadName)
</ins><span class="cx"> {
</span><span class="cx"> #if HAVE(PTHREAD_SETNAME_NP)
</span><span class="cx">     pthread_setname_np(normalizeThreadName(threadName));
</span><span class="lines">@@ -205,125 +209,230 @@
</span><span class="cx"> #else
</span><span class="cx">     UNUSED_PARAM(threadName);
</span><span class="cx"> #endif
</span><ins>+    initializeCurrentThreadEvenIfNonWTFCreated();
+}
</ins><span class="cx"> 
</span><del>-    ThreadIdentifier id = identifierByPthreadHandle(pthread_self());
-    ASSERT(id);
-    ThreadIdentifierData::initialize(id);
-}
-    
-void changeThreadPriority(ThreadIdentifier threadID, int delta)
</del><ins>+void Thread::changePriority(int delta)
</ins><span class="cx"> {
</span><del>-    pthread_t pthreadHandle;
-    ASSERT(threadID);
</del><ins>+    std::unique_lock&lt;std::mutex&gt; locker(m_mutex);
</ins><span class="cx"> 
</span><del>-    {
-        MutexLocker locker(threadMapMutex());
-        pthreadHandle = pthreadHandleForIdentifierWithLockAlreadyHeld(threadID);
-        ASSERT(pthreadHandle);
-    }
-
</del><span class="cx">     int policy;
</span><span class="cx">     struct sched_param param;
</span><span class="cx"> 
</span><del>-    if (pthread_getschedparam(pthreadHandle, &amp;policy, &amp;param))
</del><ins>+    if (pthread_getschedparam(m_handle, &amp;policy, &amp;param))
</ins><span class="cx">         return;
</span><span class="cx"> 
</span><span class="cx">     param.sched_priority += delta;
</span><span class="cx"> 
</span><del>-    pthread_setschedparam(pthreadHandle, policy, &amp;param);
</del><ins>+    pthread_setschedparam(m_handle, policy, &amp;param);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-int waitForThreadCompletion(ThreadIdentifier threadID)
</del><ins>+int Thread::waitForCompletion()
</ins><span class="cx"> {
</span><del>-    pthread_t pthreadHandle;
-    ASSERT(threadID);
-
</del><ins>+    pthread_t handle;
</ins><span class="cx">     {
</span><del>-        // We don't want to lock across the call to join, since that can block our thread and cause deadlock.
-        MutexLocker locker(threadMapMutex());
-        pthreadHandle = pthreadHandleForIdentifierWithLockAlreadyHeld(threadID);
-        ASSERT(pthreadHandle);
</del><ins>+        std::unique_lock&lt;std::mutex&gt; locker(m_mutex);
+        handle = m_handle;
</ins><span class="cx">     }
</span><span class="cx"> 
</span><del>-    int joinResult = pthread_join(pthreadHandle, 0);
</del><ins>+    int joinResult = pthread_join(handle, 0);
</ins><span class="cx"> 
</span><span class="cx">     if (joinResult == EDEADLK)
</span><del>-        LOG_ERROR(&quot;ThreadIdentifier %u was found to be deadlocked trying to quit&quot;, threadID);
</del><ins>+        LOG_ERROR(&quot;ThreadIdentifier %u was found to be deadlocked trying to quit&quot;, m_id);
</ins><span class="cx">     else if (joinResult)
</span><del>-        LOG_ERROR(&quot;ThreadIdentifier %u was unable to be joined.\n&quot;, threadID);
</del><ins>+        LOG_ERROR(&quot;ThreadIdentifier %u was unable to be joined.\n&quot;, m_id);
</ins><span class="cx"> 
</span><del>-    MutexLocker locker(threadMapMutex());
-    PthreadState* state = threadMap().get(threadID);
-    ASSERT(state);
-    ASSERT(state-&gt;joinableState() == PthreadState::Joinable);
</del><ins>+    std::unique_lock&lt;std::mutex&gt; locker(m_mutex);
+    ASSERT(joinableState() == Joinable);
</ins><span class="cx"> 
</span><del>-    // The thread has already exited, so clean up after it.
-    if (state-&gt;hasExited())
-        threadMap().remove(threadID);
-    // The thread hasn't exited yet, so don't clean anything up. Just signal that we've already joined on it so that it will clean up after itself.
-    else
-        state-&gt;didJoin();
</del><ins>+    // If the thread has already exited, then do nothing. If the thread hasn't exited yet, then just signal that we've already joined on it.
+    // In both cases, ThreadHolder::destruct() will take care of destroying Thread.
+    if (!hasExited())
+        didJoin();
</ins><span class="cx"> 
</span><span class="cx">     return joinResult;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void detachThread(ThreadIdentifier threadID)
</del><ins>+void Thread::detach()
</ins><span class="cx"> {
</span><del>-    ASSERT(threadID);
-
-    MutexLocker locker(threadMapMutex());
-    pthread_t pthreadHandle = pthreadHandleForIdentifierWithLockAlreadyHeld(threadID);
-    ASSERT(pthreadHandle);
-
-    int detachResult = pthread_detach(pthreadHandle);
</del><ins>+    std::unique_lock&lt;std::mutex&gt; locker(m_mutex);
+    int detachResult = pthread_detach(m_handle);
</ins><span class="cx">     if (detachResult)
</span><del>-        LOG_ERROR(&quot;ThreadIdentifier %u was unable to be detached\n&quot;, threadID);
</del><ins>+        LOG_ERROR(&quot;ThreadIdentifier %u was unable to be detached\n&quot;, m_id);
</ins><span class="cx"> 
</span><del>-    PthreadState* state = threadMap().get(threadID);
-    ASSERT(state);
-    if (state-&gt;hasExited())
-        threadMap().remove(threadID);
-    else
-        threadMap().get(threadID)-&gt;didBecomeDetached();
</del><ins>+    if (!hasExited())
+        didBecomeDetached();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-void threadDidExit(ThreadIdentifier threadID)
</del><ins>+Thread&amp; Thread::current()
</ins><span class="cx"> {
</span><del>-    MutexLocker locker(threadMapMutex());
-    PthreadState* state = threadMap().get(threadID);
-    ASSERT(state);
-    
-    state-&gt;didExit();
</del><ins>+    ThreadHolder* data = ThreadHolder::current();
+    if (data)
+        return data-&gt;thread();
</ins><span class="cx"> 
</span><del>-    if (state-&gt;joinableState() != PthreadState::Joinable)
-        threadMap().remove(threadID);
</del><ins>+    // Not a WTF-created thread, ThreadIdentifier is not established yet.
+    RefPtr&lt;Thread&gt; thread = adoptRef(new Thread());
+    thread-&gt;establish(pthread_self());
+    ThreadHolder::initialize(*thread);
+    initializeCurrentThreadEvenIfNonWTFCreated();
+    return *thread;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-ThreadIdentifier currentThread()
</del><ins>+ThreadIdentifier Thread::currentID()
</ins><span class="cx"> {
</span><del>-    ThreadIdentifier id = ThreadIdentifierData::identifier();
-    if (id)
-        return id;
</del><ins>+    return current().id();
+}
</ins><span class="cx"> 
</span><del>-    // Not a WTF-created thread, ThreadIdentifier is not established yet.
-    id = establishIdentifierForPthreadHandle(pthread_self());
-    ThreadIdentifierData::initialize(id);
-    return id;
</del><ins>+bool Thread::signal(int signalNumber)
+{
+    std::unique_lock&lt;std::mutex&gt; locker(m_mutex);
+    int errNo = pthread_kill(m_handle, signalNumber);
+    return !errNo; // A 0 errNo means success.
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-bool signalThread(ThreadIdentifier threadID, int signalNumber)
</del><ins>+auto Thread::suspend() -&gt; Expected&lt;void, PlatformSuspendError&gt;
</ins><span class="cx"> {
</span><del>-    pthread_t pthreadHandle;
-    ASSERT(threadID);
</del><ins>+    RELEASE_ASSERT_WITH_MESSAGE(id() != currentThread(), &quot;We do not support suspending the current thread itself.&quot;);
+    std::unique_lock&lt;std::mutex&gt; locker(m_mutex);
+#if OS(DARWIN)
+    kern_return_t result = thread_suspend(m_platformThread);
+    if (result != KERN_SUCCESS)
+        return makeUnexpected(result);
+    return { };
+#else
</ins><span class="cx">     {
</span><del>-        MutexLocker locker(threadMapMutex());
-        pthreadHandle = pthreadHandleForIdentifierWithLockAlreadyHeld(threadID);
-        ASSERT(pthreadHandle);
</del><ins>+        // During suspend, suspend or resume should not be executed from the other threads.
+        // We use global lock instead of per thread lock.
+        // Consider the following case, there are threads A and B.
+        // And A attempt to suspend B and B attempt to suspend A.
+        // A and B send signals. And later, signals are delivered to A and B.
+        // In that case, both will be suspended.
+        WordLockHolder locker(globalSuspendLock);
+        if (!m_suspendCount) {
+            // Ideally, we would like to use pthread_sigqueue. It allows us to pass the argument to the signal handler.
+            // But it can be used in a few platforms, like Linux.
+            // Instead, we use Thread* stored in the thread local storage to pass it to the signal handler.
+            targetThread.store(this);
+            int result = pthread_kill(m_handle, SigThreadSuspendResume);
+            if (result)
+                return makeUnexpected(result);
+            sem_wait(&amp;m_semaphoreForSuspendResume);
+            // Release barrier ensures that this operation is always executed after all the above processing is done.
+            m_suspended.store(true, std::memory_order_release);
+        }
+        ++m_suspendCount;
+        return { };
</ins><span class="cx">     }
</span><del>-    int errNo = pthread_kill(pthreadHandle, signalNumber);
-    return !errNo; // A 0 errNo means success.
</del><ins>+#endif
</ins><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void Thread::resume()
+{
+    std::unique_lock&lt;std::mutex&gt; locker(m_mutex);
+#if OS(DARWIN)
+    thread_resume(m_platformThread);
+#else
+    {
+        // During resume, suspend or resume should not be executed from the other threads.
+        WordLockHolder locker(globalSuspendLock);
+        if (m_suspendCount == 1) {
+            // When allowing SigThreadSuspendResume interrupt in the signal handler by sigsuspend and SigThreadSuspendResume is actually issued,
+            // the signal handler itself will be called once again.
+            // There are several ways to distinguish the handler invocation for suspend and resume.
+            // 1. Use different signal numbers. And check the signal number in the handler.
+            // 2. Use some arguments to distinguish suspend and resume in the handler. If pthread_sigqueue can be used, we can take this.
+            // 3. Use thread local storage with atomic variables in the signal handler.
+            // In this implementaiton, we take (3). suspended flag is used to distinguish it.
+            targetThread.store(this);
+            if (pthread_kill(m_handle, SigThreadSuspendResume) == ESRCH)
+                return;
+            sem_wait(&amp;m_semaphoreForSuspendResume);
+            // Release barrier ensures that this operation is always executed after all the above processing is done.
+            m_suspended.store(false, std::memory_order_release);
+        }
+        --m_suspendCount;
+    }
+#endif
+}
+
+size_t Thread::getRegisters(PlatformRegisters&amp; registers)
+{
+    std::unique_lock&lt;std::mutex&gt; locker(m_mutex);
+#if OS(DARWIN)
+#if CPU(X86)
+    unsigned userCount = sizeof(registers) / sizeof(int);
+    thread_state_flavor_t flavor = i386_THREAD_STATE;
+#elif CPU(X86_64)
+    unsigned userCount = x86_THREAD_STATE64_COUNT;
+    thread_state_flavor_t flavor = x86_THREAD_STATE64;
+#elif CPU(PPC)
+    unsigned userCount = PPC_THREAD_STATE_COUNT;
+    thread_state_flavor_t flavor = PPC_THREAD_STATE;
+#elif CPU(PPC64)
+    unsigned userCount = PPC_THREAD_STATE64_COUNT;
+    thread_state_flavor_t flavor = PPC_THREAD_STATE64;
+#elif CPU(ARM)
+    unsigned userCount = ARM_THREAD_STATE_COUNT;
+    thread_state_flavor_t flavor = ARM_THREAD_STATE;
+#elif CPU(ARM64)
+    unsigned userCount = ARM_THREAD_STATE64_COUNT;
+    thread_state_flavor_t flavor = ARM_THREAD_STATE64;
+#else
+#error Unknown Architecture
+#endif
+
+    kern_return_t result = thread_get_state(m_platformThread, flavor, (thread_state_t)&amp;registers, &amp;userCount);
+    if (result != KERN_SUCCESS) {
+        WTFReportFatalError(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, &quot;JavaScript garbage collection failed because thread_get_state returned an error (%d). This is probably the result of running inside Rosetta, which is not supported.&quot;, result);
+        CRASH();
+    }
+    return userCount * sizeof(uintptr_t);
+#elif (OS(FREEBSD) || defined(__GLIBC__)) &amp;&amp; (CPU(X86) || CPU(X86_64) || CPU(ARM) || CPU(ARM64) || CPU(MIPS))
+    registers = m_suspendedMachineContext;
+    return sizeof(PlatformRegisters);
+#elif OS(OPENBSD)
+    // http://man.openbsd.org/pthread_stackseg_np.3
+    stack_t ss;
+    int rc = pthread_stackseg_np(m_handle, &amp;ss);
+    registers.stackPointer = ss.ss_sp;
+    return 0;
+#else
+    pthread_attr_t attribute;
+    pthread_attr_init(&amp;attribute);
+#if HAVE(PTHREAD_NP_H) || OS(NETBSD)
+    // e.g. on FreeBSD 5.4, neundorf@kde.org
+    pthread_attr_get_np(m_handle, &amp;attribute);
+#else
+    // FIXME: this function is non-portable; other POSIX systems may have different np alternatives
+    pthread_getattr_np(m_handle, &amp;attribute);
+#endif
+
+    void* stackBase = 0;
+    size_t stackSize = 0;
+    int rc = pthread_attr_getstack(&amp;attribute, &amp;stackBase, &amp;stackSize);
+    ASSERT_UNUSED(rc, !rc);
+    ASSERT(stackBase);
+    registers.stackPointer = static_cast&lt;char*&gt;(stackBase) + stackSize;
+
+    pthread_attr_destroy(&amp;attribute);
+
+    return 0;
+#endif
+}
+
+void Thread::establish(pthread_t handle)
+{
+    std::unique_lock&lt;std::mutex&gt; locker(m_mutex);
+    m_handle = handle;
+    if (!m_id) {
+        static std::atomic&lt;ThreadIdentifier&gt; provider { 0 };
+        m_id = ++provider;
+#if OS(DARWIN)
+        m_platformThread = pthread_mach_thread_np(handle);
+#endif
+    }
+}
+
</ins><span class="cx"> Mutex::Mutex()
</span><span class="cx"> {
</span><span class="cx">     pthread_mutexattr_t attr;
</span></span></pre></div>
<a id="trunkSourceWTFwtfThreadingWincpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/wtf/ThreadingWin.cpp (215264 => 215265)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/wtf/ThreadingWin.cpp        2017-04-12 10:14:30 UTC (rev 215264)
+++ trunk/Source/WTF/wtf/ThreadingWin.cpp        2017-04-12 12:08:29 UTC (rev 215265)
</span><span class="lines">@@ -88,20 +88,14 @@
</span><span class="cx"> 
</span><span class="cx"> #if OS(WINDOWS)
</span><span class="cx"> 
</span><del>-#include &quot;DateMath.h&quot;
-#include &quot;dtoa.h&quot;
-#include &quot;dtoa/cached-powers.h&quot;
-
-#include &quot;MainThread.h&quot;
-#include &quot;ThreadFunctionInvocation.h&quot;
</del><span class="cx"> #include &lt;process.h&gt;
</span><span class="cx"> #include &lt;windows.h&gt;
</span><span class="cx"> #include &lt;wtf/CurrentTime.h&gt;
</span><del>-#include &lt;wtf/HashMap.h&gt;
</del><ins>+#include &lt;wtf/MainThread.h&gt;
</ins><span class="cx"> #include &lt;wtf/MathExtras.h&gt;
</span><span class="cx"> #include &lt;wtf/NeverDestroyed.h&gt;
</span><del>-#include &lt;wtf/RandomNumberSeed.h&gt;
-#include &lt;wtf/WTFThreadData.h&gt;
</del><ins>+#include &lt;wtf/ThreadFunctionInvocation.h&gt;
+#include &lt;wtf/ThreadHolder.h&gt;
</ins><span class="cx"> 
</span><span class="cx"> #if HAVE(ERRNO_H)
</span><span class="cx"> #include &lt;errno.h&gt;
</span><span class="lines">@@ -109,6 +103,18 @@
</span><span class="cx"> 
</span><span class="cx"> namespace WTF {
</span><span class="cx"> 
</span><ins>+Thread::Thread()
+{
+}
+
+Thread::~Thread()
+{
+    // It is OK because FLSAlloc's callback will be called even before there are some open handles.
+    // This easily ensures that all the thread resources are automatically closed.
+    if (m_handle != INVALID_HANDLE_VALUE)
+        CloseHandle(m_handle);
+}
+
</ins><span class="cx"> // MS_VC_EXCEPTION, THREADNAME_INFO, and setThreadNameInternal all come from &lt;http://msdn.microsoft.com/en-us/library/xcb2z8hs.aspx&gt;.
</span><span class="cx"> static const DWORD MS_VC_EXCEPTION = 0x406D1388;
</span><span class="cx"> 
</span><span class="lines">@@ -121,7 +127,7 @@
</span><span class="cx"> } THREADNAME_INFO;
</span><span class="cx"> #pragma pack(pop)
</span><span class="cx"> 
</span><del>-void initializeCurrentThreadInternal(const char* szThreadName)
</del><ins>+void Thread::initializeCurrentThreadInternal(const char* szThreadName)
</ins><span class="cx"> {
</span><span class="cx"> #if COMPILER(MINGW)
</span><span class="cx">     // FIXME: Implement thread name setting with MingW.
</span><span class="lines">@@ -129,7 +135,7 @@
</span><span class="cx"> #else
</span><span class="cx">     THREADNAME_INFO info;
</span><span class="cx">     info.dwType = 0x1000;
</span><del>-    info.szName = normalizeThreadName(szThreadName);
</del><ins>+    info.szName = Thread::normalizeThreadName(szThreadName);
</ins><span class="cx">     info.dwThreadID = GetCurrentThreadId();
</span><span class="cx">     info.dwFlags = 0;
</span><span class="cx"> 
</span><span class="lines">@@ -140,70 +146,28 @@
</span><span class="cx"> #endif
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-static Mutex&amp; threadMapMutex()
</del><ins>+void Thread::initializePlatformThreading()
</ins><span class="cx"> {
</span><del>-    static NeverDestroyed&lt;Mutex&gt; mutex;
-    return mutex;
</del><span class="cx"> }
</span><span class="cx"> 
</span><del>-void initializeThreading()
</del><ins>+static unsigned __stdcall wtfThreadEntryPoint(void* param)
</ins><span class="cx"> {
</span><del>-    static bool isInitialized;
-    
-    if (isInitialized)
-        return;
</del><ins>+    // Balanced by .leakPtr() in Thread::createInternal.
+    auto invocation = std::unique_ptr&lt;ThreadFunctionInvocation&gt;(static_cast&lt;ThreadFunctionInvocation*&gt;(param));
</ins><span class="cx"> 
</span><del>-    isInitialized = true;
</del><ins>+    ThreadHolder::initialize(*invocation-&gt;thread);
+    invocation-&gt;thread = nullptr;
</ins><span class="cx"> 
</span><del>-    WTF::double_conversion::initialize();
-    // StringImpl::empty() does not construct its static string in a threadsafe fashion,
-    // so ensure it has been initialized from here.
-    StringImpl::empty();
-    threadMapMutex();
-    initializeRandomNumberGenerator();
-    wtfThreadData();
-    initializeDates();
-}
-
-static HashMap&lt;DWORD, HANDLE&gt;&amp; threadMap()
-{
-    static NeverDestroyed&lt;HashMap&lt;DWORD, HANDLE&gt;&gt; map;
-    return map;
-}
-
-static void storeThreadHandleByIdentifier(DWORD threadID, HANDLE threadHandle)
-{
-    MutexLocker locker(threadMapMutex());
-    ASSERT(!threadMap().contains(threadID));
-    threadMap().add(threadID, threadHandle);
-}
-
-static HANDLE threadHandleForIdentifier(ThreadIdentifier id)
-{
-    MutexLocker locker(threadMapMutex());
-    return threadMap().get(id);
-}
-
-static void clearThreadHandleForIdentifier(ThreadIdentifier id)
-{
-    MutexLocker locker(threadMapMutex());
-    ASSERT(threadMap().contains(id));
-    threadMap().remove(id);
-}
-
-static unsigned __stdcall wtfThreadEntryPoint(void* param)
-{
-    std::unique_ptr&lt;ThreadFunctionInvocation&gt; invocation(static_cast&lt;ThreadFunctionInvocation*&gt;(param));
</del><span class="cx">     invocation-&gt;function(invocation-&gt;data);
</span><del>-
</del><span class="cx">     return 0;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-ThreadIdentifier createThreadInternal(ThreadFunction entryPoint, void* data, const char* threadName)
</del><ins>+RefPtr&lt;Thread&gt; Thread::createInternal(ThreadFunction entryPoint, void* data, const char* threadName)
</ins><span class="cx"> {
</span><ins>+    Ref&lt;Thread&gt; thread = adoptRef(*new Thread());
</ins><span class="cx">     unsigned threadIdentifier = 0;
</span><span class="cx">     ThreadIdentifier threadID = 0;
</span><del>-    auto invocation = std::make_unique&lt;ThreadFunctionInvocation&gt;(entryPoint, data);
</del><ins>+    auto invocation = std::make_unique&lt;ThreadFunctionInvocation&gt;(entryPoint, thread.ptr(), data);
</ins><span class="cx">     HANDLE threadHandle = reinterpret_cast&lt;HANDLE&gt;(_beginthreadex(0, 0, wtfThreadEntryPoint, invocation.get(), 0, &amp;threadIdentifier));
</span><span class="cx">     if (!threadHandle) {
</span><span class="cx"> #if !HAVE(ERRNO_H)
</span><span class="lines">@@ -219,55 +183,111 @@
</span><span class="cx">     UNUSED_PARAM(leakedInvocation);
</span><span class="cx"> 
</span><span class="cx">     threadID = static_cast&lt;ThreadIdentifier&gt;(threadIdentifier);
</span><del>-    storeThreadHandleByIdentifier(threadIdentifier, threadHandle);
</del><span class="cx"> 
</span><del>-    return threadID;
</del><ins>+    thread-&gt;establish(threadHandle, threadIdentifier);
+    return thread;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-void changeThreadPriority(ThreadIdentifier threadID, int delta)
</del><ins>+void Thread::changePriority(int delta)
</ins><span class="cx"> {
</span><del>-    ASSERT(threadID);
-
-    HANDLE threadHandle = threadHandleForIdentifier(threadID);
-    if (!threadHandle)
-        LOG_ERROR(&quot;ThreadIdentifier %u does not correspond to an active thread&quot;, threadID);
-
-    SetThreadPriority(threadHandle, THREAD_PRIORITY_NORMAL + delta);
</del><ins>+    std::unique_lock&lt;std::mutex&gt; locker(m_mutex);
+    SetThreadPriority(m_handle, THREAD_PRIORITY_NORMAL + delta);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-int waitForThreadCompletion(ThreadIdentifier threadID)
</del><ins>+int Thread::waitForCompletion()
</ins><span class="cx"> {
</span><del>-    ASSERT(threadID);
-    
-    HANDLE threadHandle = threadHandleForIdentifier(threadID);
-    if (!threadHandle)
-        LOG_ERROR(&quot;ThreadIdentifier %u did not correspond to an active thread when trying to quit&quot;, threadID);

-    DWORD joinResult = WaitForSingleObject(threadHandle, INFINITE);
</del><ins>+    HANDLE handle;
+    {
+        std::unique_lock&lt;std::mutex&gt; locker(m_mutex);
+        handle = m_handle;
+    }
+
+    DWORD joinResult = WaitForSingleObject(handle, INFINITE);
</ins><span class="cx">     if (joinResult == WAIT_FAILED)
</span><del>-        LOG_ERROR(&quot;ThreadIdentifier %u was found to be deadlocked trying to quit&quot;, threadID);
</del><ins>+        LOG_ERROR(&quot;ThreadIdentifier %u was found to be deadlocked trying to quit&quot;, m_id);
</ins><span class="cx"> 
</span><del>-    CloseHandle(threadHandle);
-    clearThreadHandleForIdentifier(threadID);
</del><ins>+    std::unique_lock&lt;std::mutex&gt; locker(m_mutex);
+    ASSERT(joinableState() == Joinable);
</ins><span class="cx"> 
</span><ins>+    // The thread has already exited, do nothing.
+    // The thread hasn't exited yet, so don't clean anything up. Just signal that we've already joined on it so that it will clean up after itself.
+    if (!hasExited())
+        didJoin();
+
</ins><span class="cx">     return joinResult;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void detachThread(ThreadIdentifier threadID)
</del><ins>+void Thread::detach()
</ins><span class="cx"> {
</span><del>-    ASSERT(threadID);
</del><ins>+    // We follow the pthread semantics: even after the detach is called,
+    // we can still perform various operations onto the thread. For example,
+    // we can do pthread_kill for the detached thread. The problem in Windows
+    // is that closing HANDLE loses the way to do such operations.
+    // To do so, we do nothing here in Windows. Original detach's purpose,
+    // releasing thread resource when the thread exits, will be achieved by
+    // FlsCallback automatically. FlsCallback will call CloseHandle to clean up
+    // resource. So in this function, we just mark the thread as detached to
+    // avoid calling waitForCompletion for this thread.
+    std::unique_lock&lt;std::mutex&gt; locker(m_mutex);
+    if (!hasExited())
+        didBecomeDetached();
+}
</ins><span class="cx"> 
</span><del>-    HANDLE threadHandle = threadHandleForIdentifier(threadID);
-    if (threadHandle)
-        CloseHandle(threadHandle);
-    clearThreadHandleForIdentifier(threadID);
</del><ins>+auto Thread::suspend() -&gt; Expected&lt;void, PlatformSuspendError&gt;
+{
+    RELEASE_ASSERT_WITH_MESSAGE(id() != currentThread(), &quot;We do not support suspending the current thread itself.&quot;);
+    std::unique_lock&lt;std::mutex&gt; locker(m_mutex);
+    DWORD result = SuspendThread(m_handle);
+    if (result != (DWORD)-1)
+        return { };
+    return makeUnexpected(result);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-ThreadIdentifier currentThread()
</del><ins>+// During resume, suspend or resume should not be executed from the other threads.
+void Thread::resume()
</ins><span class="cx"> {
</span><ins>+    std::unique_lock&lt;std::mutex&gt; locker(m_mutex);
+    ResumeThread(m_handle);
+}
+
+size_t Thread::getRegisters(PlatformRegisters&amp; registers)
+{
+    std::unique_lock&lt;std::mutex&gt; locker(m_mutex);
+    registers.ContextFlags = CONTEXT_INTEGER | CONTEXT_CONTROL;
+    GetThreadContext(m_handle, &amp;registers);
+    return sizeof(CONTEXT);
+}
+
+Thread&amp; Thread::current()
+{
+    ThreadHolder* data = ThreadHolder::current();
+    if (data)
+        return data-&gt;thread();
+
+    // Not a WTF-created thread, ThreadIdentifier is not established yet.
+    Ref&lt;Thread&gt; thread = adoptRef(*new Thread());
+
+    HANDLE handle;
+    bool isSuccessful = DuplicateHandle(GetCurrentProcess(), GetCurrentThread(), GetCurrentProcess(), &amp;handle, 0, FALSE, DUPLICATE_SAME_ACCESS);
+    RELEASE_ASSERT(isSuccessful);
+
+    thread-&gt;establish(handle, currentID());
+    ThreadHolder::initialize(thread.get());
+    return thread.get();
+}
+
+ThreadIdentifier Thread::currentID()
+{
</ins><span class="cx">     return static_cast&lt;ThreadIdentifier&gt;(GetCurrentThreadId());
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void Thread::establish(HANDLE handle, ThreadIdentifier threadID)
+{
+    std::unique_lock&lt;std::mutex&gt; locker(m_mutex);
+    m_handle = handle;
+    m_id = threadID;
+}
+
</ins><span class="cx"> Mutex::Mutex()
</span><span class="cx"> {
</span><span class="cx">     m_mutex.m_recursionCount = 0;
</span></span></pre></div>
<a id="trunkSourceWTFwtfWorkQueuecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/wtf/WorkQueue.cpp (215264 => 215265)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/wtf/WorkQueue.cpp        2017-04-12 10:14:30 UTC (rev 215264)
+++ trunk/Source/WTF/wtf/WorkQueue.cpp        2017-04-12 12:08:29 UTC (rev 215265)
</span><span class="lines">@@ -74,7 +74,7 @@
</span><span class="cx"> 
</span><span class="cx">             m_workers.reserveInitialCapacity(threadCount);
</span><span class="cx">             for (unsigned i = 0; i &lt; threadCount; ++i) {
</span><del>-                m_workers.append(createThread(String::format(&quot;ThreadPool Worker %u&quot;, i).utf8().data(), [this] {
</del><ins>+                m_workers.append(Thread::create(String::format(&quot;ThreadPool Worker %u&quot;, i).utf8().data(), [this] {
</ins><span class="cx">                     threadBody();
</span><span class="cx">                 }));
</span><span class="cx">             }
</span><span class="lines">@@ -114,7 +114,7 @@
</span><span class="cx">         Condition m_condition;
</span><span class="cx">         Deque&lt;const std::function&lt;void ()&gt;*&gt; m_queue;
</span><span class="cx"> 
</span><del>-        Vector&lt;ThreadIdentifier&gt; m_workers;
</del><ins>+        Vector&lt;RefPtr&lt;Thread&gt;&gt; m_workers;
</ins><span class="cx">     };
</span><span class="cx"> 
</span><span class="cx">     static LazyNeverDestroyed&lt;ThreadPool&gt; threadPool;
</span></span></pre></div>
<a id="trunkSourceWTFwtfWorkQueueh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/wtf/WorkQueue.h (215264 => 215265)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/wtf/WorkQueue.h        2017-04-12 10:14:30 UTC (rev 215264)
+++ trunk/Source/WTF/wtf/WorkQueue.h        2017-04-12 12:08:29 UTC (rev 215265)
</span><span class="lines">@@ -103,7 +103,7 @@
</span><span class="cx"> 
</span><span class="cx">     HANDLE m_timerQueue;
</span><span class="cx"> #elif USE(GLIB_EVENT_LOOP) || USE(GENERIC_EVENT_LOOP)
</span><del>-    ThreadIdentifier m_workQueueThread;
</del><ins>+    RefPtr&lt;Thread&gt; m_workQueueThread;
</ins><span class="cx">     Lock m_initializeRunLoopConditionMutex;
</span><span class="cx">     Condition m_initializeRunLoopCondition;
</span><span class="cx">     RunLoop* m_runLoop;
</span></span></pre></div>
<a id="trunkSourceWTFwtfcocoaWorkQueueCocoacpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/wtf/cocoa/WorkQueueCocoa.cpp (215264 => 215265)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/wtf/cocoa/WorkQueueCocoa.cpp        2017-04-12 10:14:30 UTC (rev 215264)
+++ trunk/Source/WTF/wtf/cocoa/WorkQueueCocoa.cpp        2017-04-12 12:08:29 UTC (rev 215265)
</span><span class="lines">@@ -49,15 +49,15 @@
</span><span class="cx"> {
</span><span class="cx">     switch (qos) {
</span><span class="cx">     case WorkQueue::QOS::UserInteractive:
</span><del>-        return adjustedQOSClass(QOS_CLASS_USER_INTERACTIVE);
</del><ins>+        return Thread::adjustedQOSClass(QOS_CLASS_USER_INTERACTIVE);
</ins><span class="cx">     case WorkQueue::QOS::UserInitiated:
</span><del>-        return adjustedQOSClass(QOS_CLASS_USER_INITIATED);
</del><ins>+        return Thread::adjustedQOSClass(QOS_CLASS_USER_INITIATED);
</ins><span class="cx">     case WorkQueue::QOS::Default:
</span><del>-        return adjustedQOSClass(QOS_CLASS_DEFAULT);
</del><ins>+        return Thread::adjustedQOSClass(QOS_CLASS_DEFAULT);
</ins><span class="cx">     case WorkQueue::QOS::Utility:
</span><del>-        return adjustedQOSClass(QOS_CLASS_UTILITY);
</del><ins>+        return Thread::adjustedQOSClass(QOS_CLASS_UTILITY);
</ins><span class="cx">     case WorkQueue::QOS::Background:
</span><del>-        return adjustedQOSClass(QOS_CLASS_BACKGROUND);
</del><ins>+        return Thread::adjustedQOSClass(QOS_CLASS_BACKGROUND);
</ins><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> #else
</span></span></pre></div>
<a id="trunkSourceWTFwtfgenericWorkQueueGenericcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/wtf/generic/WorkQueueGeneric.cpp (215264 => 215265)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/wtf/generic/WorkQueueGeneric.cpp        2017-04-12 10:14:30 UTC (rev 215264)
+++ trunk/Source/WTF/wtf/generic/WorkQueueGeneric.cpp        2017-04-12 12:08:29 UTC (rev 215265)
</span><span class="lines">@@ -35,7 +35,7 @@
</span><span class="cx"> void WorkQueue::platformInitialize(const char* name, Type, QOS)
</span><span class="cx"> {
</span><span class="cx">     LockHolder locker(m_initializeRunLoopConditionMutex);
</span><del>-    m_workQueueThread = createThread(name, [this] {
</del><ins>+    m_workQueueThread = Thread::create(name, [this] {
</ins><span class="cx">         {
</span><span class="cx">             LockHolder locker(m_initializeRunLoopConditionMutex);
</span><span class="cx">             m_runLoop = &amp;RunLoop::current();
</span><span class="lines">@@ -51,8 +51,8 @@
</span><span class="cx">     if (m_runLoop)
</span><span class="cx">         m_runLoop-&gt;stop();
</span><span class="cx">     if (m_workQueueThread) {
</span><del>-        detachThread(m_workQueueThread);
-        m_workQueueThread = 0;
</del><ins>+        m_workQueueThread-&gt;detach();
+        m_workQueueThread = nullptr;
</ins><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWTFwtflinuxMemoryPressureHandlerLinuxcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/wtf/linux/MemoryPressureHandlerLinux.cpp (215264 => 215265)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/wtf/linux/MemoryPressureHandlerLinux.cpp        2017-04-12 10:14:30 UTC (rev 215264)
+++ trunk/Source/WTF/wtf/linux/MemoryPressureHandlerLinux.cpp        2017-04-12 12:08:29 UTC (rev 215265)
</span><span class="lines">@@ -119,7 +119,10 @@
</span><span class="cx">     }, this, nullptr);
</span><span class="cx">     g_source_attach(m_source.get(), nullptr);
</span><span class="cx"> #else
</span><del>-    m_threadID = createThread(&quot;WTF: MemoryPressureHandler&quot;, [this] { readAndNotify(); }
</del><ins>+    m_thread = Thread::create(&quot;WTF: MemoryPressureHandler&quot;,
+        [this] {
+            readAndNotify();
+        });
</ins><span class="cx"> #endif
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -129,7 +132,7 @@
</span><span class="cx"> #if USE(GLIB)
</span><span class="cx">     g_source_destroy(m_source.get());
</span><span class="cx"> #else
</span><del>-    detachThread(m_threadID);
</del><ins>+    m_thread-&gt;detach();
</ins><span class="cx"> #endif
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWTFwtfwinMainThreadWincpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/wtf/win/MainThreadWin.cpp (215264 => 215265)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/wtf/win/MainThreadWin.cpp        2017-04-12 10:14:30 UTC (rev 215264)
+++ trunk/Source/WTF/wtf/win/MainThreadWin.cpp        2017-04-12 12:08:29 UTC (rev 215265)
</span><span class="lines">@@ -64,7 +64,7 @@
</span><span class="cx">         CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, HWND_MESSAGE, 0, 0, 0);
</span><span class="cx">     threadingFiredMessage = RegisterWindowMessageW(L&quot;com.apple.WebKit.MainThreadFired&quot;);
</span><span class="cx"> 
</span><del>-    initializeCurrentThreadInternal(&quot;Main Thread&quot;);
</del><ins>+    Thread::initializeCurrentThreadInternal(&quot;Main Thread&quot;);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void scheduleDispatchFunctionsOnMainThread()
</span></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (215264 => 215265)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2017-04-12 10:14:30 UTC (rev 215264)
+++ trunk/Source/WebCore/ChangeLog        2017-04-12 12:08:29 UTC (rev 215265)
</span><span class="lines">@@ -1,3 +1,83 @@
</span><ins>+2017-04-12  Yusuke Suzuki  &lt;utatane.tea@gmail.com&gt;
+
+        [WTF] Introduce Thread class and use RefPtr&lt;Thread&gt; and align Windows Threading implementation semantics to Pthread one
+        https://bugs.webkit.org/show_bug.cgi?id=170502
+
+        Reviewed by Mark Lam.
+
+        Mechanical change. Use Thread:: APIs.
+
+        * Modules/indexeddb/server/IDBServer.cpp:
+        (WebCore::IDBServer::IDBServer::IDBServer):
+        * Modules/indexeddb/server/IDBServer.h:
+        * Modules/webaudio/AsyncAudioDecoder.cpp:
+        (WebCore::AsyncAudioDecoder::AsyncAudioDecoder):
+        (WebCore::AsyncAudioDecoder::~AsyncAudioDecoder):
+        (WebCore::AsyncAudioDecoder::runLoop):
+        * Modules/webaudio/AsyncAudioDecoder.h:
+        * Modules/webaudio/OfflineAudioDestinationNode.cpp:
+        (WebCore::OfflineAudioDestinationNode::OfflineAudioDestinationNode):
+        (WebCore::OfflineAudioDestinationNode::uninitialize):
+        (WebCore::OfflineAudioDestinationNode::startRendering):
+        * Modules/webaudio/OfflineAudioDestinationNode.h:
+        * Modules/webdatabase/Database.cpp:
+        (WebCore::Database::securityOrigin):
+        * Modules/webdatabase/DatabaseThread.cpp:
+        (WebCore::DatabaseThread::start):
+        (WebCore::DatabaseThread::databaseThread):
+        (WebCore::DatabaseThread::recordDatabaseOpen):
+        (WebCore::DatabaseThread::recordDatabaseClosed):
+        * Modules/webdatabase/DatabaseThread.h:
+        (WebCore::DatabaseThread::getThreadID):
+        * bindings/js/GCController.cpp:
+        (WebCore::GCController::garbageCollectOnAlternateThreadForDebugging):
+        * fileapi/AsyncFileStream.cpp:
+        (WebCore::callOnFileThread):
+        * loader/icon/IconDatabase.cpp:
+        (WebCore::IconDatabase::open):
+        (WebCore::IconDatabase::close):
+        * loader/icon/IconDatabase.h:
+        * page/ResourceUsageThread.cpp:
+        (WebCore::ResourceUsageThread::createThreadIfNeeded):
+        * page/ResourceUsageThread.h:
+        * page/scrolling/ScrollingThread.cpp:
+        (WebCore::ScrollingThread::ScrollingThread):
+        (WebCore::ScrollingThread::isCurrentThread):
+        (WebCore::ScrollingThread::createThreadIfNeeded):
+        (WebCore::ScrollingThread::threadCallback):
+        * page/scrolling/ScrollingThread.h:
+        * platform/audio/HRTFDatabaseLoader.cpp:
+        (WebCore::HRTFDatabaseLoader::HRTFDatabaseLoader):
+        (WebCore::HRTFDatabaseLoader::loadAsynchronously):
+        (WebCore::HRTFDatabaseLoader::waitForLoaderThreadCompletion):
+        * platform/audio/HRTFDatabaseLoader.h:
+        * platform/audio/ReverbConvolver.cpp:
+        (WebCore::ReverbConvolver::ReverbConvolver):
+        (WebCore::ReverbConvolver::~ReverbConvolver):
+        * platform/audio/ReverbConvolver.h:
+        * platform/audio/gstreamer/AudioFileReaderGStreamer.cpp:
+        (WebCore::createBusFromAudioFile):
+        (WebCore::createBusFromInMemoryAudioFile):
+        * platform/graphics/gstreamer/WebKitWebSourceGStreamer.cpp:
+        (ResourceHandleStreamingClient::ResourceHandleStreamingClient):
+        (ResourceHandleStreamingClient::~ResourceHandleStreamingClient):
+        * platform/network/cf/LoaderRunLoopCF.cpp:
+        (WebCore::loaderRunLoop):
+        * platform/network/curl/CurlDownload.cpp:
+        (WebCore::CurlDownloadManager::startThreadIfNeeded):
+        (WebCore::CurlDownloadManager::stopThread):
+        * platform/network/curl/CurlDownload.h:
+        * platform/network/curl/SocketStreamHandleImpl.h:
+        * platform/network/curl/SocketStreamHandleImplCurl.cpp:
+        (WebCore::SocketStreamHandleImpl::startThread):
+        (WebCore::SocketStreamHandleImpl::stopThread):
+        * workers/WorkerThread.cpp:
+        (WebCore::WorkerThread::WorkerThread):
+        (WebCore::WorkerThread::start):
+        (WebCore::WorkerThread::workerThread):
+        * workers/WorkerThread.h:
+        (WebCore::WorkerThread::threadID):
+
</ins><span class="cx"> 2017-04-10  Antti Koivisto  &lt;antti@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Cache small media resources in disk cache
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddbserverIDBServercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/indexeddb/server/IDBServer.cpp (215264 => 215265)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/indexeddb/server/IDBServer.cpp        2017-04-12 10:14:30 UTC (rev 215264)
+++ trunk/Source/WebCore/Modules/indexeddb/server/IDBServer.cpp        2017-04-12 12:08:29 UTC (rev 215265)
</span><span class="lines">@@ -56,7 +56,7 @@
</span><span class="cx">     : m_backingStoreTemporaryFileHandler(fileHandler)
</span><span class="cx"> {
</span><span class="cx">     Locker&lt;Lock&gt; locker(m_databaseThreadCreationLock);
</span><del>-    m_threadID = createThread(IDBServer::databaseThreadEntry, this, &quot;IndexedDatabase Server&quot;);
</del><ins>+    m_thread = Thread::create(IDBServer::databaseThreadEntry, this, &quot;IndexedDatabase Server&quot;);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> IDBServer::IDBServer(const String&amp; databaseDirectoryPath, IDBBackingStoreTemporaryFileHandler&amp; fileHandler)
</span><span class="lines">@@ -66,7 +66,7 @@
</span><span class="cx">     LOG(IndexedDB, &quot;IDBServer created at path %s&quot;, databaseDirectoryPath.utf8().data());
</span><span class="cx"> 
</span><span class="cx">     Locker&lt;Lock&gt; locker(m_databaseThreadCreationLock);
</span><del>-    m_threadID = createThread(IDBServer::databaseThreadEntry, this, &quot;IndexedDatabase Server&quot;);
</del><ins>+    m_thread = Thread::create(IDBServer::databaseThreadEntry, this, &quot;IndexedDatabase Server&quot;);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void IDBServer::registerConnection(IDBConnectionToClient&amp; connection)
</span></span></pre></div>
<a id="trunkSourceWebCoreModulesindexeddbserverIDBServerh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/indexeddb/server/IDBServer.h (215264 => 215265)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/indexeddb/server/IDBServer.h        2017-04-12 10:14:30 UTC (rev 215264)
+++ trunk/Source/WebCore/Modules/indexeddb/server/IDBServer.h        2017-04-12 12:08:29 UTC (rev 215265)
</span><span class="lines">@@ -125,7 +125,7 @@
</span><span class="cx">     HashMap&lt;uint64_t, RefPtr&lt;IDBConnectionToClient&gt;&gt; m_connectionMap;
</span><span class="cx">     HashMap&lt;IDBDatabaseIdentifier, RefPtr&lt;UniqueIDBDatabase&gt;&gt; m_uniqueIDBDatabaseMap;
</span><span class="cx"> 
</span><del>-    ThreadIdentifier m_threadID { 0 };
</del><ins>+    RefPtr&lt;Thread&gt; m_thread { nullptr };
</ins><span class="cx">     Lock m_databaseThreadCreationLock;
</span><span class="cx">     Lock m_mainThreadReplyLock;
</span><span class="cx">     bool m_mainThreadReplyScheduled { false };
</span></span></pre></div>
<a id="trunkSourceWebCoreModuleswebaudioAsyncAudioDecodercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/webaudio/AsyncAudioDecoder.cpp (215264 => 215265)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/webaudio/AsyncAudioDecoder.cpp        2017-04-12 10:14:30 UTC (rev 215264)
+++ trunk/Source/WebCore/Modules/webaudio/AsyncAudioDecoder.cpp        2017-04-12 12:08:29 UTC (rev 215265)
</span><span class="lines">@@ -39,7 +39,7 @@
</span><span class="cx"> {
</span><span class="cx">     // Start worker thread.
</span><span class="cx">     LockHolder lock(m_threadCreationMutex);
</span><del>-    m_threadID = createThread(AsyncAudioDecoder::threadEntry, this, &quot;Audio Decoder&quot;);
</del><ins>+    m_thread = Thread::create(AsyncAudioDecoder::threadEntry, this, &quot;Audio Decoder&quot;);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> AsyncAudioDecoder::~AsyncAudioDecoder()
</span><span class="lines">@@ -47,8 +47,8 @@
</span><span class="cx">     m_queue.kill();
</span><span class="cx">     
</span><span class="cx">     // Stop thread.
</span><del>-    waitForThreadCompletion(m_threadID);
-    m_threadID = 0;
</del><ins>+    m_thread-&gt;waitForCompletion();
+    m_thread = nullptr;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void AsyncAudioDecoder::decodeAsync(Ref&lt;ArrayBuffer&gt;&amp;&amp; audioData, float sampleRate, RefPtr&lt;AudioBufferCallback&gt;&amp;&amp; successCallback, RefPtr&lt;AudioBufferCallback&gt;&amp;&amp; errorCallback)
</span><span class="lines">@@ -72,7 +72,7 @@
</span><span class="cx">     ASSERT(!isMainThread());
</span><span class="cx"> 
</span><span class="cx">     {
</span><del>-        // Wait for until we have m_threadID established before starting the run loop.
</del><ins>+        // Wait for until we have m_thread established before starting the run loop.
</ins><span class="cx">         LockHolder lock(m_threadCreationMutex);
</span><span class="cx">     }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreModuleswebaudioAsyncAudioDecoderh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/webaudio/AsyncAudioDecoder.h (215264 => 215265)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/webaudio/AsyncAudioDecoder.h        2017-04-12 10:14:30 UTC (rev 215264)
+++ trunk/Source/WebCore/Modules/webaudio/AsyncAudioDecoder.h        2017-04-12 12:08:29 UTC (rev 215265)
</span><span class="lines">@@ -77,7 +77,7 @@
</span><span class="cx">     static void threadEntry(void* threadData);
</span><span class="cx">     void runLoop();
</span><span class="cx"> 
</span><del>-    WTF::ThreadIdentifier m_threadID;
</del><ins>+    RefPtr&lt;Thread&gt; m_thread;
</ins><span class="cx">     Lock m_threadCreationMutex;
</span><span class="cx">     MessageQueue&lt;DecodingTask&gt; m_queue;
</span><span class="cx"> };
</span></span></pre></div>
<a id="trunkSourceWebCoreModuleswebaudioOfflineAudioDestinationNodecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/webaudio/OfflineAudioDestinationNode.cpp (215264 => 215265)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/webaudio/OfflineAudioDestinationNode.cpp        2017-04-12 10:14:30 UTC (rev 215264)
+++ trunk/Source/WebCore/Modules/webaudio/OfflineAudioDestinationNode.cpp        2017-04-12 12:08:29 UTC (rev 215265)
</span><span class="lines">@@ -41,7 +41,6 @@
</span><span class="cx"> OfflineAudioDestinationNode::OfflineAudioDestinationNode(AudioContext&amp; context, AudioBuffer* renderTarget)
</span><span class="cx">     : AudioDestinationNode(context, renderTarget-&gt;sampleRate())
</span><span class="cx">     , m_renderTarget(renderTarget)
</span><del>-    , m_renderThread(0)
</del><span class="cx">     , m_startedRendering(false)
</span><span class="cx"> {
</span><span class="cx">     m_renderBus = AudioBus::create(renderTarget-&gt;numberOfChannels(), renderQuantumSize);
</span><span class="lines">@@ -66,8 +65,8 @@
</span><span class="cx">         return;
</span><span class="cx"> 
</span><span class="cx">     if (m_renderThread) {
</span><del>-        waitForThreadCompletion(m_renderThread);
-        m_renderThread = 0;
</del><ins>+        m_renderThread-&gt;waitForCompletion();
+        m_renderThread = nullptr;
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     AudioNode::uninitialize();
</span><span class="lines">@@ -83,7 +82,7 @@
</span><span class="cx">     if (!m_startedRendering) {
</span><span class="cx">         m_startedRendering = true;
</span><span class="cx">         ref(); // See corresponding deref() call in notifyCompleteDispatch().
</span><del>-        m_renderThread = createThread(OfflineAudioDestinationNode::offlineRenderEntry, this, &quot;offline renderer&quot;);
</del><ins>+        m_renderThread = Thread::create(OfflineAudioDestinationNode::offlineRenderEntry, this, &quot;offline renderer&quot;);
</ins><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreModuleswebaudioOfflineAudioDestinationNodeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/webaudio/OfflineAudioDestinationNode.h (215264 => 215265)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/webaudio/OfflineAudioDestinationNode.h        2017-04-12 10:14:30 UTC (rev 215264)
+++ trunk/Source/WebCore/Modules/webaudio/OfflineAudioDestinationNode.h        2017-04-12 12:08:29 UTC (rev 215265)
</span><span class="lines">@@ -63,7 +63,7 @@
</span><span class="cx">     RefPtr&lt;AudioBus&gt; m_renderBus;
</span><span class="cx">     
</span><span class="cx">     // Rendering thread.
</span><del>-    volatile ThreadIdentifier m_renderThread;
</del><ins>+    RefPtr&lt;Thread&gt; m_renderThread;
</ins><span class="cx">     bool m_startedRendering;
</span><span class="cx">     static void offlineRenderEntry(void* threadData);
</span><span class="cx">     void offlineRender();
</span></span></pre></div>
<a id="trunkSourceWebCoreModuleswebdatabaseDatabasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/webdatabase/Database.cpp (215264 => 215265)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/webdatabase/Database.cpp        2017-04-12 10:14:30 UTC (rev 215264)
+++ trunk/Source/WebCore/Modules/webdatabase/Database.cpp        2017-04-12 12:08:29 UTC (rev 215265)
</span><span class="lines">@@ -770,8 +770,7 @@
</span><span class="cx"> {
</span><span class="cx">     if (m_scriptExecutionContext-&gt;isContextThread())
</span><span class="cx">         return SecurityOriginData::fromSecurityOrigin(m_contextThreadSecurityOrigin.get());
</span><del>-    auto&amp; thread = databaseThread();
-    if (currentThread() == thread.getThreadID())
</del><ins>+    if (currentThread() == databaseThread().getThreadID())
</ins><span class="cx">         return SecurityOriginData::fromSecurityOrigin(m_databaseThreadSecurityOrigin.get());
</span><span class="cx">     RELEASE_ASSERT_NOT_REACHED();
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceWebCoreModuleswebdatabaseDatabaseThreadcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/webdatabase/DatabaseThread.cpp (215264 => 215265)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/webdatabase/DatabaseThread.cpp        2017-04-12 10:14:30 UTC (rev 215264)
+++ trunk/Source/WebCore/Modules/webdatabase/DatabaseThread.cpp        2017-04-12 12:08:29 UTC (rev 215265)
</span><span class="lines">@@ -60,12 +60,12 @@
</span><span class="cx"> {
</span><span class="cx">     LockHolder lock(m_threadCreationMutex);
</span><span class="cx"> 
</span><del>-    if (m_threadID)
</del><ins>+    if (m_thread)
</ins><span class="cx">         return true;
</span><span class="cx"> 
</span><del>-    m_threadID = createThread(DatabaseThread::databaseThreadStart, this, &quot;WebCore: Database&quot;);
</del><ins>+    m_thread = Thread::create(DatabaseThread::databaseThreadStart, this, &quot;WebCore: Database&quot;);
</ins><span class="cx"> 
</span><del>-    return m_threadID;
</del><ins>+    return m_thread;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void DatabaseThread::requestTermination(DatabaseTaskSynchronizer* cleanupSync)
</span><span class="lines">@@ -110,7 +110,7 @@
</span><span class="cx">     // Clean up the list of all pending transactions on this database thread
</span><span class="cx">     m_transactionCoordinator-&gt;shutdown();
</span><span class="cx"> 
</span><del>-    LOG(StorageAPI, &quot;About to detach thread %i and clear the ref to DatabaseThread %p, which currently has %i ref(s)&quot;, m_threadID, this, refCount());
</del><ins>+    LOG(StorageAPI, &quot;About to detach thread %i and clear the ref to DatabaseThread %p, which currently has %i ref(s)&quot;, m_thread-&gt;id(), this, refCount());
</ins><span class="cx"> 
</span><span class="cx">     // Close the databases that we ran transactions on. This ensures that if any transactions are still open, they are rolled back and we don't leave the database in an
</span><span class="cx">     // inconsistent or locked state.
</span><span class="lines">@@ -127,7 +127,7 @@
</span><span class="cx">         openDatabase-&gt;performClose();
</span><span class="cx"> 
</span><span class="cx">     // Detach the thread so its resources are no longer of any concern to anyone else
</span><del>-    detachThread(m_threadID);
</del><ins>+    m_thread-&gt;detach();
</ins><span class="cx"> 
</span><span class="cx">     DatabaseTaskSynchronizer* cleanupSync = m_cleanupSync;
</span><span class="cx"> 
</span><span class="lines">@@ -142,7 +142,7 @@
</span><span class="cx"> {
</span><span class="cx">     LockHolder lock(m_openDatabaseSetMutex);
</span><span class="cx"> 
</span><del>-    ASSERT(currentThread() == m_threadID);
</del><ins>+    ASSERT(currentThread() == m_thread-&gt;id());
</ins><span class="cx">     ASSERT(!m_openDatabaseSet.contains(&amp;database));
</span><span class="cx">     m_openDatabaseSet.add(&amp;database);
</span><span class="cx"> }
</span><span class="lines">@@ -151,7 +151,7 @@
</span><span class="cx"> {
</span><span class="cx">     LockHolder lock(m_openDatabaseSetMutex);
</span><span class="cx"> 
</span><del>-    ASSERT(currentThread() == m_threadID);
</del><ins>+    ASSERT(currentThread() == m_thread-&gt;id());
</ins><span class="cx">     ASSERT(m_queue.killed() || m_openDatabaseSet.contains(&amp;database));
</span><span class="cx">     m_openDatabaseSet.remove(&amp;database);
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceWebCoreModuleswebdatabaseDatabaseThreadh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/Modules/webdatabase/DatabaseThread.h (215264 => 215265)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/Modules/webdatabase/DatabaseThread.h        2017-04-12 10:14:30 UTC (rev 215264)
+++ trunk/Source/WebCore/Modules/webdatabase/DatabaseThread.h        2017-04-12 12:08:29 UTC (rev 215265)
</span><span class="lines">@@ -58,7 +58,7 @@
</span><span class="cx"> 
</span><span class="cx">     void recordDatabaseOpen(Database&amp;);
</span><span class="cx">     void recordDatabaseClosed(Database&amp;);
</span><del>-    ThreadIdentifier getThreadID() { return m_threadID; }
</del><ins>+    ThreadIdentifier getThreadID() { return m_thread ? m_thread-&gt;id() : 0; }
</ins><span class="cx"> 
</span><span class="cx">     SQLTransactionCoordinator* transactionCoordinator() { return m_transactionCoordinator.get(); }
</span><span class="cx"> 
</span><span class="lines">@@ -69,7 +69,7 @@
</span><span class="cx">     void databaseThread();
</span><span class="cx"> 
</span><span class="cx">     Lock m_threadCreationMutex;
</span><del>-    ThreadIdentifier m_threadID { 0 };
</del><ins>+    RefPtr&lt;Thread&gt; m_thread;
</ins><span class="cx">     RefPtr&lt;DatabaseThread&gt; m_selfRef;
</span><span class="cx"> 
</span><span class="cx">     MessageQueue&lt;DatabaseTask&gt; m_queue;
</span></span></pre></div>
<a id="trunkSourceWebCorebindingsjsGCControllercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/bindings/js/GCController.cpp (215264 => 215265)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/bindings/js/GCController.cpp        2017-04-12 10:14:30 UTC (rev 215264)
+++ trunk/Source/WebCore/bindings/js/GCController.cpp        2017-04-12 12:08:29 UTC (rev 215265)
</span><span class="lines">@@ -101,14 +101,14 @@
</span><span class="cx"> 
</span><span class="cx"> void GCController::garbageCollectOnAlternateThreadForDebugging(bool waitUntilDone)
</span><span class="cx"> {
</span><del>-    ThreadIdentifier threadID = createThread(collect, 0, &quot;WebCore: GCController&quot;);
</del><ins>+    RefPtr&lt;Thread&gt; thread = Thread::create(collect, 0, &quot;WebCore: GCController&quot;);
</ins><span class="cx"> 
</span><span class="cx">     if (waitUntilDone) {
</span><del>-        waitForThreadCompletion(threadID);
</del><ins>+        thread-&gt;waitForCompletion();
</ins><span class="cx">         return;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    detachThread(threadID);
</del><ins>+    thread-&gt;detach();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void GCController::setJavaScriptGarbageCollectorTimerEnabled(bool enable)
</span></span></pre></div>
<a id="trunkSourceWebCorefileapiAsyncFileStreamcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/fileapi/AsyncFileStream.cpp (215264 => 215265)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/fileapi/AsyncFileStream.cpp        2017-04-12 10:14:30 UTC (rev 215264)
+++ trunk/Source/WebCore/fileapi/AsyncFileStream.cpp        2017-04-12 12:08:29 UTC (rev 215265)
</span><span class="lines">@@ -74,7 +74,7 @@
</span><span class="cx"> 
</span><span class="cx">     static std::once_flag createFileThreadOnce;
</span><span class="cx">     std::call_once(createFileThreadOnce, [] {
</span><del>-        createThread(&quot;WebCore: AsyncFileStream&quot;, [] {
</del><ins>+        Thread::create(&quot;WebCore: AsyncFileStream&quot;, [] {
</ins><span class="cx">             for (;;) {
</span><span class="cx">                 AutodrainedPool pool;
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreloadericonIconDatabasecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/loader/icon/IconDatabase.cpp (215264 => 215265)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/loader/icon/IconDatabase.cpp        2017-04-12 10:14:30 UTC (rev 215264)
+++ trunk/Source/WebCore/loader/icon/IconDatabase.cpp        2017-04-12 12:08:29 UTC (rev 215265)
</span><span class="lines">@@ -47,7 +47,7 @@
</span><span class="cx"> #define ASSERT_NOT_SYNC_THREAD() ASSERT(!m_syncThreadRunning || !IS_ICON_SYNC_THREAD())
</span><span class="cx"> 
</span><span class="cx"> // For methods that are meant to support the sync thread ONLY
</span><del>-#define IS_ICON_SYNC_THREAD() (m_syncThread == currentThread())
</del><ins>+#define IS_ICON_SYNC_THREAD() (m_syncThread-&gt;id() == currentThread())
</ins><span class="cx"> #define ASSERT_ICON_SYNC_THREAD() ASSERT(IS_ICON_SYNC_THREAD())
</span><span class="cx"> 
</span><span class="cx"> #if PLATFORM(GTK)
</span><span class="lines">@@ -141,7 +141,7 @@
</span><span class="cx">     // Lock here as well as first thing in the thread so the thread doesn't actually commence until the createThread() call 
</span><span class="cx">     // completes and m_syncThreadRunning is properly set
</span><span class="cx">     m_syncLock.lock();
</span><del>-    m_syncThread = createThread(IconDatabase::iconDatabaseSyncThreadStart, this, &quot;WebCore: IconDatabase&quot;);
</del><ins>+    m_syncThread = Thread::create(IconDatabase::iconDatabaseSyncThreadStart, this, &quot;WebCore: IconDatabase&quot;);
</ins><span class="cx">     m_syncThreadRunning = m_syncThread;
</span><span class="cx">     m_syncLock.unlock();
</span><span class="cx">     if (!m_syncThread)
</span><span class="lines">@@ -161,7 +161,7 @@
</span><span class="cx">         wakeSyncThread();
</span><span class="cx">         
</span><span class="cx">         // Wait for the sync thread to terminate
</span><del>-        waitForThreadCompletion(m_syncThread);
</del><ins>+        m_syncThread-&gt;waitForCompletion();
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     m_syncThreadRunning = false;    
</span></span></pre></div>
<a id="trunkSourceWebCoreloadericonIconDatabaseh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/loader/icon/IconDatabase.h (215264 => 215265)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/loader/icon/IconDatabase.h        2017-04-12 10:14:30 UTC (rev 215264)
+++ trunk/Source/WebCore/loader/icon/IconDatabase.h        2017-04-12 12:08:29 UTC (rev 215265)
</span><span class="lines">@@ -119,7 +119,7 @@
</span><span class="cx">     void syncTimerFired();
</span><span class="cx">     
</span><span class="cx">     Timer m_syncTimer;
</span><del>-    ThreadIdentifier m_syncThread;
</del><ins>+    RefPtr&lt;Thread&gt; m_syncThread;
</ins><span class="cx">     bool m_syncThreadRunning;
</span><span class="cx">     
</span><span class="cx">     HashSet&lt;RefPtr&lt;DocumentLoader&gt;&gt; m_loadersPendingDecision;
</span></span></pre></div>
<a id="trunkSourceWebCorepageResourceUsageThreadcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/page/ResourceUsageThread.cpp (215264 => 215265)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/page/ResourceUsageThread.cpp        2017-04-12 10:14:30 UTC (rev 215264)
+++ trunk/Source/WebCore/page/ResourceUsageThread.cpp        2017-04-12 12:08:29 UTC (rev 215265)
</span><span class="lines">@@ -96,11 +96,11 @@
</span><span class="cx"> 
</span><span class="cx"> void ResourceUsageThread::createThreadIfNeeded()
</span><span class="cx"> {
</span><del>-    if (m_threadIdentifier)
</del><ins>+    if (m_thread)
</ins><span class="cx">         return;
</span><span class="cx"> 
</span><span class="cx">     m_vm = &amp;commonVM();
</span><del>-    m_threadIdentifier = createThread(threadCallback, this, &quot;WebCore: ResourceUsage&quot;);
</del><ins>+    m_thread = Thread::create(threadCallback, this, &quot;WebCore: ResourceUsage&quot;);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void ResourceUsageThread::threadCallback(void* resourceUsageThread)
</span></span></pre></div>
<a id="trunkSourceWebCorepageResourceUsageThreadh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/page/ResourceUsageThread.h (215264 => 215265)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/page/ResourceUsageThread.h        2017-04-12 10:14:30 UTC (rev 215264)
+++ trunk/Source/WebCore/page/ResourceUsageThread.h        2017-04-12 12:08:29 UTC (rev 215265)
</span><span class="lines">@@ -62,7 +62,7 @@
</span><span class="cx">     void threadBody();
</span><span class="cx">     void platformThreadBody(JSC::VM*, ResourceUsageData&amp;);
</span><span class="cx"> 
</span><del>-    ThreadIdentifier m_threadIdentifier { 0 };
</del><ins>+    RefPtr&lt;Thread&gt; m_thread;
</ins><span class="cx">     Lock m_lock;
</span><span class="cx">     Condition m_condition;
</span><span class="cx">     HashMap&lt;void*, std::function&lt;void (const ResourceUsageData&amp;)&gt;&gt; m_observers;
</span></span></pre></div>
<a id="trunkSourceWebCorepagescrollingScrollingThreadcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/page/scrolling/ScrollingThread.cpp (215264 => 215265)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/page/scrolling/ScrollingThread.cpp        2017-04-12 10:14:30 UTC (rev 215264)
+++ trunk/Source/WebCore/page/scrolling/ScrollingThread.cpp        2017-04-12 12:08:29 UTC (rev 215265)
</span><span class="lines">@@ -35,14 +35,13 @@
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><span class="cx"> ScrollingThread::ScrollingThread()
</span><del>-    : m_threadIdentifier(0)
</del><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> bool ScrollingThread::isCurrentThread()
</span><span class="cx"> {
</span><del>-    auto threadIdentifier = ScrollingThread::singleton().m_threadIdentifier;
-    return threadIdentifier &amp;&amp; currentThread() == threadIdentifier;
</del><ins>+    RefPtr&lt;Thread&gt; thread = ScrollingThread::singleton().m_thread;
+    return thread &amp;&amp; thread-&gt;id() == currentThread();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void ScrollingThread::dispatch(Function&lt;void ()&gt;&amp;&amp; function)
</span><span class="lines">@@ -74,7 +73,7 @@
</span><span class="cx"> 
</span><span class="cx"> void ScrollingThread::createThreadIfNeeded()
</span><span class="cx"> {
</span><del>-    if (m_threadIdentifier)
</del><ins>+    if (m_thread)
</ins><span class="cx">         return;
</span><span class="cx"> 
</span><span class="cx">     // Wait for the thread to initialize the run loop.
</span><span class="lines">@@ -81,7 +80,7 @@
</span><span class="cx">     {
</span><span class="cx">         std::unique_lock&lt;Lock&gt; lock(m_initializeRunLoopMutex);
</span><span class="cx"> 
</span><del>-        m_threadIdentifier = createThread(threadCallback, this, &quot;WebCore: Scrolling&quot;);
</del><ins>+        m_thread = Thread::create(threadCallback, this, &quot;WebCore: Scrolling&quot;);
</ins><span class="cx">         
</span><span class="cx"> #if PLATFORM(COCOA)
</span><span class="cx">         m_initializeRunLoopConditionVariable.wait(lock, [this]{ return m_threadRunLoop; });
</span><span class="lines">@@ -91,7 +90,7 @@
</span><span class="cx"> 
</span><span class="cx"> void ScrollingThread::threadCallback(void* scrollingThread)
</span><span class="cx"> {
</span><del>-    WTF::setCurrentThreadIsUserInteractive();
</del><ins>+    WTF::Thread::setCurrentThreadIsUserInteractive();
</ins><span class="cx">     static_cast&lt;ScrollingThread*&gt;(scrollingThread)-&gt;threadBody();
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCorepagescrollingScrollingThreadh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/page/scrolling/ScrollingThread.h (215264 => 215265)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/page/scrolling/ScrollingThread.h        2017-04-12 10:14:30 UTC (rev 215264)
+++ trunk/Source/WebCore/page/scrolling/ScrollingThread.h        2017-04-12 12:08:29 UTC (rev 215265)
</span><span class="lines">@@ -73,7 +73,7 @@
</span><span class="cx">     void threadRunLoopSourceCallback();
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><del>-    ThreadIdentifier m_threadIdentifier;
</del><ins>+    RefPtr&lt;Thread&gt; m_thread;
</ins><span class="cx"> 
</span><span class="cx">     Condition m_initializeRunLoopConditionVariable;
</span><span class="cx">     Lock m_initializeRunLoopMutex;
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformaudioHRTFDatabaseLoadercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/audio/HRTFDatabaseLoader.cpp (215264 => 215265)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/audio/HRTFDatabaseLoader.cpp        2017-04-12 10:14:30 UTC (rev 215264)
+++ trunk/Source/WebCore/platform/audio/HRTFDatabaseLoader.cpp        2017-04-12 12:08:29 UTC (rev 215265)
</span><span class="lines">@@ -64,8 +64,7 @@
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> HRTFDatabaseLoader::HRTFDatabaseLoader(float sampleRate)
</span><del>-    : m_databaseLoaderThread(0)
-    , m_databaseSampleRate(sampleRate)
</del><ins>+    : m_databaseSampleRate(sampleRate)
</ins><span class="cx"> {
</span><span class="cx">     ASSERT(isMainThread());
</span><span class="cx"> }
</span><span class="lines">@@ -106,7 +105,7 @@
</span><span class="cx">     
</span><span class="cx">     if (!m_hrtfDatabase.get() &amp;&amp; !m_databaseLoaderThread) {
</span><span class="cx">         // Start the asynchronous database loading process.
</span><del>-        m_databaseLoaderThread = createThread(databaseLoaderEntry, this, &quot;HRTF database loader&quot;);
</del><ins>+        m_databaseLoaderThread = Thread::create(databaseLoaderEntry, this, &quot;HRTF database loader&quot;);
</ins><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -121,8 +120,8 @@
</span><span class="cx">     
</span><span class="cx">     // waitForThreadCompletion() should not be called twice for the same thread.
</span><span class="cx">     if (m_databaseLoaderThread)
</span><del>-        waitForThreadCompletion(m_databaseLoaderThread);
-    m_databaseLoaderThread = 0;
</del><ins>+        m_databaseLoaderThread-&gt;waitForCompletion();
+    m_databaseLoaderThread = nullptr;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> } // namespace WebCore
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformaudioHRTFDatabaseLoaderh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/audio/HRTFDatabaseLoader.h (215264 => 215265)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/audio/HRTFDatabaseLoader.h        2017-04-12 10:14:30 UTC (rev 215264)
+++ trunk/Source/WebCore/platform/audio/HRTFDatabaseLoader.h        2017-04-12 12:08:29 UTC (rev 215265)
</span><span class="lines">@@ -77,7 +77,7 @@
</span><span class="cx"> 
</span><span class="cx">     // Holding a m_threadLock is required when accessing m_databaseLoaderThread.
</span><span class="cx">     Lock m_threadLock;
</span><del>-    ThreadIdentifier m_databaseLoaderThread;
</del><ins>+    RefPtr&lt;Thread&gt; m_databaseLoaderThread;
</ins><span class="cx"> 
</span><span class="cx">     float m_databaseSampleRate;
</span><span class="cx"> };
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformaudioReverbConvolvercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/audio/ReverbConvolver.cpp (215264 => 215265)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/audio/ReverbConvolver.cpp        2017-04-12 10:14:30 UTC (rev 215264)
+++ trunk/Source/WebCore/platform/audio/ReverbConvolver.cpp        2017-04-12 12:08:29 UTC (rev 215265)
</span><span class="lines">@@ -130,7 +130,7 @@
</span><span class="cx">     // Start up background thread
</span><span class="cx">     // FIXME: would be better to up the thread priority here.  It doesn't need to be real-time, but higher than the default...
</span><span class="cx">     if (this-&gt;useBackgroundThreads() &amp;&amp; m_backgroundStages.size() &gt; 0)
</span><del>-        m_backgroundThread = createThread(WebCore::backgroundThreadEntry, this, &quot;convolution background thread&quot;);
</del><ins>+        m_backgroundThread = Thread::create(WebCore::backgroundThreadEntry, this, &quot;convolution background thread&quot;);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> ReverbConvolver::~ReverbConvolver()
</span><span class="lines">@@ -146,7 +146,7 @@
</span><span class="cx">             m_backgroundThreadConditionVariable.notifyOne();
</span><span class="cx">         }
</span><span class="cx"> 
</span><del>-        waitForThreadCompletion(m_backgroundThread);
</del><ins>+        m_backgroundThread-&gt;waitForCompletion();
</ins><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformaudioReverbConvolverh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/audio/ReverbConvolver.h (215264 => 215265)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/audio/ReverbConvolver.h        2017-04-12 10:14:30 UTC (rev 215264)
+++ trunk/Source/WebCore/platform/audio/ReverbConvolver.h        2017-04-12 12:08:29 UTC (rev 215265)
</span><span class="lines">@@ -86,7 +86,7 @@
</span><span class="cx"> 
</span><span class="cx">     // Background thread and synchronization
</span><span class="cx">     bool m_useBackgroundThreads;
</span><del>-    ThreadIdentifier m_backgroundThread;
</del><ins>+    RefPtr&lt;Thread&gt; m_backgroundThread;
</ins><span class="cx">     bool m_wantsToExit;
</span><span class="cx">     bool m_moreInputBuffered;
</span><span class="cx">     mutable Lock m_backgroundThreadMutex;
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformaudiogstreamerAudioFileReaderGStreamercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/audio/gstreamer/AudioFileReaderGStreamer.cpp (215264 => 215265)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/audio/gstreamer/AudioFileReaderGStreamer.cpp        2017-04-12 10:14:30 UTC (rev 215264)
+++ trunk/Source/WebCore/platform/audio/gstreamer/AudioFileReaderGStreamer.cpp        2017-04-12 12:08:29 UTC (rev 215265)
</span><span class="lines">@@ -370,10 +370,10 @@
</span><span class="cx"> PassRefPtr&lt;AudioBus&gt; createBusFromAudioFile(const char* filePath, bool mixToMono, float sampleRate)
</span><span class="cx"> {
</span><span class="cx">     RefPtr&lt;AudioBus&gt; returnValue;
</span><del>-    auto threadID = createThread(&quot;AudioFileReader&quot;, [&amp;returnValue, filePath, mixToMono, sampleRate] {
</del><ins>+    auto thread = Thread::create(&quot;AudioFileReader&quot;, [&amp;returnValue, filePath, mixToMono, sampleRate] {
</ins><span class="cx">         returnValue = AudioFileReader(filePath).createBus(sampleRate, mixToMono);
</span><span class="cx">     });
</span><del>-    waitForThreadCompletion(threadID);
</del><ins>+    thread-&gt;waitForCompletion();
</ins><span class="cx">     return returnValue;
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -380,10 +380,10 @@
</span><span class="cx"> PassRefPtr&lt;AudioBus&gt; createBusFromInMemoryAudioFile(const void* data, size_t dataSize, bool mixToMono, float sampleRate)
</span><span class="cx"> {
</span><span class="cx">     RefPtr&lt;AudioBus&gt; returnValue;
</span><del>-    auto threadID = createThread(&quot;AudioFileReader&quot;, [&amp;returnValue, data, dataSize, mixToMono, sampleRate] {
</del><ins>+    auto thread = Thread::create(&quot;AudioFileReader&quot;, [&amp;returnValue, data, dataSize, mixToMono, sampleRate] {
</ins><span class="cx">         returnValue = AudioFileReader(data, dataSize).createBus(sampleRate, mixToMono);
</span><span class="cx">     });
</span><del>-    waitForThreadCompletion(threadID);
</del><ins>+    thread-&gt;waitForCompletion();
</ins><span class="cx">     return returnValue;
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsgstreamerWebKitWebSourceGStreamercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/gstreamer/WebKitWebSourceGStreamer.cpp (215264 => 215265)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/gstreamer/WebKitWebSourceGStreamer.cpp        2017-04-12 10:14:30 UTC (rev 215264)
+++ trunk/Source/WebCore/platform/graphics/gstreamer/WebKitWebSourceGStreamer.cpp        2017-04-12 12:08:29 UTC (rev 215265)
</span><span class="lines">@@ -108,7 +108,7 @@
</span><span class="cx">         void wasBlocked(ResourceHandle*) override;
</span><span class="cx">         void cannotShowURL(ResourceHandle*) override;
</span><span class="cx"> 
</span><del>-        ThreadIdentifier m_thread { 0 };
</del><ins>+        RefPtr&lt;Thread&gt; m_thread;
</ins><span class="cx">         Lock m_initializeRunLoopConditionMutex;
</span><span class="cx">         Condition m_initializeRunLoopCondition;
</span><span class="cx">         RunLoop* m_runLoop { nullptr };
</span><span class="lines">@@ -1077,7 +1077,7 @@
</span><span class="cx">     : StreamingClient(src)
</span><span class="cx"> {
</span><span class="cx">     LockHolder locker(m_initializeRunLoopConditionMutex);
</span><del>-    m_thread = createThread(&quot;ResourceHandleStreamingClient&quot;, [this, request = WTFMove(request)] {
</del><ins>+    m_thread = Thread::create(&quot;ResourceHandleStreamingClient&quot;, [this, request = WTFMove(request)] {
</ins><span class="cx">         {
</span><span class="cx">             LockHolder locker(m_initializeRunLoopConditionMutex);
</span><span class="cx">             m_runLoop = &amp;RunLoop::current();
</span><span class="lines">@@ -1113,8 +1113,8 @@
</span><span class="cx"> ResourceHandleStreamingClient::~ResourceHandleStreamingClient()
</span><span class="cx"> {
</span><span class="cx">     if (m_thread) {
</span><del>-        detachThread(m_thread);
-        m_thread = 0;
</del><ins>+        m_thread-&gt;detach();
+        m_thread = nullptr;
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     if (m_runLoop == &amp;RunLoop::current())
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformnetworkcfLoaderRunLoopCFcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/network/cf/LoaderRunLoopCF.cpp (215264 => 215265)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/network/cf/LoaderRunLoopCF.cpp        2017-04-12 10:14:30 UTC (rev 215264)
+++ trunk/Source/WebCore/platform/network/cf/LoaderRunLoopCF.cpp        2017-04-12 12:08:29 UTC (rev 215265)
</span><span class="lines">@@ -77,7 +77,7 @@
</span><span class="cx">     std::unique_lock&lt;StaticLock&gt; lock(loaderRunLoopMutex);
</span><span class="cx"> 
</span><span class="cx">     if (!loaderRunLoopObject) {
</span><del>-        createThread(runLoaderThread, 0, &quot;WebCore: CFNetwork Loader&quot;);
</del><ins>+        Thread::create(runLoaderThread, 0, &quot;WebCore: CFNetwork Loader&quot;);
</ins><span class="cx"> 
</span><span class="cx">         loaderRunLoopConditionVariable.wait(lock, [] { return loaderRunLoopObject; });
</span><span class="cx">     }
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformnetworkcurlCurlDownloadcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/network/curl/CurlDownload.cpp (215264 => 215265)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/network/curl/CurlDownload.cpp        2017-04-12 10:14:30 UTC (rev 215264)
+++ trunk/Source/WebCore/platform/network/curl/CurlDownload.cpp        2017-04-12 12:08:29 UTC (rev 215265)
</span><span class="lines">@@ -94,10 +94,10 @@
</span><span class="cx"> void CurlDownloadManager::startThreadIfNeeded()
</span><span class="cx"> {
</span><span class="cx">     if (!runThread()) {
</span><del>-        if (m_threadId)
-            waitForThreadCompletion(m_threadId);
</del><ins>+        if (m_thread)
+            m_thread-&gt;waitForCompletion();
</ins><span class="cx">         setRunThread(true);
</span><del>-        m_threadId = createThread(downloadThread, this, &quot;downloadThread&quot;);
</del><ins>+        m_thread = Thread::create(downloadThread, this, &quot;downloadThread&quot;);
</ins><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -105,9 +105,9 @@
</span><span class="cx"> {
</span><span class="cx">     setRunThread(false);
</span><span class="cx"> 
</span><del>-    if (m_threadId) {
-        waitForThreadCompletion(m_threadId);
-        m_threadId = 0;
</del><ins>+    if (m_thread) {
+        m_thread-&gt;waitForCompletion();
+        m_thread = nullptr;
</ins><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformnetworkcurlCurlDownloadh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/network/curl/CurlDownload.h (215264 => 215265)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/network/curl/CurlDownload.h        2017-04-12 10:14:30 UTC (rev 215264)
+++ trunk/Source/WebCore/platform/network/curl/CurlDownload.h        2017-04-12 12:08:29 UTC (rev 215265)
</span><span class="lines">@@ -69,7 +69,7 @@
</span><span class="cx"> 
</span><span class="cx">     static void downloadThread(void* data);
</span><span class="cx"> 
</span><del>-    ThreadIdentifier m_threadId;
</del><ins>+    RefPtr&lt;Thread&gt; m_thread;
</ins><span class="cx">     CURLM* m_curlMultiHandle;
</span><span class="cx">     Vector&lt;CURL*&gt; m_pendingHandleList;
</span><span class="cx">     Vector&lt;CURL*&gt; m_activeHandleList;
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformnetworkcurlSocketStreamHandleImplh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/network/curl/SocketStreamHandleImpl.h (215264 => 215265)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/network/curl/SocketStreamHandleImpl.h        2017-04-12 10:14:30 UTC (rev 215264)
+++ trunk/Source/WebCore/platform/network/curl/SocketStreamHandleImpl.h        2017-04-12 12:08:29 UTC (rev 215265)
</span><span class="lines">@@ -92,7 +92,7 @@
</span><span class="cx">         size_t size { 0 };
</span><span class="cx">     };
</span><span class="cx"> 
</span><del>-    ThreadIdentifier m_workerThread { 0 };
</del><ins>+    RefPtr&lt;Thread&gt; m_workerThread;
</ins><span class="cx">     std::atomic&lt;bool&gt; m_stopThread { false };
</span><span class="cx">     Lock m_mutexSend;
</span><span class="cx">     Lock m_mutexReceive;
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformnetworkcurlSocketStreamHandleImplCurlcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/network/curl/SocketStreamHandleImplCurl.cpp (215264 => 215265)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/network/curl/SocketStreamHandleImplCurl.cpp        2017-04-12 10:14:30 UTC (rev 215264)
+++ trunk/Source/WebCore/platform/network/curl/SocketStreamHandleImplCurl.cpp        2017-04-12 12:08:29 UTC (rev 215265)
</span><span class="lines">@@ -199,7 +199,7 @@
</span><span class="cx"> 
</span><span class="cx">     ref(); // stopThread() will call deref().
</span><span class="cx"> 
</span><del>-    m_workerThread = createThread(&quot;WebSocket thread&quot;, [this] {
</del><ins>+    m_workerThread = Thread::create(&quot;WebSocket thread&quot;, [this] {
</ins><span class="cx"> 
</span><span class="cx">         ASSERT(!isMainThread());
</span><span class="cx"> 
</span><span class="lines">@@ -249,8 +249,8 @@
</span><span class="cx">         return;
</span><span class="cx"> 
</span><span class="cx">     m_stopThread = true;
</span><del>-    waitForThreadCompletion(m_workerThread);
-    m_workerThread = 0;
</del><ins>+    m_workerThread-&gt;waitForCompletion();
+    m_workerThread = nullptr;
</ins><span class="cx">     deref();
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreworkersWorkerThreadcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/workers/WorkerThread.cpp (215264 => 215265)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/workers/WorkerThread.cpp        2017-04-12 10:14:30 UTC (rev 215264)
+++ trunk/Source/WebCore/workers/WorkerThread.cpp        2017-04-12 12:08:29 UTC (rev 215265)
</span><span class="lines">@@ -99,8 +99,7 @@
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> WorkerThread::WorkerThread(const URL&amp; scriptURL, const String&amp; identifier, const String&amp; userAgent, const String&amp; sourceCode, WorkerLoaderProxy&amp; workerLoaderProxy, WorkerReportingProxy&amp; workerReportingProxy, WorkerThreadStartMode startMode, const ContentSecurityPolicyResponseHeaders&amp; contentSecurityPolicyResponseHeaders, bool shouldBypassMainWorldContentSecurityPolicy, const SecurityOrigin&amp; topOrigin, MonotonicTime timeOrigin, IDBClient::IDBConnectionProxy* connectionProxy, SocketProvider* socketProvider, JSC::RuntimeFlags runtimeFlags)
</span><del>-    : m_threadID(0)
-    , m_workerLoaderProxy(workerLoaderProxy)
</del><ins>+    : m_workerLoaderProxy(workerLoaderProxy)
</ins><span class="cx">     , m_workerReportingProxy(workerReportingProxy)
</span><span class="cx">     , m_runtimeFlags(runtimeFlags)
</span><span class="cx">     , m_startupData(std::make_unique&lt;WorkerThreadStartupData&gt;(scriptURL, identifier, userAgent, sourceCode, startMode, contentSecurityPolicyResponseHeaders, shouldBypassMainWorldContentSecurityPolicy, topOrigin, timeOrigin))
</span><span class="lines">@@ -133,15 +132,15 @@
</span><span class="cx"> 
</span><span class="cx"> bool WorkerThread::start()
</span><span class="cx"> {
</span><del>-    // Mutex protection is necessary to ensure that m_threadID is initialized when the thread starts.
</del><ins>+    // Mutex protection is necessary to ensure that m_thread is initialized when the thread starts.
</ins><span class="cx">     LockHolder lock(m_threadCreationMutex);
</span><span class="cx"> 
</span><del>-    if (m_threadID)
</del><ins>+    if (m_thread)
</ins><span class="cx">         return true;
</span><span class="cx"> 
</span><del>-    m_threadID = createThread(WorkerThread::workerThreadStart, this, &quot;WebCore: Worker&quot;);
</del><ins>+    m_thread = Thread::create(WorkerThread::workerThreadStart, this, &quot;WebCore: Worker&quot;);
</ins><span class="cx"> 
</span><del>-    return m_threadID;
</del><ins>+    return m_thread;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void WorkerThread::workerThreadStart(void* thread)
</span><span class="lines">@@ -193,7 +192,7 @@
</span><span class="cx">     g_main_context_pop_thread_default(mainContext.get());
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><del>-    ThreadIdentifier threadID = m_threadID;
</del><ins>+    RefPtr&lt;Thread&gt; protector = m_thread;
</ins><span class="cx"> 
</span><span class="cx">     ASSERT(m_workerGlobalScope-&gt;hasOneRef());
</span><span class="cx"> 
</span><span class="lines">@@ -205,7 +204,7 @@
</span><span class="cx">     threadGlobalData().destroy();
</span><span class="cx"> 
</span><span class="cx">     // The thread object may be already destroyed from notification now, don't try to access &quot;this&quot;.
</span><del>-    detachThread(threadID);
</del><ins>+    protector-&gt;detach();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void WorkerThread::startRunningDebuggerTasks()
</span></span></pre></div>
<a id="trunkSourceWebCoreworkersWorkerThreadh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/workers/WorkerThread.h (215264 => 215265)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/workers/WorkerThread.h        2017-04-12 10:14:30 UTC (rev 215264)
+++ trunk/Source/WebCore/workers/WorkerThread.h        2017-04-12 12:08:29 UTC (rev 215265)
</span><span class="lines">@@ -60,7 +60,7 @@
</span><span class="cx">     bool start();
</span><span class="cx">     void stop();
</span><span class="cx"> 
</span><del>-    ThreadIdentifier threadID() const { return m_threadID; }
</del><ins>+    ThreadIdentifier threadID() const { return m_thread ? m_thread-&gt;id() : 0; }
</ins><span class="cx">     WorkerRunLoop&amp; runLoop() { return m_runLoop; }
</span><span class="cx">     WorkerLoaderProxy&amp; workerLoaderProxy() const { return m_workerLoaderProxy; }
</span><span class="cx">     WorkerReportingProxy&amp; workerReportingProxy() const { return m_workerReportingProxy; }
</span><span class="lines">@@ -98,7 +98,7 @@
</span><span class="cx">     static void workerThreadStart(void*);
</span><span class="cx">     void workerThread();
</span><span class="cx"> 
</span><del>-    ThreadIdentifier m_threadID;
</del><ins>+    RefPtr&lt;Thread&gt; m_thread;
</ins><span class="cx">     WorkerRunLoop m_runLoop;
</span><span class="cx">     WorkerLoaderProxy&amp; m_workerLoaderProxy;
</span><span class="cx">     WorkerReportingProxy&amp; m_workerReportingProxy;
</span></span></pre></div>
<a id="trunkSourceWebKitChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/ChangeLog (215264 => 215265)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/ChangeLog        2017-04-12 10:14:30 UTC (rev 215264)
+++ trunk/Source/WebKit/ChangeLog        2017-04-12 12:08:29 UTC (rev 215265)
</span><span class="lines">@@ -1,3 +1,20 @@
</span><ins>+2017-04-12  Yusuke Suzuki  &lt;utatane.tea@gmail.com&gt;
+
+        [WTF] Introduce Thread class and use RefPtr&lt;Thread&gt; and align Windows Threading implementation semantics to Pthread one
+        https://bugs.webkit.org/show_bug.cgi?id=170502
+
+        Reviewed by Mark Lam.
+
+        Mechanical change. Use Thread:: APIs.
+
+        * Storage/StorageThread.cpp:
+        (WebCore::StorageThread::StorageThread):
+        (WebCore::StorageThread::~StorageThread):
+        (WebCore::StorageThread::start):
+        (WebCore::StorageThread::dispatch):
+        (WebCore::StorageThread::terminate):
+        * Storage/StorageThread.h:
+
</ins><span class="cx"> 2017-04-10  Chris Dumez  &lt;cdumez@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Drop Timer::startOneShot() overload taking a double
</span></span></pre></div>
<a id="trunkSourceWebKitStorageStorageThreadcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/Storage/StorageThread.cpp (215264 => 215265)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/Storage/StorageThread.cpp        2017-04-12 10:14:30 UTC (rev 215264)
+++ trunk/Source/WebKit/Storage/StorageThread.cpp        2017-04-12 12:08:29 UTC (rev 215265)
</span><span class="lines">@@ -40,7 +40,6 @@
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> StorageThread::StorageThread()
</span><del>-    : m_threadID(0)
</del><span class="cx"> {
</span><span class="cx">     ASSERT(isMainThread());
</span><span class="cx"> }
</span><span class="lines">@@ -48,16 +47,16 @@
</span><span class="cx"> StorageThread::~StorageThread()
</span><span class="cx"> {
</span><span class="cx">     ASSERT(isMainThread());
</span><del>-    ASSERT(!m_threadID);
</del><ins>+    ASSERT(!m_thread);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> bool StorageThread::start()
</span><span class="cx"> {
</span><span class="cx">     ASSERT(isMainThread());
</span><del>-    if (!m_threadID)
-        m_threadID = createThread(StorageThread::threadEntryPointCallback, this, &quot;WebCore: LocalStorage&quot;);
</del><ins>+    if (!m_thread)
+        m_thread = Thread::create(StorageThread::threadEntryPointCallback, this, &quot;WebCore: LocalStorage&quot;);
</ins><span class="cx">     activeStorageThreads().add(this);
</span><del>-    return m_threadID;
</del><ins>+    return m_thread;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void StorageThread::threadEntryPointCallback(void* thread)
</span><span class="lines">@@ -78,7 +77,7 @@
</span><span class="cx"> void StorageThread::dispatch(Function&lt;void ()&gt;&amp;&amp; function)
</span><span class="cx"> {
</span><span class="cx">     ASSERT(isMainThread());
</span><del>-    ASSERT(!m_queue.killed() &amp;&amp; m_threadID);
</del><ins>+    ASSERT(!m_queue.killed() &amp;&amp; m_thread);
</ins><span class="cx">     m_queue.append(std::make_unique&lt;Function&lt;void ()&gt;&gt;(WTFMove(function)));
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -85,18 +84,18 @@
</span><span class="cx"> void StorageThread::terminate()
</span><span class="cx"> {
</span><span class="cx">     ASSERT(isMainThread());
</span><del>-    ASSERT(!m_queue.killed() &amp;&amp; m_threadID);
</del><ins>+    ASSERT(!m_queue.killed() &amp;&amp; m_thread);
</ins><span class="cx">     activeStorageThreads().remove(this);
</span><span class="cx">     // Even in weird, exceptional cases, don't wait on a nonexistent thread to terminate.
</span><del>-    if (!m_threadID)
</del><ins>+    if (!m_thread)
</ins><span class="cx">         return;
</span><span class="cx"> 
</span><span class="cx">     m_queue.append(std::make_unique&lt;Function&lt;void ()&gt;&gt;([this] {
</span><span class="cx">         performTerminate();
</span><span class="cx">     }));
</span><del>-    waitForThreadCompletion(m_threadID);
</del><ins>+    m_thread-&gt;waitForCompletion();
</ins><span class="cx">     ASSERT(m_queue.killed());
</span><del>-    m_threadID = 0;
</del><ins>+    m_thread = nullptr;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void StorageThread::performTerminate()
</span></span></pre></div>
<a id="trunkSourceWebKitStorageStorageThreadh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/Storage/StorageThread.h (215264 => 215265)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/Storage/StorageThread.h        2017-04-12 10:14:30 UTC (rev 215264)
+++ trunk/Source/WebKit/Storage/StorageThread.h        2017-04-12 12:08:29 UTC (rev 215265)
</span><span class="lines">@@ -56,7 +56,7 @@
</span><span class="cx">     // Background thread part of the terminate procedure.
</span><span class="cx">     void performTerminate();
</span><span class="cx"> 
</span><del>-    ThreadIdentifier m_threadID;
</del><ins>+    RefPtr&lt;Thread&gt; m_thread;
</ins><span class="cx">     MessageQueue&lt;Function&lt;void ()&gt;&gt; m_queue;
</span><span class="cx"> };
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebKit2ChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/ChangeLog (215264 => 215265)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/ChangeLog        2017-04-12 10:14:30 UTC (rev 215264)
+++ trunk/Source/WebKit2/ChangeLog        2017-04-12 12:08:29 UTC (rev 215265)
</span><span class="lines">@@ -1,3 +1,25 @@
</span><ins>+2017-04-12  Yusuke Suzuki  &lt;utatane.tea@gmail.com&gt;
+
+        [WTF] Introduce Thread class and use RefPtr&lt;Thread&gt; and align Windows Threading implementation semantics to Pthread one
+        https://bugs.webkit.org/show_bug.cgi?id=170502
+
+        Reviewed by Mark Lam.
+
+        Mechanical change. Use Thread:: APIs.
+
+        * NetworkProcess/NetworkProcess.cpp:
+        (WebKit::NetworkProcess::initializeNetworkProcess):
+        * NetworkProcess/cache/NetworkCacheIOChannelSoup.cpp:
+        (WebKit::NetworkCache::IOChannel::readSyncInThread):
+        * Platform/IPC/Connection.cpp:
+        (IPC::Connection::processIncomingMessage):
+        * Shared/EntryPointUtilities/mac/XPCService/XPCServiceEntryPoint.h:
+        (WebKit::XPCServiceInitializer):
+        * UIProcess/linux/MemoryPressureMonitor.cpp:
+        (WebKit::MemoryPressureMonitor::MemoryPressureMonitor):
+        * WebProcess/WebProcess.cpp:
+        (WebKit::WebProcess::initializeWebProcess):
+
</ins><span class="cx"> 2017-04-10  Antti Koivisto  &lt;antti@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Cache small media resources in disk cache
</span></span></pre></div>
<a id="trunkSourceWebKit2NetworkProcessNetworkProcesscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/NetworkProcess/NetworkProcess.cpp (215264 => 215265)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/NetworkProcess/NetworkProcess.cpp        2017-04-12 10:14:30 UTC (rev 215264)
+++ trunk/Source/WebKit2/NetworkProcess/NetworkProcess.cpp        2017-04-12 12:08:29 UTC (rev 215265)
</span><span class="lines">@@ -204,7 +204,7 @@
</span><span class="cx"> {
</span><span class="cx">     platformInitializeNetworkProcess(parameters);
</span><span class="cx"> 
</span><del>-    WTF::setCurrentThreadIsUserInitiated();
</del><ins>+    WTF::Thread::setCurrentThreadIsUserInitiated();
</ins><span class="cx"> 
</span><span class="cx">     m_suppressMemoryPressureHandler = parameters.shouldSuppressMemoryPressureHandler;
</span><span class="cx">     m_loadThrottleLatency = parameters.loadThrottleLatency;
</span></span></pre></div>
<a id="trunkSourceWebKit2NetworkProcesscacheNetworkCacheIOChannelSoupcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheIOChannelSoup.cpp (215264 => 215265)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheIOChannelSoup.cpp        2017-04-12 10:14:30 UTC (rev 215264)
+++ trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheIOChannelSoup.cpp        2017-04-12 12:08:29 UTC (rev 215265)
</span><span class="lines">@@ -183,7 +183,7 @@
</span><span class="cx">     ASSERT(!isMainThread());
</span><span class="cx"> 
</span><span class="cx">     RefPtr&lt;IOChannel&gt; channel(this);
</span><del>-    detachThread(createThread(&quot;IOChannel::readSync&quot;, [channel, size, queue, completionHandler] {
</del><ins>+    Thread::create(&quot;IOChannel::readSync&quot;, [channel, size, queue, completionHandler] {
</ins><span class="cx">         size_t bufferSize = std::min(size, gDefaultReadBufferSize);
</span><span class="cx">         uint8_t* bufferData = static_cast&lt;uint8_t*&gt;(fastMalloc(bufferSize));
</span><span class="cx">         GRefPtr&lt;SoupBuffer&gt; readBuffer = adoptGRef(soup_buffer_new_with_owner(bufferData, bufferSize, bufferData, fastFree));
</span><span class="lines">@@ -217,7 +217,7 @@
</span><span class="cx">             Data data = { WTFMove(buffer) };
</span><span class="cx">             completionHandler(data, 0);
</span><span class="cx">         }, queue);
</span><del>-    }));
</del><ins>+    })-&gt;detach();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> struct WriteAsyncData {
</span></span></pre></div>
<a id="trunkSourceWebKit2PlatformIPCConnectioncpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/Platform/IPC/Connection.cpp (215264 => 215265)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/Platform/IPC/Connection.cpp        2017-04-12 10:14:30 UTC (rev 215264)
+++ trunk/Source/WebKit2/Platform/IPC/Connection.cpp        2017-04-12 12:08:29 UTC (rev 215265)
</span><span class="lines">@@ -675,7 +675,7 @@
</span><span class="cx"> 
</span><span class="cx"> #if HAVE(QOS_CLASSES)
</span><span class="cx">     if (message-&gt;isSyncMessage() &amp;&amp; m_shouldBoostMainThreadOnSyncMessage) {
</span><del>-        pthread_override_t override = pthread_override_qos_class_start_np(m_mainThread, adjustedQOSClass(QOS_CLASS_USER_INTERACTIVE), 0);
</del><ins>+        pthread_override_t override = pthread_override_qos_class_start_np(m_mainThread, Thread::adjustedQOSClass(QOS_CLASS_USER_INTERACTIVE), 0);
</ins><span class="cx">         message-&gt;setQOSClassOverride(override);
</span><span class="cx">     }
</span><span class="cx"> #endif
</span></span></pre></div>
<a id="trunkSourceWebKit2SharedEntryPointUtilitiesmacXPCServiceXPCServiceEntryPointh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/Shared/EntryPointUtilities/mac/XPCService/XPCServiceEntryPoint.h (215264 => 215265)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/Shared/EntryPointUtilities/mac/XPCService/XPCServiceEntryPoint.h        2017-04-12 10:14:30 UTC (rev 215264)
+++ trunk/Source/WebKit2/Shared/EntryPointUtilities/mac/XPCService/XPCServiceEntryPoint.h        2017-04-12 12:08:29 UTC (rev 215265)
</span><span class="lines">@@ -103,7 +103,7 @@
</span><span class="cx"> 
</span><span class="cx"> #if HAVE(QOS_CLASSES)
</span><span class="cx">     if (parameters.extraInitializationData.contains(ASCIILiteral(&quot;always-runs-at-background-priority&quot;)))
</span><del>-        setGlobalMaxQOSClass(QOS_CLASS_UTILITY);
</del><ins>+        Thread::setGlobalMaxQOSClass(QOS_CLASS_UTILITY);
</ins><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx">     XPCServiceType::singleton().initialize(parameters);
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcesslinuxMemoryPressureMonitorcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/linux/MemoryPressureMonitor.cpp (215264 => 215265)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/linux/MemoryPressureMonitor.cpp        2017-04-12 10:14:30 UTC (rev 215264)
+++ trunk/Source/WebKit2/UIProcess/linux/MemoryPressureMonitor.cpp        2017-04-12 12:08:29 UTC (rev 215265)
</span><span class="lines">@@ -248,7 +248,7 @@
</span><span class="cx">     if (m_eventFD == -1)
</span><span class="cx">         return;
</span><span class="cx"> 
</span><del>-    ThreadIdentifier threadIdentifier = createThread(&quot;MemoryPressureMonitor&quot;, [this] {
</del><ins>+    RefPtr&lt;Thread&gt; thread = Thread::create(&quot;MemoryPressureMonitor&quot;, [this] {
</ins><span class="cx">         double pollInterval = s_maxPollingIntervalInSeconds;
</span><span class="cx">         while (true) {
</span><span class="cx">             sleep(pollInterval);
</span><span class="lines">@@ -271,7 +271,7 @@
</span><span class="cx">         }
</span><span class="cx">         close(m_eventFD);
</span><span class="cx">     });
</span><del>-    detachThread(threadIdentifier);
</del><ins>+    thread-&gt;detach();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> IPC::Attachment MemoryPressureMonitor::createHandle() const
</span></span></pre></div>
<a id="trunkSourceWebKit2WebProcessWebProcesscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/WebProcess/WebProcess.cpp (215264 => 215265)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/WebProcess/WebProcess.cpp        2017-04-12 10:14:30 UTC (rev 215264)
+++ trunk/Source/WebKit2/WebProcess/WebProcess.cpp        2017-04-12 12:08:29 UTC (rev 215265)
</span><span class="lines">@@ -258,7 +258,7 @@
</span><span class="cx">     platformInitializeWebProcess(WTFMove(parameters));
</span><span class="cx"> 
</span><span class="cx">     // Match the QoS of the UIProcess and the scrolling thread but use a slightly lower priority.
</span><del>-    WTF::setCurrentThreadIsUserInteractive(-1);
</del><ins>+    WTF::Thread::setCurrentThreadIsUserInteractive(-1);
</ins><span class="cx"> 
</span><span class="cx">     m_suppressMemoryPressureHandler = parameters.shouldSuppressMemoryPressureHandler;
</span><span class="cx">     if (!m_suppressMemoryPressureHandler) {
</span></span></pre></div>
<a id="trunkToolsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Tools/ChangeLog (215264 => 215265)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/ChangeLog        2017-04-12 10:14:30 UTC (rev 215264)
+++ trunk/Tools/ChangeLog        2017-04-12 12:08:29 UTC (rev 215265)
</span><span class="lines">@@ -1,3 +1,23 @@
</span><ins>+2017-04-12  Yusuke Suzuki  &lt;utatane.tea@gmail.com&gt;
+
+        [WTF] Introduce Thread class and use RefPtr&lt;Thread&gt; and align Windows Threading implementation semantics to Pthread one
+        https://bugs.webkit.org/show_bug.cgi?id=170502
+
+        Reviewed by Mark Lam.
+
+        Mechanical change. Use Thread:: APIs.
+
+        * DumpRenderTree/JavaScriptThreading.cpp:
+        (runJavaScriptThread):
+        (startJavaScriptThreads):
+        (stopJavaScriptThreads):
+        * DumpRenderTree/mac/DumpRenderTree.mm:
+        (testThreadIdentifierMap):
+        * TestWebKitAPI/Tests/WTF/Condition.cpp:
+        * TestWebKitAPI/Tests/WTF/Lock.cpp:
+        (TestWebKitAPI::runLockTest):
+        * TestWebKitAPI/Tests/WTF/ParkingLot.cpp:
+
</ins><span class="cx"> 2017-04-12  Alex Christensen  &lt;achristensen@webkit.org&gt;
</span><span class="cx"> 
</span><span class="cx">         Modernize vector adoption
</span></span></pre></div>
<a id="trunkToolsDumpRenderTreeJavaScriptThreadingcpp"></a>
<div class="modfile"><h4>Modified: trunk/Tools/DumpRenderTree/JavaScriptThreading.cpp (215264 => 215265)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/DumpRenderTree/JavaScriptThreading.cpp        2017-04-12 10:14:30 UTC (rev 215264)
+++ trunk/Tools/DumpRenderTree/JavaScriptThreading.cpp        2017-04-12 12:08:29 UTC (rev 215265)
</span><span class="lines">@@ -51,7 +51,7 @@
</span><span class="cx">     return staticMutex;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-typedef HashSet&lt;ThreadIdentifier&gt; ThreadSet;
</del><ins>+typedef HashSet&lt;RefPtr&lt;Thread&gt;&gt; ThreadSet;
</ins><span class="cx"> static ThreadSet&amp; javaScriptThreads()
</span><span class="cx"> {
</span><span class="cx">     DEPRECATED_DEFINE_STATIC_LOCAL(ThreadSet, staticJavaScriptThreads, ());
</span><span class="lines">@@ -108,10 +108,10 @@
</span><span class="cx">             continue;
</span><span class="cx"> 
</span><span class="cx">         LockHolder locker(javaScriptThreadsMutex());
</span><del>-        ThreadIdentifier thread = currentThread();
-        detachThread(thread);
-        javaScriptThreads().remove(thread);
-        javaScriptThreads().add(createThread(&amp;runJavaScriptThread, 0, 0));
</del><ins>+        Thread&amp; thread = Thread::current();
+        thread.detach();
+        javaScriptThreads().remove(&amp;thread);
+        javaScriptThreads().add(Thread::create(&amp;runJavaScriptThread, 0, 0));
</ins><span class="cx">         break;
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="lines">@@ -128,7 +128,7 @@
</span><span class="cx">     LockHolder locker(javaScriptThreadsMutex());
</span><span class="cx"> 
</span><span class="cx">     for (size_t i = 0; i &lt; javaScriptThreadsCount; ++i)
</span><del>-        javaScriptThreads().add(createThread(&amp;runJavaScriptThread, 0, 0));
</del><ins>+        javaScriptThreads().add(Thread::create(&amp;runJavaScriptThread, 0, 0));
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void stopJavaScriptThreads()
</span><span class="lines">@@ -138,7 +138,7 @@
</span><span class="cx">         javaScriptThreadsShouldTerminate = true;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    Vector&lt;ThreadIdentifier, javaScriptThreadsCount&gt; threads;
</del><ins>+    Vector&lt;RefPtr&lt;Thread&gt;, javaScriptThreadsCount&gt; threads;
</ins><span class="cx">     {
</span><span class="cx">         LockHolder locker(javaScriptThreadsMutex());
</span><span class="cx">         copyToVector(javaScriptThreads(), threads);
</span><span class="lines">@@ -146,7 +146,7 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     for (size_t i = 0; i &lt; javaScriptThreadsCount; ++i)
</span><del>-        waitForThreadCompletion(threads[i]);
</del><ins>+        threads[i]-&gt;waitForCompletion();
</ins><span class="cx"> 
</span><span class="cx">     {
</span><span class="cx">         LockHolder locker(javaScriptThreadsMutex());
</span></span></pre></div>
<a id="trunkToolsDumpRenderTreemacDumpRenderTreemm"></a>
<div class="modfile"><h4>Modified: trunk/Tools/DumpRenderTree/mac/DumpRenderTree.mm (215264 => 215265)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/DumpRenderTree/mac/DumpRenderTree.mm        2017-04-12 10:14:30 UTC (rev 215264)
+++ trunk/Tools/DumpRenderTree/mac/DumpRenderTree.mm        2017-04-12 12:08:29 UTC (rev 215265)
</span><span class="lines">@@ -1072,8 +1072,8 @@
</span><span class="cx">     pthread_join(pthread, 0);
</span><span class="cx"> 
</span><span class="cx">     // Now create another thread using WTF. On OSX, it will have the same pthread handle
</span><del>-    // but should get a different ThreadIdentifier.
-    createThread(runThread, 0, &quot;DumpRenderTree: test&quot;);
</del><ins>+    // but should get a different RefPtr&lt;Thread&gt;.
+    Thread::create(runThread, 0, &quot;DumpRenderTree: test&quot;);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> static void allocateGlobalControllers()
</span></span></pre></div>
<a id="trunkToolsTestWebKitAPITestsWTFConditioncpp"></a>
<div class="modfile"><h4>Modified: trunk/Tools/TestWebKitAPI/Tests/WTF/Condition.cpp (215264 => 215265)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/TestWebKitAPI/Tests/WTF/Condition.cpp        2017-04-12 10:14:30 UTC (rev 215264)
+++ trunk/Tools/TestWebKitAPI/Tests/WTF/Condition.cpp        2017-04-12 12:08:29 UTC (rev 215265)
</span><span class="lines">@@ -89,14 +89,14 @@
</span><span class="cx">     Condition emptyCondition;
</span><span class="cx">     Condition fullCondition;
</span><span class="cx"> 
</span><del>-    Vector&lt;ThreadIdentifier&gt; consumerThreads;
-    Vector&lt;ThreadIdentifier&gt; producerThreads;
</del><ins>+    Vector&lt;RefPtr&lt;Thread&gt;&gt; consumerThreads;
+    Vector&lt;RefPtr&lt;Thread&gt;&gt; producerThreads;
</ins><span class="cx"> 
</span><span class="cx">     Vector&lt;unsigned&gt; received;
</span><span class="cx">     Lock receivedLock;
</span><span class="cx">     
</span><span class="cx">     for (unsigned i = numConsumers; i--;) {
</span><del>-        ThreadIdentifier threadIdentifier = createThread(
</del><ins>+        RefPtr&lt;Thread&gt; threadIdentifier = Thread::create(
</ins><span class="cx">             &quot;Consumer thread&quot;,
</span><span class="cx">             [&amp;] () {
</span><span class="cx">                 for (;;) {
</span><span class="lines">@@ -108,7 +108,7 @@
</span><span class="cx">                             emptyCondition, locker, 
</span><span class="cx">                             [&amp;] () {
</span><span class="cx">                                 if (verbose)
</span><del>-                                    dataLog(toString(currentThread(), &quot;: Checking consumption predicate with shouldContinue = &quot;, shouldContinue, &quot;, queue.size() == &quot;, queue.size(), &quot;\n&quot;));
</del><ins>+                                    dataLog(toString(Thread::current(), &quot;: Checking consumption predicate with shouldContinue = &quot;, shouldContinue, &quot;, queue.size() == &quot;, queue.size(), &quot;\n&quot;));
</ins><span class="cx">                                 return !shouldContinue || !queue.isEmpty();
</span><span class="cx">                             },
</span><span class="cx">                             timeout);
</span><span class="lines">@@ -131,7 +131,7 @@
</span><span class="cx">     sleep(delay);
</span><span class="cx"> 
</span><span class="cx">     for (unsigned i = numProducers; i--;) {
</span><del>-        ThreadIdentifier threadIdentifier = createThread(
</del><ins>+        RefPtr&lt;Thread&gt; threadIdentifier = Thread::create(
</ins><span class="cx">             &quot;Producer Thread&quot;,
</span><span class="cx">             [&amp;] () {
</span><span class="cx">                 for (unsigned i = 0; i &lt; numMessagesPerProducer; ++i) {
</span><span class="lines">@@ -142,7 +142,7 @@
</span><span class="cx">                             fullCondition, locker,
</span><span class="cx">                             [&amp;] () {
</span><span class="cx">                                 if (verbose)
</span><del>-                                    dataLog(toString(currentThread(), &quot;: Checking production predicate with shouldContinue = &quot;, shouldContinue, &quot;, queue.size() == &quot;, queue.size(), &quot;\n&quot;));
</del><ins>+                                    dataLog(toString(Thread::current(), &quot;: Checking production predicate with shouldContinue = &quot;, shouldContinue, &quot;, queue.size() == &quot;, queue.size(), &quot;\n&quot;));
</ins><span class="cx">                                 return queue.size() &lt; maxQueueSize;
</span><span class="cx">                             },
</span><span class="cx">                             timeout);
</span><span class="lines">@@ -155,8 +155,8 @@
</span><span class="cx">         producerThreads.append(threadIdentifier);
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    for (ThreadIdentifier threadIdentifier : producerThreads)
-        waitForThreadCompletion(threadIdentifier);
</del><ins>+    for (RefPtr&lt;Thread&gt; threadIdentifier : producerThreads)
+        threadIdentifier-&gt;waitForCompletion();
</ins><span class="cx"> 
</span><span class="cx">     {
</span><span class="cx">         std::lock_guard&lt;Lock&gt; locker(lock);
</span><span class="lines">@@ -164,8 +164,8 @@
</span><span class="cx">     }
</span><span class="cx">     emptyCondition.notifyAll();
</span><span class="cx"> 
</span><del>-    for (ThreadIdentifier threadIdentifier : consumerThreads)
-        waitForThreadCompletion(threadIdentifier);
</del><ins>+    for (RefPtr&lt;Thread&gt; threadIdentifier : consumerThreads)
+        threadIdentifier-&gt;waitForCompletion();
</ins><span class="cx"> 
</span><span class="cx">     EXPECT_EQ(numProducers * numMessagesPerProducer, received.size());
</span><span class="cx">     std::sort(received.begin(), received.end());
</span></span></pre></div>
<a id="trunkToolsTestWebKitAPITestsWTFLockcpp"></a>
<div class="modfile"><h4>Modified: trunk/Tools/TestWebKitAPI/Tests/WTF/Lock.cpp (215264 => 215265)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/TestWebKitAPI/Tests/WTF/Lock.cpp        2017-04-12 10:14:30 UTC (rev 215264)
+++ trunk/Tools/TestWebKitAPI/Tests/WTF/Lock.cpp        2017-04-12 12:08:29 UTC (rev 215265)
</span><span class="lines">@@ -46,13 +46,13 @@
</span><span class="cx"> {
</span><span class="cx">     std::unique_ptr&lt;LockType[]&gt; locks = std::make_unique&lt;LockType[]&gt;(numThreadGroups);
</span><span class="cx">     std::unique_ptr&lt;double[]&gt; words = std::make_unique&lt;double[]&gt;(numThreadGroups);
</span><del>-    std::unique_ptr&lt;ThreadIdentifier[]&gt; threads = std::make_unique&lt;ThreadIdentifier[]&gt;(numThreadGroups * numThreadsPerGroup);
</del><ins>+    std::unique_ptr&lt;RefPtr&lt;Thread&gt;[]&gt; threads = std::make_unique&lt;RefPtr&lt;Thread&gt;[]&gt;(numThreadGroups * numThreadsPerGroup);
</ins><span class="cx"> 
</span><span class="cx">     for (unsigned threadGroupIndex = numThreadGroups; threadGroupIndex--;) {
</span><span class="cx">         words[threadGroupIndex] = 0;
</span><span class="cx"> 
</span><span class="cx">         for (unsigned threadIndex = numThreadsPerGroup; threadIndex--;) {
</span><del>-            threads[threadGroupIndex * numThreadsPerGroup + threadIndex] = createThread(
</del><ins>+            threads[threadGroupIndex * numThreadsPerGroup + threadIndex] = Thread::create(
</ins><span class="cx">                 &quot;Lock test thread&quot;,
</span><span class="cx">                 [threadGroupIndex, &amp;locks, &amp;words, numIterations, workPerCriticalSection] () {
</span><span class="cx">                     for (unsigned i = numIterations; i--;) {
</span><span class="lines">@@ -66,7 +66,7 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     for (unsigned threadIndex = numThreadGroups * numThreadsPerGroup; threadIndex--;)
</span><del>-        waitForThreadCompletion(threads[threadIndex]);
</del><ins>+        threads[threadIndex]-&gt;waitForCompletion();
</ins><span class="cx"> 
</span><span class="cx">     double expected = 0;
</span><span class="cx">     for (uint64_t i = static_cast&lt;uint64_t&gt;(numIterations) * workPerCriticalSection * numThreadsPerGroup; i--;)
</span></span></pre></div>
<a id="trunkToolsTestWebKitAPITestsWTFParkingLotcpp"></a>
<div class="modfile"><h4>Modified: trunk/Tools/TestWebKitAPI/Tests/WTF/ParkingLot.cpp (215264 => 215265)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/TestWebKitAPI/Tests/WTF/ParkingLot.cpp        2017-04-12 10:14:30 UTC (rev 215264)
+++ trunk/Tools/TestWebKitAPI/Tests/WTF/ParkingLot.cpp        2017-04-12 12:08:29 UTC (rev 215265)
</span><span class="lines">@@ -48,16 +48,15 @@
</span><span class="cx">         
</span><span class="cx">         for (unsigned i = numThreads; i--;) {
</span><span class="cx">             threads.append(
</span><del>-                createThread(
</del><ins>+                Thread::create(
</ins><span class="cx">                     &quot;Parking Test Thread&quot;,
</span><span class="cx">                     [&amp;] () {
</span><span class="cx">                         EXPECT_NE(0u, currentThread());
</span><del>-
</del><span class="cx">                         down();
</span><span class="cx"> 
</span><span class="cx">                         std::lock_guard&lt;std::mutex&gt; locker(lock);
</span><del>-                        awake.add(currentThread());
-                        lastAwoken = currentThread();
</del><ins>+                        awake.add(Thread::current());
+                        lastAwoken = &amp;Thread::current();
</ins><span class="cx">                         condition.notify_one();
</span><span class="cx">                     }));
</span><span class="cx">         }
</span><span class="lines">@@ -65,16 +64,16 @@
</span><span class="cx"> 
</span><span class="cx">     void unparkOne(unsigned singleUnparkIndex)
</span><span class="cx">     {
</span><del>-        EXPECT_EQ(0u, lastAwoken);
</del><ins>+        EXPECT_TRUE(nullptr == lastAwoken);
</ins><span class="cx">         
</span><span class="cx">         unsigned numWaitingOnAddress = 0;
</span><del>-        Vector&lt;ThreadIdentifier, 8&gt; queue;
</del><ins>+        Vector&lt;RefPtr&lt;Thread&gt;, 8&gt; queue;
</ins><span class="cx">         ParkingLot::forEach(
</span><del>-            [&amp;] (ThreadIdentifier threadIdentifier, const void* address) {
</del><ins>+            [&amp;] (Thread&amp; threadIdentifier, const void* address) {
</ins><span class="cx">                 if (address != &amp;semaphore)
</span><span class="cx">                     return;
</span><span class="cx"> 
</span><del>-                queue.append(threadIdentifier);
</del><ins>+                queue.append(&amp;threadIdentifier);
</ins><span class="cx"> 
</span><span class="cx">                 numWaitingOnAddress++;
</span><span class="cx">             });
</span><span class="lines">@@ -87,12 +86,12 @@
</span><span class="cx">             std::unique_lock&lt;std::mutex&gt; locker(lock);
</span><span class="cx">             while (awake.size() &lt; singleUnparkIndex + 1)
</span><span class="cx">                 condition.wait(locker);
</span><del>-            EXPECT_NE(0u, lastAwoken);
</del><ins>+            EXPECT_TRUE(nullptr != lastAwoken);
</ins><span class="cx">             if (!queue.isEmpty() &amp;&amp; queue[0] != lastAwoken) {
</span><span class="cx">                 dataLog(&quot;Woke up wrong thread: queue = &quot;, listDump(queue), &quot;, last awoken = &quot;, lastAwoken, &quot;\n&quot;);
</span><span class="cx">                 EXPECT_EQ(queue[0], lastAwoken);
</span><span class="cx">             }
</span><del>-            lastAwoken = 0;
</del><ins>+            lastAwoken = nullptr;
</ins><span class="cx">         }
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="lines">@@ -100,7 +99,7 @@
</span><span class="cx">     {
</span><span class="cx">         unsigned numWaitingOnAddress = 0;
</span><span class="cx">         ParkingLot::forEach(
</span><del>-            [&amp;] (ThreadIdentifier, const void* address) {
</del><ins>+            [&amp;] (Thread&amp;, const void* address) {
</ins><span class="cx">                 if (address != &amp;semaphore)
</span><span class="cx">                     return;
</span><span class="cx">                 
</span><span class="lines">@@ -114,7 +113,7 @@
</span><span class="cx"> 
</span><span class="cx">         numWaitingOnAddress = 0;
</span><span class="cx">         ParkingLot::forEach(
</span><del>-            [&amp;] (ThreadIdentifier, const void* address) {
</del><ins>+            [&amp;] (Thread&amp;, const void* address) {
</ins><span class="cx">                 if (address != &amp;semaphore)
</span><span class="cx">                     return;
</span><span class="cx">             
</span><span class="lines">@@ -129,8 +128,8 @@
</span><span class="cx">                 condition.wait(locker);
</span><span class="cx">         }
</span><span class="cx"> 
</span><del>-        for (ThreadIdentifier threadIdentifier : threads)
-            waitForThreadCompletion(threadIdentifier);
</del><ins>+        for (RefPtr&lt;Thread&gt; threadIdentifier : threads)
+            threadIdentifier-&gt;waitForCompletion();
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     // Semaphore operations.
</span><span class="lines">@@ -179,9 +178,9 @@
</span><span class="cx">     Atomic&lt;int&gt; semaphore;
</span><span class="cx">     std::mutex lock;
</span><span class="cx">     std::condition_variable condition;
</span><del>-    HashSet&lt;ThreadIdentifier&gt; awake;
-    Vector&lt;ThreadIdentifier&gt; threads;
-    ThreadIdentifier lastAwoken { 0 };
</del><ins>+    HashSet&lt;Ref&lt;Thread&gt;&gt; awake;
+    Vector&lt;RefPtr&lt;Thread&gt;&gt; threads;
+    RefPtr&lt;Thread&gt; lastAwoken;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> void runParkingTest(unsigned numLatches, unsigned delay, unsigned numThreads, unsigned numSingleUnparks)
</span></span></pre>
</div>
</div>

</body>
</html>