Diff
Modified: trunk/Source/_javascript_Core/API/JSContext.mm (220068 => 220069)
--- trunk/Source/_javascript_Core/API/JSContext.mm 2017-07-31 16:15:32 UTC (rev 220068)
+++ trunk/Source/_javascript_Core/API/JSContext.mm 2017-07-31 16:32:16 UTC (rev 220069)
@@ -141,15 +141,15 @@
+ (JSContext *)currentContext
{
- Thread& thread = Thread::current();
- CallbackData *entry = (CallbackData *)thread.m_apiData;
+ WTFThreadData& threadData = wtfThreadData();
+ CallbackData *entry = (CallbackData *)threadData.m_apiData;
return entry ? entry->context : nil;
}
+ (JSValue *)currentThis
{
- Thread& thread = Thread::current();
- CallbackData *entry = (CallbackData *)thread.m_apiData;
+ WTFThreadData& threadData = wtfThreadData();
+ CallbackData *entry = (CallbackData *)threadData.m_apiData;
if (!entry)
return nil;
return [JSValue valueWithJSValueRef:entry->thisValue inContext:[JSContext currentContext]];
@@ -157,8 +157,8 @@
+ (JSValue *)currentCallee
{
- Thread& thread = Thread::current();
- CallbackData *entry = (CallbackData *)thread.m_apiData;
+ WTFThreadData& threadData = wtfThreadData();
+ CallbackData *entry = (CallbackData *)threadData.m_apiData;
if (!entry)
return nil;
return [JSValue valueWithJSValueRef:entry->calleeValue inContext:[JSContext currentContext]];
@@ -166,8 +166,8 @@
+ (NSArray *)currentArguments
{
- Thread& thread = Thread::current();
- CallbackData *entry = (CallbackData *)thread.m_apiData;
+ WTFThreadData& threadData = wtfThreadData();
+ CallbackData *entry = (CallbackData *)threadData.m_apiData;
if (!entry)
return nil;
@@ -294,21 +294,21 @@
- (void)beginCallbackWithData:(CallbackData *)callbackData calleeValue:(JSValueRef)calleeValue thisValue:(JSValueRef)thisValue argumentCount:(size_t)argumentCount arguments:(const JSValueRef *)arguments
{
- Thread& thread = Thread::current();
+ WTFThreadData& threadData = wtfThreadData();
[self retain];
- CallbackData *prevStack = (CallbackData *)thread.m_apiData;
+ CallbackData *prevStack = (CallbackData *)threadData.m_apiData;
*callbackData = (CallbackData){ prevStack, self, [self.exception retain], calleeValue, thisValue, argumentCount, arguments, nil };
- thread.m_apiData = callbackData;
+ threadData.m_apiData = callbackData;
self.exception = nil;
}
- (void)endCallbackWithData:(CallbackData *)callbackData
{
- Thread& thread = Thread::current();
+ WTFThreadData& threadData = wtfThreadData();
self.exception = callbackData->preservedException;
[callbackData->preservedException release];
[callbackData->currentArguments release];
- thread.m_apiData = callbackData->next;
+ threadData.m_apiData = callbackData->next;
[self release];
}
Modified: trunk/Source/_javascript_Core/ChangeLog (220068 => 220069)
--- trunk/Source/_javascript_Core/ChangeLog 2017-07-31 16:15:32 UTC (rev 220068)
+++ trunk/Source/_javascript_Core/ChangeLog 2017-07-31 16:32:16 UTC (rev 220069)
@@ -1,3 +1,16 @@
+2017-07-31 Matt Lewis <jlew...@apple.com>
+
+ Unreviewed, rolling out r220060.
+
+ This broke our internal builds. Contact reviewer of patch for
+ more information.
+
+ Reverted changeset:
+
+ "Merge WTFThreadData to Thread::current"
+ https://bugs.webkit.org/show_bug.cgi?id=174716
+ http://trac.webkit.org/changeset/220060
+
2017-07-31 Yusuke Suzuki <utatane....@gmail.com>
[JSC] Support optional catch binding
Modified: trunk/Source/_javascript_Core/heap/Heap.cpp (220068 => 220069)
--- trunk/Source/_javascript_Core/heap/Heap.cpp 2017-07-31 16:15:32 UTC (rev 220068)
+++ trunk/Source/_javascript_Core/heap/Heap.cpp 2017-07-31 16:32:16 UTC (rev 220069)
@@ -140,7 +140,7 @@
bool isValidThreadState(VM* vm)
{
- if (vm->atomicStringTable() != WTF::Thread::current().atomicStringTable())
+ if (vm->atomicStringTable() != wtfThreadData().atomicStringTable())
return false;
if (vm->isSharedInstance() && !isValidSharedInstanceThreadState(vm))
@@ -2023,7 +2023,7 @@
stopIfNecessary();
ASSERT(vm()->currentThreadIsHoldingAPILock());
- RELEASE_ASSERT(vm()->atomicStringTable() == WTF::Thread::current().atomicStringTable());
+ RELEASE_ASSERT(vm()->atomicStringTable() == wtfThreadData().atomicStringTable());
LockHolder locker(*m_threadLock);
// We may be able to steal the conn. That only works if the collector is definitely not running
Modified: trunk/Source/_javascript_Core/runtime/Completion.cpp (220068 => 220069)
--- trunk/Source/_javascript_Core/runtime/Completion.cpp 2017-07-31 16:15:32 UTC (rev 220068)
+++ trunk/Source/_javascript_Core/runtime/Completion.cpp 2017-07-31 16:32:16 UTC (rev 220069)
@@ -41,6 +41,7 @@
#include "Parser.h"
#include "ProgramExecutable.h"
#include "ScriptProfilingScope.h"
+#include <wtf/WTFThreadData.h>
namespace JSC {
@@ -47,7 +48,7 @@
bool checkSyntax(ExecState* exec, const SourceCode& source, JSValue* returnedException)
{
JSLockHolder lock(exec);
- RELEASE_ASSERT(exec->vm().atomicStringTable() == Thread::current().atomicStringTable());
+ RELEASE_ASSERT(exec->vm().atomicStringTable() == wtfThreadData().atomicStringTable());
ProgramExecutable* program = ProgramExecutable::create(exec, source);
JSObject* error = program->checkSyntax(exec);
@@ -63,7 +64,7 @@
bool checkSyntax(VM& vm, const SourceCode& source, ParserError& error)
{
JSLockHolder lock(vm);
- RELEASE_ASSERT(vm.atomicStringTable() == Thread::current().atomicStringTable());
+ RELEASE_ASSERT(vm.atomicStringTable() == wtfThreadData().atomicStringTable());
return !!parse<ProgramNode>(
&vm, source, Identifier(), JSParserBuiltinMode::NotBuiltin,
JSParserStrictMode::NotStrict, JSParserScriptMode::Classic, SourceParseMode::ProgramMode, SuperBinding::NotNeeded, error);
@@ -73,7 +74,7 @@
{
VM& vm = exec->vm();
JSLockHolder lock(vm);
- RELEASE_ASSERT(vm.atomicStringTable() == Thread::current().atomicStringTable());
+ RELEASE_ASSERT(vm.atomicStringTable() == wtfThreadData().atomicStringTable());
std::unique_ptr<ModuleProgramNode> moduleProgramNode = parse<ModuleProgramNode>(
&vm, source, Identifier(), JSParserBuiltinMode::NotBuiltin,
JSParserStrictMode::Strict, JSParserScriptMode::Module, SourceParseMode::ModuleAnalyzeMode, SuperBinding::NotNeeded, error);
@@ -91,7 +92,7 @@
VM& vm = exec->vm();
JSLockHolder lock(vm);
auto scope = DECLARE_CATCH_SCOPE(vm);
- RELEASE_ASSERT(vm.atomicStringTable() == Thread::current().atomicStringTable());
+ RELEASE_ASSERT(vm.atomicStringTable() == wtfThreadData().atomicStringTable());
RELEASE_ASSERT(!vm.isCollectorBusyOnCurrentThread());
CodeProfiling profile(source);
@@ -166,7 +167,7 @@
JSInternalPromise* loadAndEvaluateModule(ExecState* exec, const String& moduleName, JSValue scriptFetcher)
{
JSLockHolder lock(exec);
- RELEASE_ASSERT(exec->vm().atomicStringTable() == Thread::current().atomicStringTable());
+ RELEASE_ASSERT(exec->vm().atomicStringTable() == wtfThreadData().atomicStringTable());
RELEASE_ASSERT(!exec->vm().isCollectorBusyOnCurrentThread());
return loadAndEvaluateModule(lock, exec, exec->vmEntryGlobalObject(), Identifier::fromString(exec, moduleName), scriptFetcher);
@@ -177,7 +178,7 @@
VM& vm = exec->vm();
JSLockHolder lock(vm);
auto scope = DECLARE_THROW_SCOPE(vm);
- RELEASE_ASSERT(vm.atomicStringTable() == Thread::current().atomicStringTable());
+ RELEASE_ASSERT(vm.atomicStringTable() == wtfThreadData().atomicStringTable());
RELEASE_ASSERT(!vm.isCollectorBusyOnCurrentThread());
Symbol* key = createSymbolForEntryPointModule(vm);
@@ -204,7 +205,7 @@
JSInternalPromise* loadModule(ExecState* exec, const String& moduleName, JSValue scriptFetcher)
{
JSLockHolder lock(exec);
- RELEASE_ASSERT(exec->vm().atomicStringTable() == Thread::current().atomicStringTable());
+ RELEASE_ASSERT(exec->vm().atomicStringTable() == wtfThreadData().atomicStringTable());
RELEASE_ASSERT(!exec->vm().isCollectorBusyOnCurrentThread());
return loadModule(lock, exec, exec->vmEntryGlobalObject(), Identifier::fromString(exec, moduleName), scriptFetcher);
@@ -215,7 +216,7 @@
VM& vm = exec->vm();
JSLockHolder lock(vm);
auto scope = DECLARE_THROW_SCOPE(vm);
- RELEASE_ASSERT(vm.atomicStringTable() == Thread::current().atomicStringTable());
+ RELEASE_ASSERT(vm.atomicStringTable() == wtfThreadData().atomicStringTable());
RELEASE_ASSERT(!vm.isCollectorBusyOnCurrentThread());
Symbol* key = createSymbolForEntryPointModule(vm);
@@ -233,7 +234,7 @@
JSValue linkAndEvaluateModule(ExecState* exec, const Identifier& moduleKey, JSValue scriptFetcher)
{
JSLockHolder lock(exec);
- RELEASE_ASSERT(exec->vm().atomicStringTable() == Thread::current().atomicStringTable());
+ RELEASE_ASSERT(exec->vm().atomicStringTable() == wtfThreadData().atomicStringTable());
RELEASE_ASSERT(!exec->vm().isCollectorBusyOnCurrentThread());
JSGlobalObject* globalObject = exec->vmEntryGlobalObject();
@@ -243,7 +244,7 @@
JSInternalPromise* importModule(ExecState* exec, const Identifier& moduleKey, JSValue scriptFetcher)
{
JSLockHolder lock(exec);
- RELEASE_ASSERT(exec->vm().atomicStringTable() == Thread::current().atomicStringTable());
+ RELEASE_ASSERT(exec->vm().atomicStringTable() == wtfThreadData().atomicStringTable());
RELEASE_ASSERT(!exec->vm().isCollectorBusyOnCurrentThread());
return exec->vmEntryGlobalObject()->moduleLoader()->requestImportModule(exec, moduleKey, scriptFetcher);
Modified: trunk/Source/_javascript_Core/runtime/Identifier.cpp (220068 => 220069)
--- trunk/Source/_javascript_Core/runtime/Identifier.cpp 2017-07-31 16:15:32 UTC (rev 220068)
+++ trunk/Source/_javascript_Core/runtime/Identifier.cpp 2017-07-31 16:32:16 UTC (rev 220069)
@@ -110,7 +110,7 @@
{
// Check the identifier table accessible through the threadspecific matches the
// vm's identifier table.
- ASSERT_UNUSED(vm, vm->atomicStringTable() == Thread::current().atomicStringTable());
+ ASSERT_UNUSED(vm, vm->atomicStringTable() == wtfThreadData().atomicStringTable());
}
void Identifier::checkCurrentAtomicStringTable(ExecState* exec)
Modified: trunk/Source/_javascript_Core/runtime/InitializeThreading.cpp (220068 => 220069)
--- trunk/Source/_javascript_Core/runtime/InitializeThreading.cpp 2017-07-31 16:15:32 UTC (rev 220068)
+++ trunk/Source/_javascript_Core/runtime/InitializeThreading.cpp 2017-07-31 16:32:16 UTC (rev 220069)
@@ -75,8 +75,8 @@
DisallowVMReentry::initialize();
#endif
initializeSuperSampler();
- Thread& thread = Thread::current();
- thread.setSavedLastStackTop(thread.stack().origin());
+ WTFThreadData& threadData = wtfThreadData();
+ threadData.setSavedLastStackTop(threadData.stack().origin());
#if ENABLE(WEBASSEMBLY)
Wasm::Thunks::initialize();
Modified: trunk/Source/_javascript_Core/runtime/JSLock.cpp (220068 => 220069)
--- trunk/Source/_javascript_Core/runtime/JSLock.cpp 2017-07-31 16:15:32 UTC (rev 220068)
+++ trunk/Source/_javascript_Core/runtime/JSLock.cpp 2017-07-31 16:32:16 UTC (rev 220069)
@@ -127,9 +127,9 @@
if (!m_vm)
return;
- Thread& thread = Thread::current();
+ WTFThreadData& threadData = wtfThreadData();
ASSERT(!m_entryAtomicStringTable);
- m_entryAtomicStringTable = thread.setCurrentAtomicStringTable(m_vm->atomicStringTable());
+ m_entryAtomicStringTable = threadData.setCurrentAtomicStringTable(m_vm->atomicStringTable());
ASSERT(m_entryAtomicStringTable);
if (m_vm->heap.hasAccess())
@@ -143,7 +143,7 @@
void* p = &p; // A proxy for the current stack pointer.
m_vm->setStackPointerAtVMEntry(p);
- m_vm->setLastStackTop(thread.savedLastStackTop());
+ m_vm->setLastStackTop(threadData.savedLastStackTop());
m_vm->heap.machineThreads().addCurrentThread();
#if ENABLE(WEBASSEMBLY)
@@ -200,7 +200,7 @@
}
if (m_entryAtomicStringTable) {
- Thread::current().setCurrentAtomicStringTable(m_entryAtomicStringTable);
+ wtfThreadData().setCurrentAtomicStringTable(m_entryAtomicStringTable);
m_entryAtomicStringTable = nullptr;
}
}
@@ -225,9 +225,9 @@
dropper->setDropDepth(m_lockDropDepth);
- Thread& thread = Thread::current();
- thread.setSavedStackPointerAtVMEntry(m_vm->stackPointerAtVMEntry());
- thread.setSavedLastStackTop(m_vm->lastStackTop());
+ WTFThreadData& threadData = wtfThreadData();
+ threadData.setSavedStackPointerAtVMEntry(m_vm->stackPointerAtVMEntry());
+ threadData.setSavedLastStackTop(m_vm->lastStackTop());
unsigned droppedLockCount = m_lockCount;
unlock(droppedLockCount);
@@ -252,9 +252,9 @@
--m_lockDropDepth;
- Thread& thread = Thread::current();
- m_vm->setStackPointerAtVMEntry(thread.savedStackPointerAtVMEntry());
- m_vm->setLastStackTop(thread.savedLastStackTop());
+ WTFThreadData& threadData = wtfThreadData();
+ m_vm->setStackPointerAtVMEntry(threadData.savedStackPointerAtVMEntry());
+ m_vm->setLastStackTop(threadData.savedLastStackTop());
}
JSLock::DropAllLocks::DropAllLocks(VM* vm)
Modified: trunk/Source/_javascript_Core/runtime/JSLock.h (220068 => 220069)
--- trunk/Source/_javascript_Core/runtime/JSLock.h 2017-07-31 16:15:32 UTC (rev 220068)
+++ trunk/Source/_javascript_Core/runtime/JSLock.h 2017-07-31 16:32:16 UTC (rev 220069)
@@ -25,7 +25,7 @@
#include <wtf/Lock.h>
#include <wtf/Noncopyable.h>
#include <wtf/RefPtr.h>
-#include <wtf/Threading.h>
+#include <wtf/ThreadSafeRefCounted.h>
#include <wtf/text/AtomicStringTable.h>
namespace JSC {
Modified: trunk/Source/_javascript_Core/runtime/VM.cpp (220068 => 220069)
--- trunk/Source/_javascript_Core/runtime/VM.cpp 2017-07-31 16:15:32 UTC (rev 220068)
+++ trunk/Source/_javascript_Core/runtime/VM.cpp 2017-07-31 16:32:16 UTC (rev 220069)
@@ -114,6 +114,7 @@
#include <wtf/SimpleStats.h>
#include <wtf/StringPrintStream.h>
#include <wtf/Threading.h>
+#include <wtf/WTFThreadData.h>
#include <wtf/text/AtomicStringTable.h>
#include <wtf/text/SymbolRegistry.h>
@@ -175,7 +176,7 @@
, topVMEntryFrame(nullptr)
, topCallFrame(CallFrame::noCaller())
, promiseDeferredTimer(std::make_unique<PromiseDeferredTimer>(*this))
- , m_atomicStringTable(vmType == Default ? Thread::current().atomicStringTable() : new AtomicStringTable)
+ , m_atomicStringTable(vmType == Default ? wtfThreadData().atomicStringTable() : new AtomicStringTable)
, propertyNames(nullptr)
, emptyList(new ArgList)
, machineCodeBytesPerBytecodeWordForBaselineJIT(std::make_unique<SimpleStats>())
@@ -210,13 +211,13 @@
, m_shadowChicken(std::make_unique<ShadowChicken>())
{
interpreter = new Interpreter(*this);
- StackBounds stack = Thread::current().stack();
+ StackBounds stack = wtfThreadData().stack();
updateSoftReservedZoneSize(Options::softReservedZoneSize());
setLastStackTop(stack.origin());
// Need to be careful to keep everything consistent here
JSLockHolder lock(this);
- AtomicStringTable* existingEntryAtomicStringTable = Thread::current().setCurrentAtomicStringTable(m_atomicStringTable);
+ AtomicStringTable* existingEntryAtomicStringTable = wtfThreadData().setCurrentAtomicStringTable(m_atomicStringTable);
propertyNames = new CommonIdentifiers(this);
structureStructure.set(*this, Structure::createStructure(*this));
structureRareDataStructure.set(*this, StructureRareData::createStructure(*this, 0, jsNull()));
@@ -269,7 +270,7 @@
nativeStdFunctionCellStructure.set(*this, NativeStdFunctionCell::createStructure(*this, 0, jsNull()));
smallStrings.initializeCommonStrings(*this);
- Thread::current().setCurrentAtomicStringTable(existingEntryAtomicStringTable);
+ wtfThreadData().setCurrentAtomicStringTable(existingEntryAtomicStringTable);
#if ENABLE(JIT)
jitStubs = std::make_unique<JITThunks>();
@@ -671,7 +672,7 @@
void* lastSoftStackLimit = m_softStackLimit;
#endif
- const StackBounds& stack = Thread::current().stack();
+ const StackBounds& stack = wtfThreadData().stack();
size_t reservedZoneSize = Options::reservedZoneSize();
// We should have already ensured that Options::reservedZoneSize() >= minimumReserveZoneSize at
// options initialization time, and the option value should not have been changed thereafter.
@@ -885,9 +886,9 @@
#if ENABLE(JIT)
// When using the C stack, we don't know how many stack pages are actually
// committed. So, we use the current stack usage as an estimate.
- ASSERT(Thread::current().stack().isGrowingDownward());
+ ASSERT(wtfThreadData().stack().isGrowingDownward());
int8_t* current = reinterpret_cast<int8_t*>(¤t);
- int8_t* high = reinterpret_cast<int8_t*>(Thread::current().stack().origin());
+ int8_t* high = reinterpret_cast<int8_t*>(wtfThreadData().stack().origin());
return high - current;
#else
return CLoopStack::committedByteCount();
Modified: trunk/Source/_javascript_Core/runtime/VM.h (220068 => 220069)
--- trunk/Source/_javascript_Core/runtime/VM.h 2017-07-31 16:15:32 UTC (rev 220068)
+++ trunk/Source/_javascript_Core/runtime/VM.h 2017-07-31 16:32:16 UTC (rev 220069)
@@ -68,6 +68,7 @@
#include <wtf/Stopwatch.h>
#include <wtf/ThreadSafeRefCounted.h>
#include <wtf/ThreadSpecific.h>
+#include <wtf/WTFThreadData.h>
#include <wtf/text/SymbolRegistry.h>
#include <wtf/text/WTFString.h>
#if ENABLE(REGEXP_TRACING)
@@ -242,7 +243,7 @@
// WebCore has a one-to-one mapping of threads to VMs;
// either create() or createLeaked() should only be called once
// on a thread, this is the 'default' VM (it uses the
- // thread's default string uniquing table from Thread::current()).
+ // thread's default string uniquing table from wtfThreadData).
// API contexts created using the new context group aware interface
// create APIContextGroup objects which require less locking of JSC
// than the old singleton APIShared VM created for use by
@@ -690,7 +691,7 @@
bool isSafeToRecurse(void* stackLimit) const
{
- ASSERT(Thread::current().stack().isGrowingDownward());
+ ASSERT(wtfThreadData().stack().isGrowingDownward());
void* curr = reinterpret_cast<void*>(&curr);
return curr >= stackLimit;
}
Modified: trunk/Source/_javascript_Core/runtime/VMEntryScope.cpp (220068 => 220069)
--- trunk/Source/_javascript_Core/runtime/VMEntryScope.cpp 2017-07-31 16:15:32 UTC (rev 220068)
+++ trunk/Source/_javascript_Core/runtime/VMEntryScope.cpp 2017-07-31 16:32:16 UTC (rev 220069)
@@ -41,7 +41,7 @@
, m_globalObject(globalObject)
{
ASSERT(!DisallowVMReentry::isInEffectOnCurrentThread());
- ASSERT(Thread::current().stack().isGrowingDownward());
+ ASSERT(wtfThreadData().stack().isGrowingDownward());
if (!vm.entryScope) {
vm.entryScope = this;
Modified: trunk/Source/_javascript_Core/runtime/VMInlines.h (220068 => 220069)
--- trunk/Source/_javascript_Core/runtime/VMInlines.h 2017-07-31 16:15:32 UTC (rev 220068)
+++ trunk/Source/_javascript_Core/runtime/VMInlines.h 2017-07-31 16:32:16 UTC (rev 220069)
@@ -34,7 +34,7 @@
bool VM::ensureStackCapacityFor(Register* newTopOfStack)
{
#if ENABLE(JIT)
- ASSERT(Thread::current().stack().isGrowingDownward());
+ ASSERT(wtfThreadData().stack().isGrowingDownward());
return newTopOfStack >= m_softStackLimit;
#else
return ensureStackCapacityForCLoop(newTopOfStack);
Modified: trunk/Source/_javascript_Core/yarr/YarrPattern.cpp (220068 => 220069)
--- trunk/Source/_javascript_Core/yarr/YarrPattern.cpp 2017-07-31 16:15:32 UTC (rev 220068)
+++ trunk/Source/_javascript_Core/yarr/YarrPattern.cpp 2017-07-31 16:32:16 UTC (rev 220069)
@@ -32,8 +32,8 @@
#include "YarrCanonicalize.h"
#include "YarrParser.h"
#include <wtf/DataLog.h>
-#include <wtf/Threading.h>
#include <wtf/Vector.h>
+#include <wtf/WTFThreadData.h>
using namespace WTF;
@@ -882,7 +882,7 @@
{
if (!m_stackLimit)
return true;
- ASSERT(Thread::current().stack().isGrowingDownward());
+ ASSERT(wtfThreadData().stack().isGrowingDownward());
int8_t* curr = reinterpret_cast<int8_t*>(&curr);
int8_t* limit = reinterpret_cast<int8_t*>(m_stackLimit);
return curr >= limit;
Modified: trunk/Source/WTF/ChangeLog (220068 => 220069)
--- trunk/Source/WTF/ChangeLog 2017-07-31 16:15:32 UTC (rev 220068)
+++ trunk/Source/WTF/ChangeLog 2017-07-31 16:32:16 UTC (rev 220069)
@@ -1,3 +1,16 @@
+2017-07-31 Matt Lewis <jlew...@apple.com>
+
+ Unreviewed, rolling out r220060.
+
+ This broke our internal builds. Contact reviewer of patch for
+ more information.
+
+ Reverted changeset:
+
+ "Merge WTFThreadData to Thread::current"
+ https://bugs.webkit.org/show_bug.cgi?id=174716
+ http://trac.webkit.org/changeset/220060
+
2017-07-31 Yusuke Suzuki <utatane....@gmail.com>
Merge WTFThreadData to Thread::current
Modified: trunk/Source/WTF/WTF.xcodeproj/project.pbxproj (220068 => 220069)
--- trunk/Source/WTF/WTF.xcodeproj/project.pbxproj 2017-07-31 16:15:32 UTC (rev 220068)
+++ trunk/Source/WTF/WTF.xcodeproj/project.pbxproj 2017-07-31 16:32:16 UTC (rev 220069)
@@ -123,6 +123,7 @@
A8A47460151A825B004123FF /* CollatorDefault.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A8A4734B151A825B004123FF /* CollatorDefault.cpp */; };
A8A47463151A825B004123FF /* CollatorICU.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A8A47350151A825B004123FF /* CollatorICU.cpp */; };
A8A47469151A825B004123FF /* UTF8.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A8A47357151A825B004123FF /* UTF8.cpp */; };
+ A8A47486151A825B004123FF /* WTFThreadData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A8A4737A151A825B004123FF /* WTFThreadData.cpp */; };
AD89B6B71E6415080090707F /* MemoryPressureHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AD89B6B51E6415080090707F /* MemoryPressureHandler.cpp */; };
AD89B6BA1E64150F0090707F /* MemoryPressureHandlerCocoa.mm in Sources */ = {isa = PBXBuildFile; fileRef = AD89B6B91E64150F0090707F /* MemoryPressureHandlerCocoa.mm */; };
ADF2CE671E39F106006889DB /* MemoryFootprintCocoa.cpp in Sources */ = {isa = PBXBuildFile; fileRef = ADF2CE651E39F106006889DB /* MemoryFootprintCocoa.cpp */; };
@@ -514,6 +515,8 @@
A8A47370151A825B004123FF /* Vector.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Vector.h; sourceTree = "<group>"; };
A8A47371151A825B004123FF /* VectorTraits.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VectorTraits.h; sourceTree = "<group>"; };
A8A47372151A825B004123FF /* VMTags.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VMTags.h; sourceTree = "<group>"; };
+ A8A4737A151A825B004123FF /* WTFThreadData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WTFThreadData.cpp; sourceTree = "<group>"; };
+ A8A4737B151A825B004123FF /* WTFThreadData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WTFThreadData.h; sourceTree = "<group>"; };
A8A4748B151A8264004123FF /* config.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = config.h; sourceTree = "<group>"; };
A9A4727F151A825A004123FF /* DisallowCType.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DisallowCType.h; sourceTree = "<group>"; };
AD7C434A1DD2A4A70026888B /* Expected.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Expected.h; sourceTree = "<group>"; };
@@ -996,6 +999,8 @@
0FE4479B1B7AAA03009498EB /* WordLock.h */,
E4A0AD371A96245500536DF6 /* WorkQueue.cpp */,
E4A0AD381A96245500536DF6 /* WorkQueue.h */,
+ A8A4737A151A825B004123FF /* WTFThreadData.cpp */,
+ A8A4737B151A825B004123FF /* WTFThreadData.h */,
);
path = wtf;
sourceTree = "<group>";
@@ -1406,6 +1411,7 @@
E4A0AD391A96245500536DF6 /* WorkQueue.cpp in Sources */,
E4A0AD3D1A96253C00536DF6 /* WorkQueueCocoa.cpp in Sources */,
A8A47445151A825B004123FF /* WTFString.cpp in Sources */,
+ A8A47486151A825B004123FF /* WTFThreadData.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Modified: trunk/Source/WTF/wtf/CMakeLists.txt (220068 => 220069)
--- trunk/Source/WTF/wtf/CMakeLists.txt 2017-07-31 16:15:32 UTC (rev 220068)
+++ trunk/Source/WTF/wtf/CMakeLists.txt 2017-07-31 16:32:16 UTC (rev 220069)
@@ -150,6 +150,7 @@
Variant.h
Vector.h
VectorTraits.h
+ WTFThreadData.h
WallTime.h
WeakPtr.h
WordLock.h
@@ -253,6 +254,7 @@
Threading.cpp
TimeWithDynamicClockType.cpp
UUID.cpp
+ WTFThreadData.cpp
WallTime.cpp
WordLock.cpp
WorkQueue.cpp
Modified: trunk/Source/WTF/wtf/LockAlgorithm.h (220068 => 220069)
--- trunk/Source/WTF/wtf/LockAlgorithm.h 2017-07-31 16:15:32 UTC (rev 220068)
+++ trunk/Source/WTF/wtf/LockAlgorithm.h 2017-07-31 16:32:16 UTC (rev 220069)
@@ -28,6 +28,7 @@
#include <wtf/Atomics.h>
#include <wtf/Compiler.h>
+#include <wtf/Threading.h>
namespace WTF {
Modified: trunk/Source/WTF/wtf/LockAlgorithmInlines.h (220068 => 220069)
--- trunk/Source/WTF/wtf/LockAlgorithmInlines.h 2017-07-31 16:15:32 UTC (rev 220068)
+++ trunk/Source/WTF/wtf/LockAlgorithmInlines.h 2017-07-31 16:32:16 UTC (rev 220069)
@@ -27,7 +27,6 @@
#include <wtf/LockAlgorithm.h>
#include <wtf/ParkingLot.h>
-#include <wtf/Threading.h>
// It's a good idea to avoid including this header in too many places, so that it's possible to change
// the lock algorithm slow path without recompiling the world. Right now this should be included in two
Modified: trunk/Source/WTF/wtf/MainThread.h (220068 => 220069)
--- trunk/Source/WTF/wtf/MainThread.h 2017-07-31 16:15:32 UTC (rev 220068)
+++ trunk/Source/WTF/wtf/MainThread.h 2017-07-31 16:32:16 UTC (rev 220069)
@@ -33,7 +33,7 @@
#include <stdint.h>
#include <wtf/Function.h>
#include <wtf/Optional.h>
-#include <wtf/ThreadingPrimitives.h>
+#include <wtf/Threading.h>
namespace WTF {
Modified: trunk/Source/WTF/wtf/ParkingLot.cpp (220068 => 220069)
--- trunk/Source/WTF/wtf/ParkingLot.cpp 2017-07-31 16:15:32 UTC (rev 220068)
+++ trunk/Source/WTF/wtf/ParkingLot.cpp 2017-07-31 16:32:16 UTC (rev 220069)
@@ -31,7 +31,7 @@
#include "HashFunctions.h"
#include "StringPrintStream.h"
#include "ThreadSpecific.h"
-#include "Threading.h"
+#include "ThreadingPrimitives.h"
#include "Vector.h"
#include "WeakRandom.h"
#include "WordLock.h"
Modified: trunk/Source/WTF/wtf/StackStats.cpp (220068 => 220069)
--- trunk/Source/WTF/wtf/StackStats.cpp 2017-07-31 16:15:32 UTC (rev 220068)
+++ trunk/Source/WTF/wtf/StackStats.cpp 2017-07-31 16:32:16 UTC (rev 220069)
@@ -30,6 +30,7 @@
#include "Assertions.h"
#include "DataLog.h"
+#include "WTFThreadData.h"
// Define the following flag if you want to collect stats on every single
// checkpoint. By default, we only log checkpoints that establish new
@@ -58,7 +59,7 @@
StackStats::PerThreadStats::PerThreadStats()
{
- const StackBounds& stack = Thread::current().stack();
+ const StackBounds& stack = wtfThreadData().stack();
m_reentryDepth = 0;
m_stackStart = (char*)stack.origin();
m_currentCheckPoint = 0;
@@ -69,9 +70,9 @@
StackStats::CheckPoint::CheckPoint()
{
std::lock_guard<StaticLock> lock(StackStats::s_sharedMutex);
- Thread& thread = Thread::current();
- StackStats::PerThreadStats& t = thread.stackStats();
- const StackBounds& stack = thread.stack();
+ WTFThreadData* threadData = const_cast<WTFThreadData*>(&wtfThreadData());
+ StackStats::PerThreadStats& t = threadData->stackStats();
+ const StackBounds& stack = threadData->stack();
bool isGrowingDownward = stack.isGrowingDownward();
bool needToLog = false;
@@ -127,8 +128,8 @@
StackStats::CheckPoint::~CheckPoint()
{
std::lock_guard<StaticLock> lock(StackStats::s_sharedMutex);
- Thread& thread = Thread::current();
- StackStats::PerThreadStats& t = thread.stackStats();
+ WTFThreadData* threadData = const_cast<WTFThreadData*>(&wtfThreadData());
+ StackStats::PerThreadStats& t = threadData->stackStats();
// Pop to previous checkpoint:
t.m_currentCheckPoint = m_prev;
@@ -137,7 +138,7 @@
// Log this checkpoint if needed:
#if ENABLE(VERBOSE_STACK_STATS)
if (!m_prev) {
- const StackBounds& stack = thread.stack();
+ const StackBounds& stack = threadData->stack();
bool isGrowingDownward = stack.isGrowingDownward();
char* current = reinterpret_cast<char*>(this);
@@ -158,9 +159,9 @@
void StackStats::probe()
{
std::lock_guard<StaticLock> lock(StackStats::s_sharedMutex);
- Thread& thread = Thread::current();
- StackStats::PerThreadStats& t = thread.stackStats();
- const StackBounds& stack = thread.stack();
+ WTFThreadData* threadData = const_cast<WTFThreadData*>(&wtfThreadData());
+ StackStats::PerThreadStats& t = threadData->stackStats();
+ const StackBounds& stack = threadData->stack();
bool isGrowingDownward = stack.isGrowingDownward();
@@ -219,9 +220,9 @@
StackStats::probe();
std::lock_guard<StaticLock> lock(StackStats::s_sharedMutex);
- Thread& thread = Thread::current();
- StackStats::PerThreadStats& t = thread.stackStats();
- const StackBounds& stack = thread.stack();
+ WTFThreadData* threadData = const_cast<WTFThreadData*>(&wtfThreadData());
+ StackStats::PerThreadStats& t = threadData->stackStats();
+ const StackBounds& stack = threadData->stack();
bool isGrowingDownward = stack.isGrowingDownward();
Modified: trunk/Source/WTF/wtf/ThreadHolder.cpp (220068 => 220069)
--- trunk/Source/WTF/wtf/ThreadHolder.cpp 2017-07-31 16:15:32 UTC (rev 220068)
+++ trunk/Source/WTF/wtf/ThreadHolder.cpp 2017-07-31 16:32:16 UTC (rev 220069)
@@ -43,9 +43,4 @@
m_thread->didExit();
}
-ThreadHolder& ThreadHolder::initializeCurrent()
-{
- return initialize(Thread::createCurrentThread());
-}
-
} // namespace WTF
Modified: trunk/Source/WTF/wtf/ThreadHolder.h (220068 => 220069)
--- trunk/Source/WTF/wtf/ThreadHolder.h 2017-07-31 16:15:32 UTC (rev 220068)
+++ trunk/Source/WTF/wtf/ThreadHolder.h 2017-07-31 16:32:16 UTC (rev 220069)
@@ -29,17 +29,13 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef ThreadHolder_h
-#define ThreadHolder_h
+#pragma once
-#include <wtf/Ref.h>
-#include <wtf/RefPtr.h>
#include <wtf/ThreadSpecific.h>
+#include <wtf/Threading.h>
namespace WTF {
-class Thread;
-
// 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
@@ -51,26 +47,23 @@
// One time initialization for this class as a whole.
// This method must be called before initialize() and it is not thread-safe.
- WTF_EXPORT_PRIVATE static void initializeOnce();
+ static void initializeOnce();
// Creates and puts an instance of ThreadHolder into thread-specific storage.
- WTF_EXPORT_PRIVATE static ThreadHolder& initialize(Ref<Thread>&&);
- WTF_EXPORT_PRIVATE static ThreadHolder& initializeCurrent();
+ static void initialize(Thread&);
// Returns 0 if thread-specific storage was not initialized.
- static ThreadHolder& current();
- static ThreadHolder* currentMayBeNull();
+ static ThreadHolder* current();
Thread& thread() { return m_thread.get(); }
#if OS(WINDOWS)
- WTF_EXPORT_PRIVATE static ThreadHolder* currentDying();
static RefPtr<Thread> get(ThreadIdentifier);
#endif
private:
- ThreadHolder(Ref<Thread>&& thread)
- : m_thread(WTFMove(thread))
+ ThreadHolder(Thread& thread)
+ : m_thread(thread)
, m_isDestroyedOnce(false)
{
}
@@ -84,39 +77,7 @@
Ref<Thread> m_thread;
bool m_isDestroyedOnce;
- static WTF_EXPORTDATA ThreadSpecificKey m_key;
+ static ThreadSpecificKey m_key;
};
-inline ThreadHolder* ThreadHolder::currentMayBeNull()
-{
-#if !HAVE(FAST_TLS)
- ASSERT(m_key != InvalidThreadSpecificKey);
- return static_cast<ThreadHolder*>(threadSpecificGet(m_key));
-#else
- return static_cast<ThreadHolder*>(_pthread_getspecific_direct(WTF_THREAD_DATA_KEY));
-#endif
-}
-
-inline ThreadHolder& ThreadHolder::current()
-{
- // WRT WebCore:
- // ThreadHolder is used on main thread before it could possibly be used
- // on secondary ones, so there is no need for synchronization here.
- // WRT _javascript_Core:
- // Thread::current() is initially called from initializeThreading(), ensuring
- // this is initially called in a pthread_once locked context.
-#if !HAVE(FAST_TLS)
- if (UNLIKELY(ThreadHolder::m_key == InvalidThreadSpecificKey))
- initializeOnce();
-#endif
- if (auto* holder = currentMayBeNull())
- return *holder;
-#if OS(WINDOWS)
- if (auto* holder = currentDying())
- return *holder;
-#endif
- return initializeCurrent();
-}
-
} // namespace WTF
-#endif // ThreadHolder_h
Modified: trunk/Source/WTF/wtf/ThreadHolderPthreads.cpp (220068 => 220069)
--- trunk/Source/WTF/wtf/ThreadHolderPthreads.cpp 2017-07-31 16:15:32 UTC (rev 220068)
+++ trunk/Source/WTF/wtf/ThreadHolderPthreads.cpp 2017-07-31 16:32:16 UTC (rev 220069)
@@ -41,41 +41,36 @@
threadSpecificKeyCreate(&m_key, destruct);
}
-ThreadHolder& ThreadHolder::initialize(Ref<Thread>&& thread)
+ThreadHolder* ThreadHolder::current()
{
- auto* holder = new ThreadHolder(WTFMove(thread));
-#if !HAVE(FAST_TLS)
- // 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 "didn't call
- // WTF::initializeThreading() soon enough" bugs in release mode.
ASSERT(m_key != InvalidThreadSpecificKey);
- threadSpecificSet(m_key, holder);
-#else
- _pthread_setspecific_direct(WTF_THREAD_DATA_KEY, holder);
- pthread_key_init_np(WTF_THREAD_DATA_KEY, &destruct);
-#endif
- return *holder;
+ return static_cast<ThreadHolder*>(threadSpecificGet(m_key));
}
+void ThreadHolder::initialize(Thread& 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 "didn't call
+ // WTF::initializeThreading() soon enough" bugs in release mode.
+ ASSERT(m_key != InvalidThreadSpecificKey);
+ threadSpecificSet(m_key, new ThreadHolder(thread));
+ }
+}
+
void ThreadHolder::destruct(void* data)
{
- ThreadHolder* holder = static_cast<ThreadHolder*>(data);
- ASSERT(holder);
+ ThreadHolder* threadIdentifierData = static_cast<ThreadHolder*>(data);
+ ASSERT(threadIdentifierData);
- if (holder->m_isDestroyedOnce) {
- delete holder;
+ if (threadIdentifierData->m_isDestroyedOnce) {
+ delete threadIdentifierData;
return;
}
- holder->m_isDestroyedOnce = true;
+ threadIdentifierData->m_isDestroyedOnce = true;
// Re-setting the value for key causes another destruct() call after all other thread-specific destructors were called.
-#if !HAVE(FAST_TLS)
- ASSERT(m_key != InvalidThreadSpecificKey);
- threadSpecificSet(m_key, holder);
-#else
- _pthread_setspecific_direct(WTF_THREAD_DATA_KEY, holder);
- pthread_key_init_np(WTF_THREAD_DATA_KEY, &destruct);
-#endif
+ threadSpecificSet(m_key, threadIdentifierData);
}
} // namespace WTF
Modified: trunk/Source/WTF/wtf/ThreadHolderWin.cpp (220068 => 220069)
--- trunk/Source/WTF/wtf/ThreadHolderWin.cpp 2017-07-31 16:15:32 UTC (rev 220068)
+++ trunk/Source/WTF/wtf/ThreadHolderWin.cpp 2017-07-31 16:32:16 UTC (rev 220069)
@@ -56,9 +56,15 @@
threadSpecificKeyCreate(&m_key, destruct);
}
-ThreadHolder* ThreadHolder::currentDying()
+ThreadHolder* ThreadHolder::current()
{
ASSERT(m_key != InvalidThreadSpecificKey);
+ ThreadHolder* holder = static_cast<ThreadHolder*>(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::lock_guard<std::mutex> locker(threadMapMutex());
return threadMap().get(currentThread());
@@ -74,21 +80,21 @@
return nullptr;
}
-ThreadHolder& ThreadHolder::initialize(Ref<Thread>&& thread)
+void ThreadHolder::initialize(Thread& thread)
{
- // 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 "didn't call
- // WTF::initializeThreading() soon enough" bugs in release mode.
- ASSERT(m_key != InvalidThreadSpecificKey);
- // FIXME: Remove this workaround code once <rdar://problem/31793213> is fixed.
- auto id = thread->id();
- auto* holder = new ThreadHolder(WTFMove(thread));
- threadSpecificSet(m_key, holder);
- {
- std::lock_guard<std::mutex> locker(threadMapMutex());
- threadMap().add(id, holder);
+ 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 "didn't call
+ // WTF::initializeThreading() soon enough" bugs in release mode.
+ ASSERT(m_key != InvalidThreadSpecificKey);
+ // FIXME: Remove this workaround code once <rdar://problem/31793213> is fixed.
+ auto* holder = new ThreadHolder(thread);
+ threadSpecificSet(m_key, holder);
+ {
+ std::lock_guard<std::mutex> locker(threadMapMutex());
+ threadMap().add(thread.id(), holder);
+ }
}
- return *holder;
}
void ThreadHolder::destruct(void* data)
Modified: trunk/Source/WTF/wtf/Threading.cpp (220068 => 220069)
--- trunk/Source/WTF/wtf/Threading.cpp 2017-07-31 16:15:32 UTC (rev 220068)
+++ trunk/Source/WTF/wtf/Threading.cpp 2017-07-31 16:32:16 UTC (rev 220069)
@@ -37,7 +37,7 @@
#include <wtf/ThreadHolder.h>
#include <wtf/ThreadMessage.h>
#include <wtf/ThreadingPrimitives.h>
-#include <wtf/text/AtomicStringTable.h>
+#include <wtf/WTFThreadData.h>
#include <wtf/text/StringView.h>
#if HAVE(QOS_CLASSES)
@@ -94,13 +94,6 @@
#endif
}
-void Thread::initializeInThread()
-{
- m_savedLastStackTop = stack().origin();
- AtomicStringTable::create(*this);
- m_currentAtomicStringTable = m_defaultAtomicStringTable;
-}
-
void Thread::entryPoint(NewThreadContext* newThreadContext)
{
Function<void()> function;
@@ -112,7 +105,7 @@
ASSERT(context->stage == NewThreadContext::Stage::EstablishedHandle);
// Initialize thread holder with established ID.
- ThreadHolder::initialize(context->thread.copyRef());
+ ThreadHolder::initialize(context->thread.get());
Thread::initializeCurrentThreadInternal(context->name);
function = WTFMove(context->entryPoint);
@@ -123,7 +116,6 @@
context->stage = NewThreadContext::Stage::Initialized;
context->condition.signal();
#endif
- context->thread->initializeInThread();
}
ASSERT(!Thread::current().stack().isEmpty());
@@ -163,6 +155,14 @@
return WTFMove(thread);
}
+Thread* Thread::currentMayBeNull()
+{
+ ThreadHolder* data = ""
+ if (data)
+ return &data->thread();
+ return nullptr;
+}
+
static bool shouldRemoveThreadFromThreadGroup()
{
#if OS(WINDOWS)
@@ -197,9 +197,6 @@
threadGroup->m_threads.remove(*this);
}
}
- if (m_atomicStringTableDestructor)
- m_atomicStringTableDestructor(m_defaultAtomicStringTable);
-
// We would like to say "thread is exited" after unregistering threads from thread groups.
// So we need to separate m_isShuttingDown from m_didExit.
std::lock_guard<std::mutex> locker(m_mutex);
@@ -280,8 +277,9 @@
{
static std::once_flag initializeKey;
std::call_once(initializeKey, [] {
+ ThreadHolder::initializeOnce();
initializeRandomNumberGenerator();
- Thread::current();
+ wtfThreadData();
initializeDates();
Thread::initializePlatformThreading();
});
Modified: trunk/Source/WTF/wtf/Threading.h (220068 => 220069)
--- trunk/Source/WTF/wtf/Threading.h 2017-07-31 16:15:32 UTC (rev 220068)
+++ trunk/Source/WTF/wtf/Threading.h 2017-07-31 16:32:16 UTC (rev 220069)
@@ -39,8 +39,6 @@
#include <wtf/PlatformRegisters.h>
#include <wtf/RefPtr.h>
#include <wtf/StackBounds.h>
-#include <wtf/StackStats.h>
-#include <wtf/ThreadHolder.h>
#include <wtf/ThreadSafeRefCounted.h>
#include <wtf/Vector.h>
@@ -52,13 +50,13 @@
namespace WTF {
class AbstractLocker;
-class AtomicStringTable;
class ThreadMessageData;
-using AtomicStringTableDestructor = void (*)(AtomicStringTable*);
-
enum class ThreadGroupAddResult;
+using ThreadIdentifier = uint32_t;
+typedef void (*ThreadFunction)(void* argument);
+
class ThreadGroup;
class ThreadHolder;
class PrintStream;
@@ -67,7 +65,6 @@
public:
friend class ThreadGroup;
friend class ThreadHolder;
- friend class AtomicStringTable;
WTF_EXPORT_PRIVATE ~Thread();
@@ -76,7 +73,8 @@
WTF_EXPORT_PRIVATE static RefPtr<Thread> create(const char* threadName, Function<void()>&&);
// Returns Thread object.
- static Thread& current();
+ WTF_EXPORT_PRIVATE static Thread& current();
+ static Thread* currentMayBeNull();
// 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
@@ -143,47 +141,6 @@
return m_stack;
}
- AtomicStringTable* atomicStringTable()
- {
- return m_currentAtomicStringTable;
- }
-
- AtomicStringTable* setCurrentAtomicStringTable(AtomicStringTable* atomicStringTable)
- {
- AtomicStringTable* oldAtomicStringTable = m_currentAtomicStringTable;
- m_currentAtomicStringTable = atomicStringTable;
- return oldAtomicStringTable;
- }
-
-#if ENABLE(STACK_STATS)
- StackStats::PerThreadStats& stackStats()
- {
- return m_stackStats;
- }
-#endif
-
- void* savedStackPointerAtVMEntry()
- {
- return m_savedStackPointerAtVMEntry;
- }
-
- void setSavedStackPointerAtVMEntry(void* stackPointerAtVMEntry)
- {
- m_savedStackPointerAtVMEntry = stackPointerAtVMEntry;
- }
-
- void* savedLastStackTop()
- {
- return m_savedLastStackTop;
- }
-
- void setSavedLastStackTop(void* lastStackTop)
- {
- m_savedLastStackTop = lastStackTop;
- }
-
- void* m_apiData { nullptr };
-
#if OS(DARWIN)
mach_port_t machThread() { return m_platformThread; }
#endif
@@ -193,16 +150,13 @@
protected:
Thread();
- static Ref<Thread> createCurrentThread();
- void initializeInThread();
-
// Internal platform-specific Thread establishment implementation.
bool establishHandle(NewThreadContext*);
#if USE(PTHREADS)
- void establishPlatformSpecificHandle(PlatformThreadHandle);
+ void establishPlatformSpecificHandle(pthread_t);
#else
- void establishPlatformSpecificHandle(PlatformThreadHandle, ThreadIdentifier);
+ void establishPlatformSpecificHandle(HANDLE, ThreadIdentifier);
#endif
#if USE(PTHREADS) && !OS(DARWIN)
@@ -243,25 +197,22 @@
Vector<std::weak_ptr<ThreadGroup>> m_threadGroups;
bool m_isShuttingDown { false };
bool m_didExit { false };
- PlatformThreadHandle m_handle;
+#if USE(PTHREADS)
+ pthread_t m_handle;
+
#if OS(DARWIN)
mach_port_t m_platformThread;
-#elif USE(PTHREADS)
+#else
sem_t m_semaphoreForSuspendResume;
PlatformRegisters m_platformRegisters;
unsigned m_suspendCount { 0 };
std::atomic<bool> m_suspended { false };
#endif
-
- AtomicStringTable* m_currentAtomicStringTable { nullptr };
- AtomicStringTable* m_defaultAtomicStringTable { nullptr };
- AtomicStringTableDestructor m_atomicStringTableDestructor { nullptr };
-
-#if ENABLE(STACK_STATS)
- StackStats::PerThreadStats m_stackStats;
+#elif OS(WINDOWS)
+ HANDLE m_handle { INVALID_HANDLE_VALUE };
+#else
+#error Unknown System
#endif
- void* m_savedStackPointerAtVMEntry { nullptr };
- void* m_savedLastStackTop;
};
// This function can be called from any threads.
@@ -272,10 +223,6 @@
return Thread::currentID();
}
-inline Thread& Thread::current()
-{
- return ThreadHolder::current().thread();
-}
// FIXME: The following functions remain because they are used from WebKit Windows support library,
// WebKitQuartzCoreAdditions.dll. When updating the support library, we should use new API instead
Modified: trunk/Source/WTF/wtf/ThreadingPrimitives.h (220068 => 220069)
--- trunk/Source/WTF/wtf/ThreadingPrimitives.h 2017-07-31 16:15:32 UTC (rev 220068)
+++ trunk/Source/WTF/wtf/ThreadingPrimitives.h 2017-07-31 16:32:16 UTC (rev 220069)
@@ -45,9 +45,6 @@
namespace WTF {
-using ThreadIdentifier = uint32_t;
-using ThreadFunction = void (*)(void* argument);
-
#if USE(PTHREADS)
using PlatformThreadHandle = pthread_t;
using PlatformMutex = pthread_mutex_t;
Modified: trunk/Source/WTF/wtf/ThreadingPthreads.cpp (220068 => 220069)
--- trunk/Source/WTF/wtf/ThreadingPthreads.cpp 2017-07-31 16:15:32 UTC (rev 220068)
+++ trunk/Source/WTF/wtf/ThreadingPthreads.cpp 2017-07-31 16:32:16 UTC (rev 220069)
@@ -286,16 +286,18 @@
didBecomeDetached();
}
+Thread& Thread::current()
+{
+ if (Thread* current = currentMayBeNull())
+ return *current;
-Ref<Thread> Thread::createCurrentThread()
-{
// Not a WTF-created thread, ThreadIdentifier is not established yet.
Ref<Thread> thread = adoptRef(*new Thread());
thread->establishPlatformSpecificHandle(pthread_self());
thread->m_stack = StackBounds::currentThreadStackBounds();
- thread->initializeInThread();
+ ThreadHolder::initialize(thread.get());
initializeCurrentThreadEvenIfNonWTFCreated();
- return thread;
+ return thread.get();
}
ThreadIdentifier Thread::currentID()
Modified: trunk/Source/WTF/wtf/ThreadingWin.cpp (220068 => 220069)
--- trunk/Source/WTF/wtf/ThreadingWin.cpp 2017-07-31 16:15:32 UTC (rev 220068)
+++ trunk/Source/WTF/wtf/ThreadingWin.cpp 2017-07-31 16:32:16 UTC (rev 220069)
@@ -243,8 +243,11 @@
return sizeof(CONTEXT);
}
-Ref<Thread> Thread::createCurrentThread()
+Thread& Thread::current()
{
+ if (Thread* current = currentMayBeNull())
+ return *current;
+
// Not a WTF-created thread, ThreadIdentifier is not established yet.
Ref<Thread> thread = adoptRef(*new Thread());
@@ -254,9 +257,9 @@
thread->establishPlatformSpecificHandle(handle, currentID());
thread->m_stack = StackBounds::currentThreadStackBounds();
- thread->initializeInThread();
+ ThreadHolder::initialize(thread.get());
initializeCurrentThreadEvenIfNonWTFCreated();
- return thread;
+ return thread.get();
}
ThreadIdentifier Thread::currentID()
Copied: trunk/Source/WTF/wtf/WTFThreadData.cpp (from rev 220068, trunk/Source/_javascript_Core/runtime/VMInlines.h) (0 => 220069)
--- trunk/Source/WTF/wtf/WTFThreadData.cpp (rev 0)
+++ trunk/Source/WTF/wtf/WTFThreadData.cpp 2017-07-31 16:32:16 UTC (rev 220069)
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2008, 2010 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.
+ *
+ */
+
+#include "config.h"
+#include "WTFThreadData.h"
+
+#include <wtf/text/AtomicStringTable.h>
+
+#if USE(WEB_THREAD)
+#include <wtf/MainThread.h>
+#endif
+
+namespace WTF {
+
+#if !HAVE(FAST_TLS)
+ThreadSpecific<WTFThreadData>* WTFThreadData::staticData;
+#endif
+
+WTFThreadData::WTFThreadData()
+ : m_stackBounds(StackBounds::currentThreadStackBounds())
+ , m_savedLastStackTop(stack().origin())
+{
+ AtomicStringTable::create(*this);
+ m_currentAtomicStringTable = m_defaultAtomicStringTable;
+}
+
+WTFThreadData::~WTFThreadData()
+{
+ if (m_atomicStringTableDestructor)
+ m_atomicStringTableDestructor(m_defaultAtomicStringTable);
+}
+
+#if HAVE(FAST_TLS)
+WTFThreadData& WTFThreadData::createAndRegisterForGetspecificDirect()
+{
+ WTFThreadData* data = "" WTFThreadData;
+ _pthread_setspecific_direct(WTF_THREAD_DATA_KEY, data);
+ pthread_key_init_np(WTF_THREAD_DATA_KEY, [](void* data){
+ delete static_cast<WTFThreadData*>(data);
+ });
+ return *data;
+}
+#endif
+
+} // namespace WTF
Added: trunk/Source/WTF/wtf/WTFThreadData.h (0 => 220069)
--- trunk/Source/WTF/wtf/WTFThreadData.h (rev 0)
+++ trunk/Source/WTF/wtf/WTFThreadData.h 2017-07-31 16:32:16 UTC (rev 220069)
@@ -0,0 +1,141 @@
+/*
+ * Copyright (C) 2008-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.
+ *
+ */
+
+#ifndef WTFThreadData_h
+#define WTFThreadData_h
+
+#include <wtf/FastTLS.h>
+#include <wtf/Noncopyable.h>
+#include <wtf/StackBounds.h>
+#include <wtf/StackStats.h>
+#include <wtf/ThreadSpecific.h>
+
+namespace WTF {
+
+class AtomicStringTable;
+
+typedef void (*AtomicStringTableDestructor)(AtomicStringTable*);
+
+class WTFThreadData {
+ WTF_MAKE_NONCOPYABLE(WTFThreadData);
+public:
+ WTF_EXPORT_PRIVATE WTFThreadData();
+ WTF_EXPORT_PRIVATE ~WTFThreadData();
+
+ AtomicStringTable* atomicStringTable()
+ {
+ return m_currentAtomicStringTable;
+ }
+
+ AtomicStringTable* setCurrentAtomicStringTable(AtomicStringTable* atomicStringTable)
+ {
+ AtomicStringTable* oldAtomicStringTable = m_currentAtomicStringTable;
+ m_currentAtomicStringTable = atomicStringTable;
+ return oldAtomicStringTable;
+ }
+
+ const StackBounds& stack()
+ {
+ return m_stackBounds;
+ }
+
+#if ENABLE(STACK_STATS)
+ StackStats::PerThreadStats& stackStats()
+ {
+ return m_stackStats;
+ }
+#endif
+
+ void* savedStackPointerAtVMEntry()
+ {
+ return m_savedStackPointerAtVMEntry;
+ }
+
+ void setSavedStackPointerAtVMEntry(void* stackPointerAtVMEntry)
+ {
+ m_savedStackPointerAtVMEntry = stackPointerAtVMEntry;
+ }
+
+ void* savedLastStackTop()
+ {
+ return m_savedLastStackTop;
+ }
+
+ void setSavedLastStackTop(void* lastStackTop)
+ {
+ m_savedLastStackTop = lastStackTop;
+ }
+
+ void* m_apiData { nullptr };
+
+private:
+ AtomicStringTable* m_currentAtomicStringTable { nullptr };
+ AtomicStringTable* m_defaultAtomicStringTable { nullptr };
+ AtomicStringTableDestructor m_atomicStringTableDestructor { nullptr };
+
+ StackBounds m_stackBounds;
+#if ENABLE(STACK_STATS)
+ StackStats::PerThreadStats m_stackStats;
+#endif
+ void* m_savedStackPointerAtVMEntry { nullptr };
+ void* m_savedLastStackTop;
+
+#if HAVE(FAST_TLS)
+ WTF_EXPORT_PRIVATE static WTFThreadData& createAndRegisterForGetspecificDirect();
+#else
+ static WTF_EXPORTDATA ThreadSpecific<WTFThreadData>* staticData;
+#endif
+
+ friend WTFThreadData& wtfThreadData();
+ friend class AtomicStringTable;
+};
+
+inline WTFThreadData& wtfThreadData()
+{
+ // WRT WebCore:
+ // WTFThreadData is used on main thread before it could possibly be used
+ // on secondary ones, so there is no need for synchronization here.
+ // WRT _javascript_Core:
+ // wtfThreadData() is initially called from initializeThreading(), ensuring
+ // this is initially called in a pthread_once locked context.
+#if !HAVE(FAST_TLS)
+ if (!WTFThreadData::staticData)
+ WTFThreadData::staticData = new ThreadSpecific<WTFThreadData>;
+ return **WTFThreadData::staticData;
+#else
+ if (WTFThreadData* data = ""
+ return *data;
+ return WTFThreadData::createAndRegisterForGetspecificDirect();
+#endif
+}
+
+} // namespace WTF
+
+using WTF::WTFThreadData;
+using WTF::wtfThreadData;
+using WTF::AtomicStringTable;
+
+#endif // WTFThreadData_h
Modified: trunk/Source/WTF/wtf/text/AtomicString.cpp (220068 => 220069)
--- trunk/Source/WTF/wtf/text/AtomicString.cpp 2017-07-31 16:15:32 UTC (rev 220068)
+++ trunk/Source/WTF/wtf/text/AtomicString.cpp 2017-07-31 16:32:16 UTC (rev 220069)
@@ -23,10 +23,8 @@
#include "config.h"
#include "AtomicString.h"
-#include <mutex>
-#include <wtf/MainThread.h>
-#include <wtf/text/IntegerToStringConversion.h>
-
+#include "IntegerToStringConversion.h"
+#include "MainThread.h"
#include "dtoa.h"
namespace WTF {
Modified: trunk/Source/WTF/wtf/text/AtomicStringImpl.cpp (220068 => 220069)
--- trunk/Source/WTF/wtf/text/AtomicStringImpl.cpp 2017-07-31 16:15:32 UTC (rev 220068)
+++ trunk/Source/WTF/wtf/text/AtomicStringImpl.cpp 2017-07-31 16:32:16 UTC (rev 220069)
@@ -32,6 +32,7 @@
#include "StringHash.h"
#include "StringPrintStream.h"
#include "Threading.h"
+#include "WTFThreadData.h"
#include <wtf/unicode/UTF8.h>
#if USE(WEB_THREAD)
@@ -71,7 +72,7 @@
static ALWAYS_INLINE StringTableImpl& stringTable()
{
- return Thread::current().atomicStringTable()->table();
+ return wtfThreadData().atomicStringTable()->table();
}
template<typename T, typename HashTranslator>
Modified: trunk/Source/WTF/wtf/text/AtomicStringTable.cpp (220068 => 220069)
--- trunk/Source/WTF/wtf/text/AtomicStringTable.cpp 2017-07-31 16:15:32 UTC (rev 220068)
+++ trunk/Source/WTF/wtf/text/AtomicStringTable.cpp 2017-07-31 16:32:16 UTC (rev 220069)
@@ -25,11 +25,11 @@
#include <wtf/HashSet.h>
#include <wtf/MainThread.h>
-#include <wtf/Threading.h>
+#include <wtf/WTFThreadData.h>
namespace WTF {
-void AtomicStringTable::create(Thread& thread)
+void AtomicStringTable::create(WTFThreadData& data)
{
#if USE(WEB_THREAD)
// On iOS, one AtomicStringTable is shared between the main UI thread and the WebThread.
@@ -37,17 +37,17 @@
bool currentThreadIsWebThread = isWebThread();
if (currentThreadIsWebThread || isUIThread())
- thread.m_defaultAtomicStringTable = sharedStringTable;
+ data.m_defaultAtomicStringTable = sharedStringTable;
else
- thread.m_defaultAtomicStringTable = new AtomicStringTable;
+ data.m_defaultAtomicStringTable = new AtomicStringTable;
// We do the following so that its destruction happens only
// once - on the main UI thread.
if (!currentThreadIsWebThread)
- thread.m_atomicStringTableDestructor = AtomicStringTable::destroy;
+ data.m_atomicStringTableDestructor = AtomicStringTable::destroy;
#else
- thread.m_defaultAtomicStringTable = new AtomicStringTable;
- thread.m_atomicStringTableDestructor = AtomicStringTable::destroy;
+ data.m_defaultAtomicStringTable = new AtomicStringTable;
+ data.m_atomicStringTableDestructor = AtomicStringTable::destroy;
#endif // USE(WEB_THREAD)
}
Modified: trunk/Source/WTF/wtf/text/AtomicStringTable.h (220068 => 220069)
--- trunk/Source/WTF/wtf/text/AtomicStringTable.h 2017-07-31 16:15:32 UTC (rev 220068)
+++ trunk/Source/WTF/wtf/text/AtomicStringTable.h 2017-07-31 16:32:16 UTC (rev 220069)
@@ -24,12 +24,12 @@
#define WTF_AtomicStringTable_h
#include <wtf/HashSet.h>
+#include <wtf/WTFThreadData.h>
#include <wtf/text/StringImpl.h>
namespace WTF {
class StringImpl;
-class Thread;
class AtomicStringTable {
WTF_MAKE_FAST_ALLOCATED;
@@ -36,7 +36,7 @@
public:
WTF_EXPORT_PRIVATE ~AtomicStringTable();
- static void create(Thread&);
+ static void create(WTFThreadData&);
HashSet<StringImpl*>& table() { return m_table; }
private:
@@ -46,6 +46,5 @@
};
}
-using WTF::AtomicStringTable;
#endif
Modified: trunk/Source/WebCore/ChangeLog (220068 => 220069)
--- trunk/Source/WebCore/ChangeLog 2017-07-31 16:15:32 UTC (rev 220068)
+++ trunk/Source/WebCore/ChangeLog 2017-07-31 16:32:16 UTC (rev 220069)
@@ -1,3 +1,16 @@
+2017-07-31 Matt Lewis <jlew...@apple.com>
+
+ Unreviewed, rolling out r220060.
+
+ This broke our internal builds. Contact reviewer of patch for
+ more information.
+
+ Reverted changeset:
+
+ "Merge WTFThreadData to Thread::current"
+ https://bugs.webkit.org/show_bug.cgi?id=174716
+ http://trac.webkit.org/changeset/220060
+
2017-07-31 Yusuke Suzuki <utatane....@gmail.com>
Merge WTFThreadData to Thread::current
Modified: trunk/Source/WebCore/fileapi/AsyncFileStream.cpp (220068 => 220069)
--- trunk/Source/WebCore/fileapi/AsyncFileStream.cpp 2017-07-31 16:15:32 UTC (rev 220068)
+++ trunk/Source/WebCore/fileapi/AsyncFileStream.cpp 2017-07-31 16:32:16 UTC (rev 220069)
@@ -41,7 +41,6 @@
#include <wtf/MainThread.h>
#include <wtf/MessageQueue.h>
#include <wtf/NeverDestroyed.h>
-#include <wtf/Threading.h>
namespace WebCore {
Modified: trunk/Source/WebCore/platform/ThreadGlobalData.cpp (220068 => 220069)
--- trunk/Source/WebCore/platform/ThreadGlobalData.cpp 2017-07-31 16:15:32 UTC (rev 220068)
+++ trunk/Source/WebCore/platform/ThreadGlobalData.cpp 2017-07-31 16:32:16 UTC (rev 220069)
@@ -35,6 +35,7 @@
#include <wtf/MainThread.h>
#include <wtf/ThreadSpecific.h>
#include <wtf/Threading.h>
+#include <wtf/WTFThreadData.h>
#include <wtf/text/StringImpl.h>
#if PLATFORM(MAC)
@@ -65,7 +66,7 @@
// any other thread, and is only called once per thread - this makes this a convenient
// point to call methods that internally perform a one-time initialization that is not
// threadsafe.
- Thread::current();
+ wtfThreadData();
StringImpl::empty();
}
Modified: trunk/Source/WebCore/platform/graphics/cocoa/WebCoreDecompressionSession.h (220068 => 220069)
--- trunk/Source/WebCore/platform/graphics/cocoa/WebCoreDecompressionSession.h 2017-07-31 16:15:32 UTC (rev 220068)
+++ trunk/Source/WebCore/platform/graphics/cocoa/WebCoreDecompressionSession.h 2017-07-31 16:32:16 UTC (rev 220069)
@@ -28,7 +28,6 @@
#if USE(VIDEOTOOLBOX)
#include <CoreMedia/CMTime.h>
-#include <functional>
#include <wtf/Lock.h>
#include <wtf/MediaTime.h>
#include <wtf/OSObjectPtr.h>
Modified: trunk/Source/WebCore/platform/ios/wak/WebCoreThread.mm (220068 => 220069)
--- trunk/Source/WebCore/platform/ios/wak/WebCoreThread.mm 2017-07-31 16:15:32 UTC (rev 220068)
+++ trunk/Source/WebCore/platform/ios/wak/WebCoreThread.mm 2017-07-31 16:32:16 UTC (rev 220069)
@@ -702,7 +702,7 @@
{
webThreadStarted = TRUE;
- // ThreadGlobalData touches AtomicString, which requires Threading initialization.
+ // ThreadGlobalData touches AtomicString, which requires WTFThreadData and Threading initialization.
WTF::initializeThreading();
// Initialize AtomicString on the main thread.
Modified: trunk/Source/WebCore/workers/WorkerThread.cpp (220068 => 220069)
--- trunk/Source/WebCore/workers/WorkerThread.cpp 2017-07-31 16:15:32 UTC (rev 220068)
+++ trunk/Source/WebCore/workers/WorkerThread.cpp 2017-07-31 16:32:16 UTC (rev 220069)
@@ -216,7 +216,7 @@
// We cannot let any objects survive past thread exit, because no other thread will run GC or otherwise destroy them.
workerGlobalScopeToDelete = nullptr;
- // Clean up WebCore::ThreadGlobalData before WTF::Thread goes away!
+ // Clean up WebCore::ThreadGlobalData before WTF::WTFThreadData goes away!
threadGlobalData().destroy();
// The thread object may be already destroyed from notification now, don't try to access "this".