Diff
Modified: branches/safari-601.6.16-branch/LayoutTests/ChangeLog (199857 => 199858)
--- branches/safari-601.6.16-branch/LayoutTests/ChangeLog 2016-04-22 01:15:01 UTC (rev 199857)
+++ branches/safari-601.6.16-branch/LayoutTests/ChangeLog 2016-04-22 01:18:00 UTC (rev 199858)
@@ -1,3 +1,21 @@
+2016-04-21 Babak Shafiei <bshaf...@apple.com>
+
+ Merge r199762.
+
+ 2016-04-19 Michael Saboff <msab...@apple.com>
+
+ iTunes crashing _javascript_Core.dll
+ https://bugs.webkit.org/show_bug.cgi?id=156647
+
+ Reviewed by Filip Pizlo.
+
+ Disabled fast/workers/dedicated-worker-lifecycle.html as it creates
+ more workers that we have ThreadSpecific keys. We need at least one
+ key per JSC VM we create. I didn't want to weaken the test for other
+ platforms.
+
+ * platform/win/TestExpectations:
+
2016-03-31 Matthew Hanson <matthew_han...@apple.com>
Roll out r191180. rdar://problem/25448882
Modified: branches/safari-601.6.16-branch/LayoutTests/platform/win/TestExpectations (199857 => 199858)
--- branches/safari-601.6.16-branch/LayoutTests/platform/win/TestExpectations 2016-04-22 01:15:01 UTC (rev 199857)
+++ branches/safari-601.6.16-branch/LayoutTests/platform/win/TestExpectations 2016-04-22 01:18:00 UTC (rev 199858)
@@ -419,6 +419,10 @@
storage/storagequota-request-quota.html [ Skip ]
fast/workers/worker-storagequota-query-usage.html [ Skip ]
+# The number of workers in this test exceeds the number of
+# ThreadSpecificValues we have on Windows.
+fast/workers/dedicated-worker-lifecycle.html [ Skip ]
+
# Tests that require ENABLE(DOWNLOAD_ATTRIBUTE).
fast/dom/HTMLAnchorElement/anchor-nodownload.html [ Skip ]
fast/dom/HTMLAnchorElement/anchor-download.html [ Skip ]
Modified: branches/safari-601.6.16-branch/Source/_javascript_Core/ChangeLog (199857 => 199858)
--- branches/safari-601.6.16-branch/Source/_javascript_Core/ChangeLog 2016-04-22 01:15:01 UTC (rev 199857)
+++ branches/safari-601.6.16-branch/Source/_javascript_Core/ChangeLog 2016-04-22 01:18:00 UTC (rev 199858)
@@ -1,3 +1,31 @@
+2016-04-21 Babak Shafiei <bshaf...@apple.com>
+
+ Merge r199762.
+
+ 2016-04-19 Michael Saboff <msab...@apple.com>
+
+ iTunes crashing _javascript_Core.dll
+ https://bugs.webkit.org/show_bug.cgi?id=156647
+
+ Reviewed by Filip Pizlo.
+
+ Given that there there are only 128 FLS indices compared to over a 1000 for TLS,
+ I eliminated the thread specific m_threadSpecificForThread and instead we look
+ for the current thread in m_registeredThreads list when we need it.
+ In most cases there will only be one thread.
+
+ Added THREAD_SPECIFIC_CALL to signature of ThreadSpecific remove callbacks
+ to set the calling convention correctly for Windows 32 bit.
+
+ * heap/MachineStackMarker.cpp:
+ (JSC::ActiveMachineThreadsManager::remove):
+ (JSC::MachineThreads::MachineThreads):
+ (JSC::MachineThreads::~MachineThreads):
+ (JSC::MachineThreads::addCurrentThread):
+ (JSC::MachineThreads::machineThreadForCurrentThread):
+ (JSC::MachineThreads::removeThread):
+ * heap/MachineStackMarker.h:
+
2016-03-24 Matthew Hanson <matthew_han...@apple.com>
Merge r198592. rdar://problem/25332806
Modified: branches/safari-601.6.16-branch/Source/_javascript_Core/heap/MachineStackMarker.cpp (199857 => 199858)
--- branches/safari-601.6.16-branch/Source/_javascript_Core/heap/MachineStackMarker.cpp 2016-04-22 01:15:01 UTC (rev 199857)
+++ branches/safari-601.6.16-branch/Source/_javascript_Core/heap/MachineStackMarker.cpp 2016-04-22 01:18:00 UTC (rev 199858)
@@ -112,7 +112,7 @@
m_set.add(machineThreads);
}
- void remove(MachineThreads* machineThreads)
+ void THREAD_SPECIFIC_CALL remove(MachineThreads* machineThreads)
{
MutexLocker managerLock(m_lock);
auto recordedMachineThreads = m_set.take(machineThreads);
@@ -248,20 +248,20 @@
MachineThreads::MachineThreads(Heap* heap)
: m_registeredThreads(0)
- , m_threadSpecific(0)
+ , m_threadSpecificForMachineThreads(0)
#if !ASSERT_DISABLED
, m_heap(heap)
#endif
{
UNUSED_PARAM(heap);
- threadSpecificKeyCreate(&m_threadSpecific, removeThread);
+ threadSpecificKeyCreate(&m_threadSpecificForMachineThreads, removeThread);
activeMachineThreadsManager().add(this);
}
MachineThreads::~MachineThreads()
{
activeMachineThreadsManager().remove(this);
- threadSpecificKeyDelete(m_threadSpecific);
+ threadSpecificKeyDelete(m_threadSpecificForMachineThreads);
MutexLocker registeredThreadsLock(m_registeredThreadsMutex);
for (Thread* t = m_registeredThreads; t;) {
@@ -286,12 +286,15 @@
{
ASSERT(!m_heap->vm()->hasExclusiveThread() || m_heap->vm()->exclusiveThread() == std::this_thread::get_id());
- if (threadSpecificGet(m_threadSpecific)) {
- ASSERT(threadSpecificGet(m_threadSpecific) == this);
+ if (threadSpecificGet(m_threadSpecificForMachineThreads)) {
+#ifndef NDEBUG
+ MutexLocker lock(m_registeredThreadsMutex);
+ ASSERT(threadSpecificGet(m_threadSpecificForMachineThreads) == this);
+#endif
return;
}
- threadSpecificSet(m_threadSpecific, this);
+ threadSpecificSet(m_threadSpecificForMachineThreads, this);
Thread* thread = Thread::createForCurrentThread();
MutexLocker lock(m_registeredThreadsMutex);
@@ -300,7 +303,7 @@
m_registeredThreads = thread;
}
-void MachineThreads::removeThread(void* p)
+void THREAD_SPECIFIC_CALL MachineThreads::removeThread(void* p)
{
auto& manager = activeMachineThreadsManager();
ActiveMachineThreadsManager::Locker lock(manager);
Modified: branches/safari-601.6.16-branch/Source/_javascript_Core/heap/MachineStackMarker.h (199857 => 199858)
--- branches/safari-601.6.16-branch/Source/_javascript_Core/heap/MachineStackMarker.h 2016-04-22 01:15:01 UTC (rev 199857)
+++ branches/safari-601.6.16-branch/Source/_javascript_Core/heap/MachineStackMarker.h 2016-04-22 01:18:00 UTC (rev 199858)
@@ -54,14 +54,14 @@
void tryCopyOtherThreadStack(Thread*, void*, size_t capacity, size_t*);
bool tryCopyOtherThreadStacks(MutexLocker&, void*, size_t capacity, size_t*);
- static void removeThread(void*);
+ static void THREAD_SPECIFIC_CALL removeThread(void*);
template<typename PlatformThread>
void removeThreadIfFound(PlatformThread);
Mutex m_registeredThreadsMutex;
Thread* m_registeredThreads;
- WTF::ThreadSpecificKey m_threadSpecific;
+ WTF::ThreadSpecificKey m_threadSpecificForMachineThreads;
#if !ASSERT_DISABLED
Heap* m_heap;
#endif
Modified: branches/safari-601.6.16-branch/Source/WTF/ChangeLog (199857 => 199858)
--- branches/safari-601.6.16-branch/Source/WTF/ChangeLog 2016-04-22 01:15:01 UTC (rev 199857)
+++ branches/safari-601.6.16-branch/Source/WTF/ChangeLog 2016-04-22 01:18:00 UTC (rev 199858)
@@ -1,3 +1,68 @@
+2016-04-21 Babak Shafiei <bshaf...@apple.com>
+
+ Merge r199762.
+
+ 2016-04-19 Michael Saboff <msab...@apple.com>
+
+ iTunes crashing _javascript_Core.dll
+ https://bugs.webkit.org/show_bug.cgi?id=156647
+
+ Reviewed by Filip Pizlo.
+
+ If a thread was created without using the WTF thread apis and that thread uses
+ a _javascript_ VM and that thread exits with the VM still around, JSC won't know
+ that the thread has exited. Currently, we use ThreadSpecificThreadExit() to
+ clean up any thread specific keys. Cleaning up these keys is how JSC is
+ notified of a thread exit. We only call ThreadSpecificThreadExit() from
+ wtfThreadEntryPoint() when the thread entry point function returns.
+ This mechanism was put in place for Windows because we layer the WTF::ThreadSpecific
+ functionality on top of TLS (Thread Local Storage), but TLS doesn't have
+ a thread exiting callback the way that pthread_create_key does.
+
+ The fix is to change from using TLS to using FLS (Fiber Local Storage). Although
+ Windows allows multiple fibers per thread, WebKit is not designed to work with a
+ multiple fibers per thread. When there is only one fiber per thread, FLS works just
+ like TLS, but it has the destroy callback.
+
+ I restructured the Windows version of WTF::ThreadSpecific to be almost the same
+ as the pthread version. Added THREAD_SPECIFIC_CALL to set the correct
+ calling convenction for Windows 32 bit.
+
+ * wtf/ThreadSpecific.h:
+ (WTF::threadSpecificKeyCreate):
+ (WTF::threadSpecificKeyDelete):
+ (WTF::threadSpecificSet):
+ (WTF::threadSpecificGet):
+ (WTF::ThreadSpecific<T>::ThreadSpecific):
+ (WTF::ThreadSpecific<T>::~ThreadSpecific):
+ (WTF::ThreadSpecific<T>::get):
+ (WTF::ThreadSpecific<T>::set):
+ (WTF::ThreadSpecific<T>::destroy):
+ Restructured to use FLS. Renamed TLS* to FLS*.
+
+ * wtf/ThreadSpecificWin.cpp:
+ (WTF::flsKeyCount):
+ (WTF::flsKeys):
+ Renamed from tlsKey*() to flsKey*().
+
+ (WTF::destructorsList): Deleted.
+ (WTF::destructorsMutex): Deleted.
+ (WTF::PlatformThreadSpecificKey::PlatformThreadSpecificKey): Deleted.
+ (WTF::PlatformThreadSpecificKey::~PlatformThreadSpecificKey): Deleted.
+ (WTF::PlatformThreadSpecificKey::setValue): Deleted.
+ (WTF::PlatformThreadSpecificKey::value): Deleted.
+ (WTF::PlatformThreadSpecificKey::callDestructor): Deleted.
+ (WTF::tlsKeyCount): Deleted.
+ (WTF::tlsKeys): Deleted.
+ (WTF::threadSpecificKeyCreate): Deleted.
+ (WTF::threadSpecificKeyDelete): Deleted.
+ (WTF::threadSpecificSet): Deleted.
+ (WTF::threadSpecificGet): Deleted.
+ (WTF::ThreadSpecificThreadExit): Deleted.
+
+ * wtf/ThreadingWin.cpp:
+ (WTF::wtfThreadEntryPoint): Eliminated call to ThreadSpecificThreadExit.
+
2016-02-26 Tim Horton <timothy_hor...@apple.com>
Fix the Mavericks build.
Modified: branches/safari-601.6.16-branch/Source/WTF/wtf/ThreadSpecific.h (199857 => 199858)
--- branches/safari-601.6.16-branch/Source/WTF/wtf/ThreadSpecific.h 2016-04-22 01:15:01 UTC (rev 199857)
+++ branches/safari-601.6.16-branch/Source/WTF/wtf/ThreadSpecific.h 2016-04-22 01:18:00 UTC (rev 199858)
@@ -53,10 +53,10 @@
namespace WTF {
-#if OS(WINDOWS)
-// ThreadSpecificThreadExit should be called each time when a thread is detached.
-// This is done automatically for threads created with WTF::createThread.
-void ThreadSpecificThreadExit();
+#if OS(WINDOWS) && CPU(X86)
+#define THREAD_SPECIFIC_CALL __stdcall
+#else
+#define THREAD_SPECIFIC_CALL
#endif
template<typename T> class ThreadSpecific {
@@ -73,10 +73,6 @@
#endif
private:
-#if OS(WINDOWS)
- friend void ThreadSpecificThreadExit();
-#endif
-
// Not implemented. It's technically possible to destroy a thread specific key, but one would need
// to make sure that all values have been destroyed already (usually, that all threads that used it
// have exited). It's unlikely that any user of this call will be in that situation - and having
@@ -85,7 +81,7 @@
T* get();
void set(T*);
- void static destroy(void* ptr);
+ void static THREAD_SPECIFIC_CALL destroy(void* ptr);
struct Data {
WTF_MAKE_NONCOPYABLE(Data);
@@ -94,9 +90,6 @@
T* value;
ThreadSpecific<T>* owner;
-#if OS(WINDOWS)
- void (*destructor)(void*);
-#endif
};
#if USE(PTHREADS)
@@ -158,47 +151,64 @@
#elif OS(WINDOWS)
-// The maximum number of TLS keys that can be created. For simplification, we assume that:
+// The maximum number of FLS keys that can be created. For simplification, we assume that:
// 1) Once the instance of ThreadSpecific<> is created, it will not be destructed until the program dies.
// 2) We do not need to hold many instances of ThreadSpecific<> data. This fixed number should be far enough.
-const int kMaxTlsKeySize = 256;
+const int kMaxFlsKeySize = 128;
-WTF_EXPORT_PRIVATE long& tlsKeyCount();
-WTF_EXPORT_PRIVATE DWORD* tlsKeys();
+WTF_EXPORT_PRIVATE long& flsKeyCount();
+WTF_EXPORT_PRIVATE DWORD* flsKeys();
-class PlatformThreadSpecificKey;
-typedef PlatformThreadSpecificKey* ThreadSpecificKey;
+typedef DWORD ThreadSpecificKey;
-WTF_EXPORT_PRIVATE void threadSpecificKeyCreate(ThreadSpecificKey*, void (*)(void *));
-WTF_EXPORT_PRIVATE void threadSpecificKeyDelete(ThreadSpecificKey);
-WTF_EXPORT_PRIVATE void threadSpecificSet(ThreadSpecificKey, void*);
-WTF_EXPORT_PRIVATE void* threadSpecificGet(ThreadSpecificKey);
+inline void threadSpecificKeyCreate(ThreadSpecificKey* key, void (THREAD_SPECIFIC_CALL *destructor)(void *))
+{
+ DWORD flsKey = FlsAlloc(destructor);
+ if (flsKey == FLS_OUT_OF_INDEXES)
+ CRASH();
+ *key = flsKey;
+}
+
+inline void threadSpecificKeyDelete(ThreadSpecificKey key)
+{
+ FlsFree(key);
+}
+
+inline void threadSpecificSet(ThreadSpecificKey key, void* data)
+{
+ FlsSetValue(key, data);
+}
+
+inline void* threadSpecificGet(ThreadSpecificKey key)
+{
+ return FlsGetValue(key);
+}
+
template<typename T>
inline ThreadSpecific<T>::ThreadSpecific()
: m_index(-1)
{
- DWORD tlsKey = TlsAlloc();
- if (tlsKey == TLS_OUT_OF_INDEXES)
+ DWORD flsKey = FlsAlloc(destroy);
+ if (flsKey == FLS_OUT_OF_INDEXES)
CRASH();
- m_index = InterlockedIncrement(&tlsKeyCount()) - 1;
- if (m_index >= kMaxTlsKeySize)
+ m_index = InterlockedIncrement(&flsKeyCount()) - 1;
+ if (m_index >= kMaxFlsKeySize)
CRASH();
- tlsKeys()[m_index] = tlsKey;
+ flsKeys()[m_index] = flsKey;
}
template<typename T>
inline ThreadSpecific<T>::~ThreadSpecific()
{
- // Does not invoke destructor functions. They will be called from ThreadSpecificThreadExit when the thread is detached.
- TlsFree(tlsKeys()[m_index]);
+ FlsFree(flsKeys()[m_index]);
}
template<typename T>
inline T* ThreadSpecific<T>::get()
{
- Data* data = ""
+ Data* data = ""
return data ? data->value : 0;
}
@@ -207,8 +217,7 @@
{
ASSERT(!get());
Data* data = "" Data(ptr, this);
- data->destructor = &ThreadSpecific<T>::destroy;
- TlsSetValue(tlsKeys()[m_index], data);
+ FlsSetValue(flsKeys()[m_index], data);
}
#else
@@ -216,7 +225,7 @@
#endif
template<typename T>
-inline void ThreadSpecific<T>::destroy(void* ptr)
+inline void THREAD_SPECIFIC_CALL ThreadSpecific<T>::destroy(void* ptr)
{
Data* data = ""
@@ -232,7 +241,7 @@
#if USE(PTHREADS)
pthread_setspecific(data->owner->m_key, 0);
#elif OS(WINDOWS)
- TlsSetValue(tlsKeys()[data->owner->m_index], 0);
+ FlsSetValue(flsKeys()[data->owner->m_index], 0);
#else
#error ThreadSpecific is not implemented for this platform.
#endif
Modified: branches/safari-601.6.16-branch/Source/WTF/wtf/ThreadSpecificWin.cpp (199857 => 199858)
--- branches/safari-601.6.16-branch/Source/WTF/wtf/ThreadSpecificWin.cpp 2016-04-22 01:15:01 UTC (rev 199857)
+++ branches/safari-601.6.16-branch/Source/WTF/wtf/ThreadSpecificWin.cpp 2016-04-22 01:18:00 UTC (rev 199858)
@@ -24,117 +24,22 @@
#if OS(WINDOWS)
-#include "StdLibExtras.h"
-#include "ThreadingPrimitives.h"
-#include <wtf/DoublyLinkedList.h>
-
#if !USE(PTHREADS)
namespace WTF {
-static DoublyLinkedList<PlatformThreadSpecificKey>& destructorsList()
+long& flsKeyCount()
{
- static DoublyLinkedList<PlatformThreadSpecificKey> staticList;
- return staticList;
-}
-
-static Mutex& destructorsMutex()
-{
- static Mutex staticMutex;
- return staticMutex;
-}
-
-class PlatformThreadSpecificKey : public DoublyLinkedListNode<PlatformThreadSpecificKey> {
-public:
- friend class DoublyLinkedListNode<PlatformThreadSpecificKey>;
-
- PlatformThreadSpecificKey(void (*destructor)(void *))
- : m_destructor(destructor)
- {
- m_tlsKey = TlsAlloc();
- if (m_tlsKey == TLS_OUT_OF_INDEXES)
- CRASH();
- }
-
- ~PlatformThreadSpecificKey()
- {
- TlsFree(m_tlsKey);
- }
-
- void setValue(void* data) { TlsSetValue(m_tlsKey, data); }
- void* value() { return TlsGetValue(m_tlsKey); }
-
- void callDestructor()
- {
- if (void* data = ""
- m_destructor(data);
- }
-
-private:
- void (*m_destructor)(void *);
- DWORD m_tlsKey;
- PlatformThreadSpecificKey* m_prev;
- PlatformThreadSpecificKey* m_next;
-};
-
-long& tlsKeyCount()
-{
static long count;
return count;
}
-DWORD* tlsKeys()
+DWORD* flsKeys()
{
- static DWORD keys[kMaxTlsKeySize];
+ static DWORD keys[kMaxFlsKeySize];
return keys;
}
-void threadSpecificKeyCreate(ThreadSpecificKey* key, void (*destructor)(void *))
-{
- // Use the original malloc() instead of fastMalloc() to use this function in FastMalloc code.
- *key = static_cast<PlatformThreadSpecificKey*>(::malloc(sizeof(PlatformThreadSpecificKey)));
- new (*key) PlatformThreadSpecificKey(destructor);
-
- MutexLocker locker(destructorsMutex());
- destructorsList().push(*key);
-}
-
-void threadSpecificKeyDelete(ThreadSpecificKey key)
-{
- MutexLocker locker(destructorsMutex());
- destructorsList().remove(key);
- key->~PlatformThreadSpecificKey();
- ::free(key);
-}
-
-void threadSpecificSet(ThreadSpecificKey key, void* data)
-{
- key->setValue(data);
-}
-
-void* threadSpecificGet(ThreadSpecificKey key)
-{
- return key->value();
-}
-
-void ThreadSpecificThreadExit()
-{
- for (long i = 0; i < tlsKeyCount(); i++) {
- // The layout of ThreadSpecific<T>::Data does not depend on T. So we are safe to do the static cast to ThreadSpecific<int> in order to access its data member.
- ThreadSpecific<int>::Data* data = ""
- if (data)
- data->destructor(data);
- }
-
- MutexLocker locker(destructorsMutex());
- PlatformThreadSpecificKey* key = destructorsList().head();
- while (key) {
- PlatformThreadSpecificKey* nextKey = key->next();
- key->callDestructor();
- key = nextKey;
- }
-}
-
} // namespace WTF
#endif // !USE(PTHREADS)
Modified: branches/safari-601.6.16-branch/Source/WTF/wtf/ThreadingWin.cpp (199857 => 199858)
--- branches/safari-601.6.16-branch/Source/WTF/wtf/ThreadingWin.cpp 2016-04-22 01:15:01 UTC (rev 199857)
+++ branches/safari-601.6.16-branch/Source/WTF/wtf/ThreadingWin.cpp 2016-04-22 01:18:00 UTC (rev 199858)
@@ -102,10 +102,6 @@
#include <wtf/RandomNumberSeed.h>
#include <wtf/WTFThreadData.h>
-#if !USE(PTHREADS) && OS(WINDOWS)
-#include "ThreadSpecific.h"
-#endif
-
#if HAVE(ERRNO_H)
#include <errno.h>
#endif
@@ -200,11 +196,6 @@
std::unique_ptr<ThreadFunctionInvocation> invocation(static_cast<ThreadFunctionInvocation*>(param));
invocation->function(invocation->data);
-#if !USE(PTHREADS) && OS(WINDOWS)
- // Do the TLS cleanup.
- ThreadSpecificThreadExit();
-#endif
-
return 0;
}