[llvm][clang] Revert split stacks implementation from runOnNewStack (#181743)

This was potentially causing Clang to emit out of stack space warnings
in rare cases, so I'm reverting it until I can verify the issue. This
keeps the API change as that's known not to be the issue.
This commit is contained in:
Michael Spencer 2026-02-16 14:38:40 -07:00 committed by GitHub
parent eb85fc740c
commit 227d8d33c6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 1 additions and 85 deletions

View File

@ -12,17 +12,6 @@
#include "llvm/ADT/STLFunctionalExtras.h"
#include "llvm/Support/Compiler.h"
// LLVM_HAS_SPLIT_STACKS is exposed in the header because CrashRecoveryContext
// needs to know if it's running on another thread or not.
//
// Currently only Apple AArch64 is known to support split stacks in the debugger
// and other tooling.
#if defined(__APPLE__) && defined(__MACH__) && defined(__aarch64__) && \
__has_extension(gnu_asm)
# define LLVM_HAS_SPLIT_STACKS
# define LLVM_HAS_SPLIT_STACKS_AARCH64
#endif
namespace llvm {
/// \returns an address close to the current value of the stack pointer.

View File

@ -526,10 +526,5 @@ bool CrashRecoveryContext::RunSafelyOnThread(function_ref<void()> Fn,
bool CrashRecoveryContext::RunSafelyOnNewStack(function_ref<void()> Fn,
unsigned RequestedStackSize) {
#ifdef LLVM_HAS_SPLIT_STACKS
return runOnNewStack(RequestedStackSize,
function_ref<bool()>([&]() { return RunSafely(Fn); }));
#else
return RunSafelyOnThread(Fn, RequestedStackSize);
#endif
}

View File

@ -18,9 +18,7 @@
# include <intrin.h> // for _AddressOfReturnAddress
#endif
#ifndef LLVM_HAS_SPLIT_STACKS
# include "llvm/Support/thread.h"
#endif
#include "llvm/Support/thread.h"
using namespace llvm;
@ -54,74 +52,8 @@ unsigned llvm::getDefaultStackSize() {
#endif
}
// Not an anonymous namespace to avoid warning about undefined local function.
namespace llvm {
#ifdef LLVM_HAS_SPLIT_STACKS_AARCH64
void runOnNewStackImpl(void *Stack, void (*Fn)(void *), void *Ctx) __asm__(
"_ZN4llvm17runOnNewStackImplEPvPFvS0_ES0_");
// This can't use naked functions because there is no way to know if cfi
// directives are being emitted or not.
//
// When adding new platforms it may be better to move to a .S file with macros
// for dealing with platform differences.
__asm__ (
".globl _ZN4llvm17runOnNewStackImplEPvPFvS0_ES0_\n\t"
".p2align 2\n\t"
"_ZN4llvm17runOnNewStackImplEPvPFvS0_ES0_:\n\t"
".cfi_startproc\n\t"
"mov x16, sp\n\t"
"sub x0, x0, #0x20\n\t" // subtract space from stack
"stp xzr, x16, [x0, #0x00]\n\t" // save old sp
"stp x29, x30, [x0, #0x10]\n\t" // save fp, lr
"mov sp, x0\n\t" // switch to new stack
"add x29, x0, #0x10\n\t" // switch to new frame
".cfi_def_cfa w29, 16\n\t"
".cfi_offset w30, -8\n\t" // lr
".cfi_offset w29, -16\n\t" // fp
"mov x0, x2\n\t" // Ctx is the only argument
"blr x1\n\t" // call Fn
"ldp x29, x30, [sp, #0x10]\n\t" // restore fp, lr
"ldp xzr, x16, [sp, #0x00]\n\t" // load old sp
"mov sp, x16\n\t"
"ret\n\t"
".cfi_endproc"
);
#endif
} // namespace llvm
namespace {
#ifdef LLVM_HAS_SPLIT_STACKS
void callback(void *Ctx) {
(*reinterpret_cast<function_ref<void()> *>(Ctx))();
}
#endif
} // namespace
#ifdef LLVM_HAS_SPLIT_STACKS
void llvm::runOnNewStack(unsigned StackSize, function_ref<void()> Fn) {
if (StackSize == 0)
StackSize = getDefaultStackSize();
// We use malloc here instead of mmap because:
// - it's simpler,
// - many malloc implementations will reuse the allocation in cases where
// we're bouncing accross the edge of a stack boundry, and
// - many malloc implemenations will already provide guard pages for
// allocations this large.
void *Stack = malloc(StackSize);
void *BottomOfStack = (char *)Stack + StackSize;
runOnNewStackImpl(BottomOfStack, callback, &Fn);
free(Stack);
}
#else
void llvm::runOnNewStack(unsigned StackSize, function_ref<void()> Fn) {
llvm::thread Thread(
StackSize == 0 ? std::nullopt : std::optional<unsigned>(StackSize), Fn);
Thread.join();
}
#endif