diff options
author | Michael Spencer <bigcheesegs@gmail.com> | 2025-04-30 19:14:15 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-04-30 19:14:15 -0700 |
commit | 07deaf8464f29c34ff46983450a7412a36adcb7b (patch) | |
tree | 01f3d1b5782f81c9f4e4d9c23122b6ffc5bab71e /llvm/unittests/Support/ProgramStackTest.cpp | |
parent | 46838e1a093510529185408349fe192c09ea42f0 (diff) | |
download | llvm-07deaf8464f29c34ff46983450a7412a36adcb7b.zip llvm-07deaf8464f29c34ff46983450a7412a36adcb7b.tar.gz llvm-07deaf8464f29c34ff46983450a7412a36adcb7b.tar.bz2 |
Reland: [llvm][clang] Allocate a new stack instead of spawning a new thread to get more stack space (#136046)
Reland https://github.com/llvm/llvm-project/pull/133173
Clang spawns a new thread to avoid running out of stack space. This can
make debugging and performance analysis more difficult as how the
threads are connected is difficult to recover.
This patch introduces `runOnNewStack` and applies it in Clang. On
platforms that have good support for it this allocates a new stack and
moves to it using assembly. Doing split stacks like this actually runs
on most platforms, but many debuggers and unwinders reject the large or
backwards stack offsets that occur. Apple platforms and tools are known
to support this, so this only enables it there for now.
Diffstat (limited to 'llvm/unittests/Support/ProgramStackTest.cpp')
-rw-r--r-- | llvm/unittests/Support/ProgramStackTest.cpp | 35 |
1 files changed, 35 insertions, 0 deletions
diff --git a/llvm/unittests/Support/ProgramStackTest.cpp b/llvm/unittests/Support/ProgramStackTest.cpp new file mode 100644 index 0000000..31dfb3b --- /dev/null +++ b/llvm/unittests/Support/ProgramStackTest.cpp @@ -0,0 +1,35 @@ +//===- unittest/Support/ProgramStackTest.cpp ------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "llvm/Support/ProgramStack.h" +#include "llvm/Support/Process.h" +#include "gtest/gtest.h" + +using namespace llvm; + +static uintptr_t func(int &A) { + A = 7; + return getStackPointer(); +} + +static void func2(int &A) { + A = 5; +} + +TEST(ProgramStackTest, runOnNewStack) { + int A = 0; + uintptr_t Stack = runOnNewStack(0, function_ref<uintptr_t(int &)>(func), A); + EXPECT_EQ(A, 7); + intptr_t StackDiff = (intptr_t)llvm::getStackPointer() - (intptr_t)Stack; + size_t StackDistance = (size_t)std::abs(StackDiff); + // Page size is used as it's large enough to guarantee were not on the same + // stack but not too large to cause spurious failures. + EXPECT_GT(StackDistance, llvm::sys::Process::getPageSizeEstimate()); + runOnNewStack(0, function_ref<void(int &)>(func2), A); + EXPECT_EQ(A, 5); +} |