1// Licensed to the .NET Foundation under one or more agreements.
2// The .NET Foundation licenses this file to you under the MIT license.
3// See the LICENSE file in the project root for more information.
4
5//
6
7//
8// ==--==
9//
10
11//
12//-----------------------------------------------------------------------------
13// Stack Probe Header for inline functions
14// Used to setup stack guards
15//-----------------------------------------------------------------------------
16#ifndef __STACKPROBE_inl__
17#define __STACKPROBE_inl__
18
19#include "stackprobe.h"
20#include "common.h"
21
22#if defined(FEATURE_STACK_PROBE) && !defined(DACCESS_COMPILE)
23
24// want to inline in retail, but out of line into stackprobe.cpp in debug
25#if !defined(_DEBUG) || defined(INCLUDE_RETAIL_STACK_PROBE)
26
27#ifndef _DEBUG
28#define INLINE_NONDEBUG_ONLY FORCEINLINE
29#else
30#define INLINE_NONDEBUG_ONLY
31#endif
32
33INLINE_NONDEBUG_ONLY BOOL ShouldProbeOnThisThread()
34{
35 // we only want to probe on user threads, not any of our special threads
36 return GetCurrentTaskType() == TT_USER;
37}
38
39#if defined(_DEBUG) && defined(STACK_GUARDS_DEBUG)
40
41DEBUG_NOINLINE void DebugSOTolerantTransitionHandler::EnterSOTolerantCode(Thread *pThread)
42{
43 SCAN_SCOPE_BEGIN;
44 ANNOTATION_FN_SO_TOLERANT;
45
46 if (pThread)
47 {
48 m_clrDebugState = pThread->GetClrDebugState();
49 }
50 else
51 {
52 m_clrDebugState = GetClrDebugState();
53 }
54 if (m_clrDebugState)
55 m_prevSOTolerantState = m_clrDebugState->BeginSOTolerant();
56}
57
58DEBUG_NOINLINE void DebugSOTolerantTransitionHandler::ReturnFromSOTolerantCode()
59{
60 SCAN_SCOPE_END;
61
62 if (m_clrDebugState)
63 m_clrDebugState->SetSOTolerance(m_prevSOTolerantState);
64}
65
66#endif
67
68// Keep the main body out of line to keep code size down.
69NOINLINE BOOL RetailStackProbeNoThrowWorker(unsigned int n, Thread *pThread);
70NOINLINE void RetailStackProbeWorker(unsigned int n, Thread *pThread);
71
72INLINE_NONDEBUG_ONLY
73BOOL RetailStackProbeNoThrow(unsigned int n, Thread *pThread)
74{
75 STATIC_CONTRACT_NOTHROW;
76 STATIC_CONTRACT_GC_NOTRIGGER;
77 STATIC_CONTRACT_SO_TOLERANT;
78
79#ifdef STACK_GUARDS_RELEASE
80 if(!IsStackProbingEnabled())
81 {
82 return TRUE;
83 }
84#endif
85
86 return RetailStackProbeNoThrowWorker(n, pThread);
87}
88
89INLINE_NONDEBUG_ONLY
90void RetailStackProbe(unsigned int n, Thread *pThread)
91{
92 STATIC_CONTRACT_THROWS;
93 STATIC_CONTRACT_GC_NOTRIGGER;
94 STATIC_CONTRACT_SO_TOLERANT;
95
96#ifdef STACK_GUARDS_RELEASE
97 if(!IsStackProbingEnabled())
98 {
99 return;
100 }
101#endif
102
103 if (RetailStackProbeNoThrowWorker(n, pThread))
104 {
105 return;
106 }
107 ReportStackOverflow();
108}
109
110INLINE_NONDEBUG_ONLY
111void RetailStackProbe(unsigned int n)
112{
113 STATIC_CONTRACT_THROWS;
114 STATIC_CONTRACT_GC_NOTRIGGER;
115 STATIC_CONTRACT_SO_TOLERANT;
116
117#ifdef STACK_GUARDS_RELEASE
118 if(!IsStackProbingEnabled())
119 {
120 return;
121 }
122#endif
123
124 if (RetailStackProbeNoThrowWorker(n, GetThread()))
125 {
126 return;
127 }
128 ReportStackOverflow();
129}
130
131#endif
132#endif
133
134
135#endif // __STACKPROBE_inl__
136