| Index: third_party/WebKit/Source/wtf/ThreadSpecific.h
|
| diff --git a/third_party/WebKit/Source/wtf/ThreadSpecific.h b/third_party/WebKit/Source/wtf/ThreadSpecific.h
|
| index 377a82f4e24e405aafb5c707a672de58ddc39ce6..5b197de00b5e533550547a6575b3cc4d7f3dfa1a 100644
|
| --- a/third_party/WebKit/Source/wtf/ThreadSpecific.h
|
| +++ b/third_party/WebKit/Source/wtf/ThreadSpecific.h
|
| @@ -44,6 +44,7 @@
|
|
|
| #include "wtf/Allocator.h"
|
| #include "wtf/Noncopyable.h"
|
| +#include "wtf/StackUtil.h"
|
| #include "wtf/StdLibExtras.h"
|
| #include "wtf/WTF.h"
|
| #include "wtf/WTFExport.h"
|
| @@ -113,6 +114,8 @@ class ThreadSpecific {
|
| #elif OS(WIN)
|
| int m_index;
|
| #endif
|
| + // This member must only be accessed or modified on the main thread.
|
| + T* m_mainThreadStorage = nullptr;
|
| };
|
|
|
| #if OS(POSIX)
|
| @@ -261,17 +264,29 @@ inline bool ThreadSpecific<T>::isSet() {
|
|
|
| template <typename T>
|
| inline ThreadSpecific<T>::operator T*() {
|
| - T* ptr = static_cast<T*>(get());
|
| - if (!ptr) {
|
| - // Set up thread-specific value's memory pointer before invoking
|
| - // constructor, in case any function it calls
|
| - // needs to access the value, to avoid recursion.
|
| - ptr = static_cast<T*>(Partitions::fastZeroedMalloc(
|
| + T* offThreadPtr;
|
| +#if defined(__GLIBC__) || OS(ANDROID) || OS(FREEBSD)
|
| + // TLS is fast on these platforms.
|
| + // TODO(csharrison): Qualify this statement for Android.
|
| + T** ptr = &offThreadPtr;
|
| + offThreadPtr = static_cast<T*>(get());
|
| +#else
|
| + T** ptr = &m_mainThreadStorage;
|
| + if (UNLIKELY(internal::mayNotBeMainThread())) {
|
| + offThreadPtr = static_cast<T*>(get());
|
| + ptr = &offThreadPtr;
|
| + }
|
| +#endif
|
| + // Set up thread-specific value's memory pointer before invoking constructor,
|
| + // in case any function it calls needs to access the value, to avoid
|
| + // recursion.
|
| + if (UNLIKELY(!*ptr)) {
|
| + *ptr = static_cast<T*>(Partitions::fastZeroedMalloc(
|
| sizeof(T), WTF_HEAP_PROFILER_TYPE_NAME(T)));
|
| - set(ptr);
|
| - new (NotNull, ptr) T;
|
| + set(*ptr);
|
| + new (NotNull, *ptr) T;
|
| }
|
| - return ptr;
|
| + return *ptr;
|
| }
|
|
|
| template <typename T>
|
|
|