Commit ac641d44 authored by peria@chromium.org's avatar peria@chromium.org

Set the stack limit size based on estimated sizes.

To check if the stack memory has enough room for recursive
calls, we tried to allocate a large object and assumed the size.
This CL estimate the real thread stack limit using APIs.
On some platforms where such APIs do not work correctly,
we set the limit using the old algorithm.

On ASAN build, we disable it because sanitizer creates and uses "fake stacks".

---
This CL is re-land of https://codereview.chromium.org/910663002/, https://codereview.chromium.org/927213002/, and https://codereview.chromium.org/943293002/.

Test was changed in another CL.


BUG=420515, 457982

Review URL: https://codereview.chromium.org/955563002

git-svn-id: svn://svn.chromium.org/blink/trunk@190738 bbb929c8-8fbe-4397-9dbb-9b2b20218538
parent 48a8ebe7
......@@ -29,7 +29,17 @@ NEVER_INLINE static uintptr_t currentStackFrameBaseOnCallee(const char* dummy)
void StackFrameDepth::configureLimit()
{
// Allocate a large object in stack and query stack frame pointer after it.
static const int kStackRoomSize = 1024;
size_t stackSize = getUnderestimatedStackSize();
if (stackSize) {
size_t stackBase = reinterpret_cast<size_t>(getStackStart());
m_stackFrameLimit = stackBase - stackSize + kStackRoomSize;
return;
}
// Fallback version
// Allocate a 32KB object on stack and query stack frame base after it.
char dummy[kSafeStackFrameSize];
m_stackFrameLimit = currentStackFrameBaseOnCallee(dummy);
......@@ -39,14 +49,45 @@ void StackFrameDepth::configureLimit()
size_t StackFrameDepth::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)
return 0;
#endif
// FIXME: On Mac OSX and Linux, this method cannot estimate stack size
// correctly for the main thread.
#if defined(__GLIBC__) || OS(ANDROID) || OS(FREEBSD)
// We cannot get the stack size in these platforms because
// pthread_getattr_np() can fail for the main thread.
// This is OK because ThreadState::current() doesn't use the stack size
// in these platforms.
// pthread_getattr_np() can fail if the thread is not invoked by
// pthread_create() (e.g., the main thread of webkit_unit_tests).
// In this case, this method returns 0 and the caller must handle it.
pthread_attr_t attr;
int error;
#if OS(FREEBSD)
pthread_attr_init(&attr);
error = pthread_attr_get_np(pthread_self(), &attr);
#else
error = pthread_getattr_np(pthread_self(), &attr);
#endif
if (!error) {
void* base;
size_t size;
error = pthread_attr_getstack(&attr, &base, &size);
RELEASE_ASSERT(!error);
pthread_attr_destroy(&attr);
return size;
}
#if OS(FREEBSD)
pthread_attr_destroy(&attr);
#endif
return 0;
#elif OS(MACOSX)
return pthread_get_stacksize_np(pthread_self());
// FIXME: pthread_get_stacksize_np() returns shorter size than actual stack
// size for the main thread on Mavericks(10.9).
return 0;
#elif OS(WIN) && COMPILER(MSVC)
// On Windows stack limits for the current thread are available in
// the thread information block (TIB). Its fields can be accessed through
......@@ -57,6 +98,7 @@ size_t StackFrameDepth::getUnderestimatedStackSize()
return __readfsdword(offsetof(NT_TIB, StackBase)) - __readfsdword(offsetof(NT_TIB, StackLimit));
#endif
#else
#error "Stack frame size estimation not supported on this platform."
return 0;
#endif
}
......
......@@ -255,7 +255,9 @@ ThreadState::ThreadState()
if (isMainThread()) {
s_mainThreadStackStart = reinterpret_cast<uintptr_t>(m_startOfStack) - sizeof(void*);
s_mainThreadUnderestimatedStackSize = StackFrameDepth::getUnderestimatedStackSize() - sizeof(void*);
size_t underestimatedStackSize = StackFrameDepth::getUnderestimatedStackSize();
if (underestimatedStackSize > sizeof(void*))
s_mainThreadUnderestimatedStackSize = underestimatedStackSize - sizeof(void*);
}
for (int heapIndex = 0; heapIndex < LargeObjectHeapIndex; heapIndex++)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment