summaryrefslogtreecommitdiff
path: root/src/vm/stackprobe.inl
blob: de912ffaccf2e336abfa53266c16adbf82d6cb13 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

// 

// 
// ==--==
//

//
//-----------------------------------------------------------------------------
// Stack Probe Header for inline functions
// Used to setup stack guards
//-----------------------------------------------------------------------------
#ifndef __STACKPROBE_inl__
#define __STACKPROBE_inl__

#include "stackprobe.h"
#include "common.h"

#if defined(FEATURE_STACK_PROBE) && !defined(DACCESS_COMPILE)

// want to inline in retail, but out of line into stackprobe.cpp in debug
#if !defined(_DEBUG) || defined(INCLUDE_RETAIL_STACK_PROBE)

#ifndef _DEBUG
#define INLINE_NONDEBUG_ONLY FORCEINLINE
#else
#define INLINE_NONDEBUG_ONLY
#endif

INLINE_NONDEBUG_ONLY BOOL ShouldProbeOnThisThread()
{
    // we only want to probe on user threads, not any of our special threads
    return GetCurrentTaskType() == TT_USER;
}

#if defined(_DEBUG) && defined(STACK_GUARDS_DEBUG)

DEBUG_NOINLINE void DebugSOTolerantTransitionHandler::EnterSOTolerantCode(Thread *pThread) 
{
    SCAN_SCOPE_BEGIN;
    ANNOTATION_FN_SO_TOLERANT;

    if (pThread)
    {
        m_clrDebugState = pThread->GetClrDebugState();
    }
    else
    {
        m_clrDebugState = GetClrDebugState();
    }
    if (m_clrDebugState)
        m_prevSOTolerantState = m_clrDebugState->BeginSOTolerant();
}

DEBUG_NOINLINE void DebugSOTolerantTransitionHandler::ReturnFromSOTolerantCode()
{
    SCAN_SCOPE_END;

    if (m_clrDebugState)
        m_clrDebugState->SetSOTolerance(m_prevSOTolerantState);
}

#endif

// Keep the main body out of line to keep code size down.
NOINLINE BOOL RetailStackProbeNoThrowWorker(unsigned int n, Thread *pThread);
NOINLINE void RetailStackProbeWorker(unsigned int n, Thread *pThread);

INLINE_NONDEBUG_ONLY 
BOOL RetailStackProbeNoThrow(unsigned int n, Thread *pThread)
{
    STATIC_CONTRACT_NOTHROW;
    STATIC_CONTRACT_GC_NOTRIGGER;
    STATIC_CONTRACT_SO_TOLERANT;

#ifdef STACK_GUARDS_RELEASE
    if(!IsStackProbingEnabled())
    {
        return TRUE;
    }
#endif

    return RetailStackProbeNoThrowWorker(n, pThread);
}

INLINE_NONDEBUG_ONLY 
void RetailStackProbe(unsigned int n, Thread *pThread)
{
    STATIC_CONTRACT_THROWS;
    STATIC_CONTRACT_GC_NOTRIGGER;
    STATIC_CONTRACT_SO_TOLERANT;

#ifdef STACK_GUARDS_RELEASE
    if(!IsStackProbingEnabled())
    {
        return;
    }
#endif

    if (RetailStackProbeNoThrowWorker(n, pThread))
    {
        return;
    }
    ReportStackOverflow();
}

INLINE_NONDEBUG_ONLY 
void RetailStackProbe(unsigned int n)
{
    STATIC_CONTRACT_THROWS;
    STATIC_CONTRACT_GC_NOTRIGGER;
    STATIC_CONTRACT_SO_TOLERANT;

#ifdef STACK_GUARDS_RELEASE
    if(!IsStackProbingEnabled())
    {
        return;
    }
#endif

    if (RetailStackProbeNoThrowWorker(n, GetThread()))
    {
        return;
    }
    ReportStackOverflow();
}

#endif
#endif


#endif  // __STACKPROBE_inl__