13
13
14
14
#include " clang/Basic/Stack.h"
15
15
#include " llvm/Support/CrashRecoveryContext.h"
16
- #include " llvm/Support/ProgramStack.h"
17
16
18
- static LLVM_THREAD_LOCAL uintptr_t BottomOfStack = 0 ;
17
+ #ifdef _MSC_VER
18
+ #include < intrin.h> // for _AddressOfReturnAddress
19
+ #endif
19
20
20
- void clang::noteBottomOfStack (bool ForceSet) {
21
- if (!BottomOfStack || ForceSet)
22
- BottomOfStack = llvm::getStackPointer ();
21
+ static LLVM_THREAD_LOCAL void *BottomOfStack = nullptr ;
22
+
23
+ static void *getStackPointer () {
24
+ #if __GNUC__ || __has_builtin(__builtin_frame_address)
25
+ return __builtin_frame_address (0 );
26
+ #elif defined(_MSC_VER)
27
+ return _AddressOfReturnAddress ();
28
+ #else
29
+ char CharOnStack = 0 ;
30
+ // The volatile store here is intended to escape the local variable, to
31
+ // prevent the compiler from optimizing CharOnStack into anything other
32
+ // than a char on the stack.
33
+ //
34
+ // Tested on: MSVC 2015 - 2019, GCC 4.9 - 9, Clang 3.2 - 9, ICC 13 - 19.
35
+ char *volatile Ptr = &CharOnStack;
36
+ return Ptr;
37
+ #endif
38
+ }
39
+
40
+ void clang::noteBottomOfStack () {
41
+ if (!BottomOfStack)
42
+ BottomOfStack = getStackPointer ();
23
43
}
24
44
25
45
bool clang::isStackNearlyExhausted () {
@@ -31,8 +51,7 @@ bool clang::isStackNearlyExhausted() {
31
51
if (!BottomOfStack)
32
52
return false ;
33
53
34
- intptr_t StackDiff =
35
- (intptr_t )llvm::getStackPointer () - (intptr_t )BottomOfStack;
54
+ intptr_t StackDiff = (intptr_t )getStackPointer () - (intptr_t )BottomOfStack;
36
55
size_t StackUsage = (size_t )std::abs (StackDiff);
37
56
38
57
// If the stack pointer has a surprising value, we do not understand this
@@ -47,12 +66,9 @@ bool clang::isStackNearlyExhausted() {
47
66
void clang::runWithSufficientStackSpaceSlow (llvm::function_ref<void ()> Diag,
48
67
llvm::function_ref<void()> Fn) {
49
68
llvm::CrashRecoveryContext CRC;
50
- // Preserve the BottomOfStack in case RunSafelyOnNewStack uses split stacks.
51
- uintptr_t PrevBottom = BottomOfStack;
52
- CRC.RunSafelyOnNewStack ([&] {
53
- noteBottomOfStack (true );
69
+ CRC.RunSafelyOnThread ([&] {
70
+ noteBottomOfStack ();
54
71
Diag ();
55
72
Fn ();
56
73
}, DesiredStackSize);
57
- BottomOfStack = PrevBottom;
58
74
}
0 commit comments