//===--- ProgramStack.h -----------------------------------------*- C++ -*-===// // // 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 // //===----------------------------------------------------------------------===// #ifndef LLVM_SUPPORT_PROGRAMSTACK_H #define LLVM_SUPPORT_PROGRAMSTACK_H #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. /// /// The value is not guaranteed to point to anything specific. It can be used to /// estimate how much stack space has been used since the previous call. LLVM_ABI uintptr_t getStackPointer(); /// \returns the default stack size for this platform. /// /// Based on \p RLIMIT_STACK or the equivalent. LLVM_ABI unsigned getDefaultStackSize(); /// Runs Fn on a new stack of at least the given size. /// /// \param StackSize requested stack size. A size of 0 uses the default stack /// size of the platform. /// /// The preferred implementation is split stacks on platforms that have a good /// debugging experience for them. On other platforms a new thread is used. LLVM_ABI void runOnNewStack(unsigned StackSize, function_ref Fn); template auto runOnNewStack(unsigned StackSize, function_ref Fn, Ts &&...Args) { if constexpr (std::is_same_v) { runOnNewStack(StackSize, [&]() { Fn(std::forward(Args)...); }); } else { std::optional Ret; runOnNewStack(StackSize, [&]() { Ret = Fn(std::forward(Args)...); }); return std::move(*Ret); } } } // namespace llvm #endif // LLVM_SUPPORT_PROGRAMSTACK_H