| 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
|
|
|