1 //===--- Stack.cpp - Utilities for dealing with stack space ---------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 /// 9 /// \file 10 /// Defines utilities for dealing with stack allocation and stack space. 11 /// 12 //===----------------------------------------------------------------------===// 13 14 #include "clang/Basic/Stack.h" 15 #include "llvm/Support/CrashRecoveryContext.h" 16 #include "llvm/Support/ProgramStack.h" 17 18 static LLVM_THREAD_LOCAL uintptr_t BottomOfStack = 0; 19 20 void clang::noteBottomOfStack(bool ForceSet) { 21 if (!BottomOfStack || ForceSet) 22 BottomOfStack = llvm::getStackPointer(); 23 } 24 25 bool clang::isStackNearlyExhausted() { 26 // We consider 256 KiB to be sufficient for any code that runs between checks 27 // for stack size. 28 constexpr size_t SufficientStack = 256 << 10; 29 30 // If we don't know where the bottom of the stack is, hope for the best. 31 if (!BottomOfStack) 32 return false; 33 34 intptr_t StackDiff = 35 (intptr_t)llvm::getStackPointer() - (intptr_t)BottomOfStack; 36 size_t StackUsage = (size_t)std::abs(StackDiff); 37 38 // If the stack pointer has a surprising value, we do not understand this 39 // stack usage scheme. (Perhaps the target allocates new stack regions on 40 // demand for us.) Don't try to guess what's going on. 41 if (StackUsage > DesiredStackSize) 42 return false; 43 44 return StackUsage >= DesiredStackSize - SufficientStack; 45 } 46 47 void clang::runWithSufficientStackSpaceSlow(llvm::function_ref<void()> Diag, 48 llvm::function_ref<void()> Fn) { 49 llvm::CrashRecoveryContext CRC; 50 // Preserve the BottomOfStack in case RunSafelyOnNewStack uses split stacks. 51 uintptr_t PrevBottom = BottomOfStack; 52 CRC.RunSafelyOnNewStack([&] { 53 noteBottomOfStack(true); 54 Diag(); 55 Fn(); 56 }, DesiredStackSize); 57 BottomOfStack = PrevBottom; 58 } 59