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)) { |
haraken
2017/01/18 05:29:42
Can we just use if(!offThreadPtr) ? I don't fully
haraken
2017/01/18 05:29:42
Not related to this CL but we might want to remove
Charlie Harrison
2017/01/18 16:29:55
Acknowledged, though I wonder if that would lead t
Charlie Harrison
2017/01/18 16:29:55
We use pointer indirection here because ptr can po
haraken
2017/01/19 01:04:38
Thread initialization is already heavy, so I don't
|
+ *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> |