Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(294)

Unified Diff: third_party/WebKit/Source/wtf/WTFThreadData.cpp

Issue 2623273007: Fast path for ThreadSpecific for main thread on TLS-slow platforms (Closed)
Patch Set: [WIP] Fast path for currentThread() for main thread on TLS-slow platforms Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: third_party/WebKit/Source/wtf/WTFThreadData.cpp
diff --git a/third_party/WebKit/Source/wtf/WTFThreadData.cpp b/third_party/WebKit/Source/wtf/WTFThreadData.cpp
index 33abb350ad6961e7e70fada3cb27683297d177f4..802c761d90190f156b7ec023bdc0290112ddc8de 100644
--- a/third_party/WebKit/Source/wtf/WTFThreadData.cpp
+++ b/third_party/WebKit/Source/wtf/WTFThreadData.cpp
@@ -26,18 +26,112 @@
#include "wtf/WTFThreadData.h"
+#include "wtf/PtrUtil.h"
+#include "wtf/StackUtil.h"
#include "wtf/text/AtomicStringTable.h"
#include "wtf/text/TextCodecICU.h"
namespace WTF {
+uintptr_t WTFThreadData::s_mainThreadStackStart = 0;
+uintptr_t WTFThreadData::s_mainThreadUnderestimatedStackSize = 0;
+uint8_t WTFThreadData::s_mainThreadDataStorage[sizeof(WTFThreadData)];
+
ThreadSpecific<WTFThreadData>* WTFThreadData::staticData;
-WTFThreadData::WTFThreadData()
- : m_atomicStringTable(new AtomicStringTable),
- m_cachedConverterICU(new ICUConverterWrapper),
- m_threadId(internal::currentThreadSyscall()) {}
+WTFThreadData::WTFThreadData(ThreadType type)
+ : m_threadId(internal::currentThreadSyscall()) {
+ // Static globals must be initialized before the AtomicStringTable, but after
+ // |this| is initialized. Note that we call threadStackSize() from
+ // getUnderestimatedStackSize() on MSVC.
+ if (type == MainThread) {
+ s_mainThreadStackStart =
+ reinterpret_cast<uintptr_t>(WTF::getStackStart()) - sizeof(void*);
+ size_t underestimatedStackSize = getUnderestimatedStackSize();
+ if (underestimatedStackSize > sizeof(void*)) {
+ s_mainThreadUnderestimatedStackSize =
+ underestimatedStackSize - sizeof(void*);
+ }
haraken 2017/01/16 04:42:30 Can we do this initialization in WTFThreadData::in
Charlie Harrison 2017/01/18 01:49:48 This is all gone.
+ }
+ m_atomicStringTable = makeUnique<AtomicStringTable>();
+ m_cachedConverterICU = makeUnique<ICUConverterWrapper>();
+}
WTFThreadData::~WTFThreadData() {}
+#if OS(WIN) && COMPILER(MSVC)
+size_t WTFThreadData::threadStackSize() {
haraken 2017/01/16 04:42:30 I want to put this method in the same file as getU
Charlie Harrison 2017/01/18 01:49:48 Done.
+ if (m_threadStackSize)
+ return m_threadStackSize;
+
+ // Notice that we cannot use the TIB's StackLimit for the stack end, as it
+ // tracks the end of the committed range. We're after the end of the reserved
+ // stack area (most of which will be uncommitted, most times.)
+ MEMORY_BASIC_INFORMATION stackInfo;
+ memset(&stackInfo, 0, sizeof(MEMORY_BASIC_INFORMATION));
+ size_t resultSize =
+ VirtualQuery(&stackInfo, &stackInfo, sizeof(MEMORY_BASIC_INFORMATION));
+ DCHECK_GE(resultSize, sizeof(MEMORY_BASIC_INFORMATION));
+ uint8_t* stackEnd = reinterpret_cast<uint8_t*>(stackInfo.AllocationBase);
+
+ uint8_t* stackStart = reinterpret_cast<uint8_t*>(WTF::getStackStart());
+ RELEASE_ASSERT(stackStart && stackStart > stackEnd);
+ m_threadStackSize = static_cast<size_t>(stackStart - stackEnd);
+ // When the third last page of the reserved stack is accessed as a
+ // guard page, the second last page will be committed (along with removing
+ // the guard bit on the third last) _and_ a stack overflow exception
+ // is raised.
+ //
+ // We have zero interest in running into stack overflow exceptions while
+ // marking objects, so simply consider the last three pages + one above
+ // as off-limits and adjust the reported stack size accordingly.
+ //
+ // http://blogs.msdn.com/b/satyem/archive/2012/08/13/thread-s-stack-memory-management.aspx
+ // explains the details.
+ RELEASE_ASSERT(m_threadStackSize > 4 * 0x1000);
+ m_threadStackSize -= 4 * 0x1000;
+ return m_threadStackSize;
+}
+#endif
+
+void WTFThreadData::initialize() {
+ DCHECK(!WTFThreadData::staticData);
+ WTFThreadData::staticData = new ThreadSpecific<WTFThreadData>;
+ new (s_mainThreadDataStorage) WTFThreadData(MainThread);
+}
+
+WTFThreadData& WTFThreadData::current() {
+#if defined(__GLIBC__) || OS(ANDROID) || OS(FREEBSD)
+ return **WTFThreadData::staticData;
+#else
+ // TLS lookup is slow.
+ if (LIKELY(stackBasedIsMainThread()))
+ return mainThreadData();
+ return **WTFThreadData::staticData;
+#endif
+}
+
+bool WTFThreadData::isMainThread() {
+ return current() == mainThreadData();
+}
+
+WTFThreadData& WTFThreadData::mainThreadData() {
+ return *(reinterpret_cast<WTFThreadData*>(s_mainThreadDataStorage));
+}
+
+bool WTFThreadData::stackBasedIsMainThread() {
+ uintptr_t dummy;
+ uintptr_t addressDiff =
+ s_mainThreadStackStart - reinterpret_cast<uintptr_t>(&dummy);
+ // This is a fast way to judge if we are in the main thread.
+ // If |&dummy| is within |s_mainThreadUnderestimatedStackSize| byte from
+ // the stack start of the main thread, we judge that we are in
+ // the main thread.
+ return addressDiff < s_mainThreadUnderestimatedStackSize;
+}
+
+bool operator==(const WTFThreadData& data1, const WTFThreadData& data2) {
+ return data1.threadId() == data2.threadId();
+}
+
} // namespace WTF

Powered by Google App Engine
This is Rietveld 408576698