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

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

Issue 2623273007: Fast path for ThreadSpecific for main thread on TLS-slow platforms (Closed)
Patch Set: haraken revieqw 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
« no previous file with comments | « third_party/WebKit/Source/wtf/StackUtil.h ('k') | third_party/WebKit/Source/wtf/ThreadSpecific.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: third_party/WebKit/Source/wtf/StackUtil.cpp
diff --git a/third_party/WebKit/Source/platform/heap/StackFrameDepth.cpp b/third_party/WebKit/Source/wtf/StackUtil.cpp
similarity index 64%
copy from third_party/WebKit/Source/platform/heap/StackFrameDepth.cpp
copy to third_party/WebKit/Source/wtf/StackUtil.cpp
index 1d164f510a36de4ecb3328e6c80065f4913eca5d..f9e51b866b60fe64317289f43ee7783a86412b8f 100644
--- a/third_party/WebKit/Source/platform/heap/StackFrameDepth.cpp
+++ b/third_party/WebKit/Source/wtf/StackUtil.cpp
@@ -1,10 +1,12 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
+// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "platform/heap/StackFrameDepth.h"
+#include "wtf/StackUtil.h"
-#include "public/platform/Platform.h"
+#include "wtf/Assertions.h"
+#include "wtf/Threading.h"
+#include "wtf/WTFThreadData.h"
#if OS(WIN)
#include <stddef.h>
@@ -14,51 +16,9 @@
extern "C" void* __libc_stack_end; // NOLINT
#endif
-namespace blink {
+namespace WTF {
-static const char* s_avoidOptimization = nullptr;
-
-// NEVER_INLINE ensures that |dummy| array on configureLimit() is not optimized
-// away, and the stack frame base register is adjusted |kSafeStackFrameSize|.
-NEVER_INLINE static uintptr_t currentStackFrameBaseOnCallee(const char* dummy) {
- s_avoidOptimization = dummy;
- return StackFrameDepth::currentStackFrame();
-}
-
-uintptr_t StackFrameDepth::getFallbackStackLimit() {
- // Allocate an |kSafeStackFrameSize|-sized object on stack and query
- // stack frame base after it.
- char dummy[kSafeStackFrameSize];
-
- // Check that the stack frame can be used.
- dummy[sizeof(dummy) - 1] = 0;
- return currentStackFrameBaseOnCallee(dummy);
-}
-
-void StackFrameDepth::enableStackLimit() {
- // All supported platforms will currently return a non-zero estimate,
- // except if ASan is enabled.
- size_t stackSize = getUnderestimatedStackSize();
- if (!stackSize) {
- m_stackFrameLimit = getFallbackStackLimit();
- return;
- }
-
- static const int kStackRoomSize = 1024;
-
- Address stackBase = reinterpret_cast<Address>(getStackStart());
- RELEASE_ASSERT(stackSize > static_cast<const size_t>(kStackRoomSize));
- size_t stackRoom = stackSize - kStackRoomSize;
- RELEASE_ASSERT(stackBase > reinterpret_cast<Address>(stackRoom));
- m_stackFrameLimit = reinterpret_cast<uintptr_t>(stackBase - stackRoom);
-
- // If current stack use is already exceeding estimated limit, mark as
- // disabled.
- if (!isSafeToRecurse())
- disableStackLimit();
-}
-
-size_t StackFrameDepth::getUnderestimatedStackSize() {
+size_t getUnderestimatedStackSize() {
// FIXME: ASAN bot uses a fake stack as a thread stack frame,
// and its size is different from the value which APIs tells us.
#if defined(ADDRESS_SANITIZER)
@@ -127,14 +87,14 @@ size_t StackFrameDepth::getUnderestimatedStackSize() {
}
return pthread_get_stacksize_np(pthread_self());
#elif OS(WIN) && COMPILER(MSVC)
- return ThreadState::current()->threadStackSize();
+ return WTFThreadData::threadStackSize();
#else
#error "Stack frame size estimation not supported on this platform."
return 0;
#endif
}
-void* StackFrameDepth::getStackStart() {
+void* getStackStart() {
#if defined(__GLIBC__) || OS(ANDROID) || OS(FREEBSD)
pthread_attr_t attr;
int error;
@@ -162,7 +122,7 @@ void* StackFrameDepth::getStackStart() {
// See https://code.google.com/p/nativeclient/issues/detail?id=3431.
return __libc_stack_end;
#else
- ASSERT_NOT_REACHED();
+ NOTREACHED();
return nullptr;
#endif
#elif OS(MACOSX)
@@ -181,4 +141,49 @@ void* StackFrameDepth::getStackStart() {
#endif
}
-} // namespace blink
+namespace internal {
+
+uintptr_t mainThreadUnderestimatedStackSize() {
+ size_t underestimatedStackSize = getUnderestimatedStackSize();
+ // See comment in mayNotBeMainThread as to why we subtract here.
+ if (underestimatedStackSize > sizeof(void*)) {
+ underestimatedStackSize = underestimatedStackSize - sizeof(void*);
+ }
+ return underestimatedStackSize;
+}
+
+#if OS(WIN) && COMPILER(MSVC)
+size_t threadStackSize() {
+ // Notice that we cannot use the TIB's StackLimit for the stack end, as i
+ // 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);
+ size_t s_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(s_threadStackSize > 4 * 0x1000);
+ s_threadStackSize -= 4 * 0x1000;
+ return s_threadStackSize;
+}
+#endif
+
+} // namespace internal
+
+} // namespace WTF
« no previous file with comments | « third_party/WebKit/Source/wtf/StackUtil.h ('k') | third_party/WebKit/Source/wtf/ThreadSpecific.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698