Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gcenv.h « Runtime « Native « src - github.com/mono/corert.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 557103dbcead8eb32829fa77c0b8397f7e25fce7 (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
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
// 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.
#define FEATURE_PREMORTEM_FINALIZATION

#ifdef _MSC_VER
#pragma warning( disable: 4189 )  // 'hp': local variable is initialized but not referenced -- common in GC
#pragma warning( disable: 4127 )  // conditional expression is constant -- common in GC
#endif

#include "sal.h"
#include "gcenv.structs.h"
#include "gcenv.os.h"
#include "gcenv.interlocked.h"
#include "gcenv.base.h"

#include "Crst.h"
#include "event.h"
#include "CommonTypes.h"
#include "CommonMacros.h"
#include "daccess.h"
#include "TargetPtrs.h"
#include "eetype.h"
#include "ObjectLayout.h"
#include "rheventtrace.h"
#include "PalRedhawkCommon.h"
#include "PalRedhawk.h"
#include "gcrhinterface.h"
#include "gcenv.interlocked.inl"

#include "stressLog.h"
#ifdef FEATURE_ETW

    #ifndef _INC_WINDOWS
        typedef void* LPVOID;
        typedef uint32_t UINT;
        typedef void* PVOID;
        typedef uint64_t ULONGLONG;
        typedef uint32_t ULONG;
        typedef int64_t LONGLONG;
        typedef uint8_t BYTE;
        typedef uint16_t UINT16;
    #endif // _INC_WINDOWS

    #include "etwevents.h"
    #include "eventtrace.h"

#else // FEATURE_ETW

    #include "etmdummy.h"
    #define ETW_EVENT_ENABLED(e,f) false

#endif // FEATURE_ETW

#define MAX_LONGPATH 1024
#define LOG(x)

#ifndef YieldProcessor
#define YieldProcessor PalYieldProcessor
#endif

// Adapter for GC's view of Array
class ArrayBase : Array
{
public:
    DWORD GetNumComponents()
    {
        return m_Length;
    }

    static size_t GetOffsetOfNumComponents()
    {
        return offsetof(ArrayBase, m_Length);
    }
};

//
// -----------------------------------------------------------------------------------------------------------
//
// Bridge GC/HandleTable's version of MethodTable to Redhawk's EEType. Neither component tries to access any
// fields of MethodTable directly so this is mostly just a case of providing all the CLR-style accessors they
// need implemented on top of EEType functionality (we can simply recast the 'this' pointer into an EEType
// pointer).
//
// ****** NOTE: Do NOT attempt to add fields or virtual methods to this class! The pointer passed in 'this'
// ****** really does point to an EEType (there's no such thing as a MethodTable structure in RH).
//
class MethodTable
{
public:
    UInt32 GetBaseSize() { return ((EEType*)this)->get_BaseSize(); }
    UInt16 GetComponentSize() { return ((EEType*)this)->get_ComponentSize(); }
    UInt16 RawGetComponentSize() { return ((EEType*)this)->get_ComponentSize(); }
    UInt32 ContainsPointers() { return ((EEType*)this)->HasReferenceFields(); }
    UInt32 ContainsPointersOrCollectible() { return ((EEType*)this)->HasReferenceFields(); }
    UInt32_BOOL HasComponentSize() const { return TRUE; }
#ifdef FEATURE_PREMORTEM_FINALIZATION
    UInt32_BOOL HasFinalizer() { return ((EEType*)this)->HasFinalizer(); }
    UInt32_BOOL HasCriticalFinalizer() { return FALSE; }
#endif // FEATURE_PREMORTEM_FINALIZATION
#ifdef FEATURE_STRUCTALIGN
#ifdef FEATURE_BARTOK
    UInt32 GetRequiredAlignment() const { return ((EEType*)this)->get_BaseAlignment(); }
#else // FEATURE_BARTOK
    UInt32 GetRequiredAlignment() const { return sizeof(void*); }
#endif // FEATURE_BARTOK
#endif // FEATURE_STRUCTALIGN
    bool RequiresAlign8() { return ((EEType*)this)->RequiresAlign8(); }
    bool IsValueType() { return ((EEType*)this)->get_IsValueType(); }
    UInt32_BOOL SanityCheck() { return ((EEType*)this)->Validate(); }
};

class EEConfig
{
    UInt8 m_gcStressMode;

public:
    enum HeapVerifyFlags {
        HEAPVERIFY_NONE             = 0,
        HEAPVERIFY_GC               = 1,   // Verify the heap at beginning and end of GC
        HEAPVERIFY_BARRIERCHECK     = 2,   // Verify the brick table
        HEAPVERIFY_SYNCBLK          = 4,   // Verify sync block scanning

        // the following options can be used to mitigate some of the overhead introduced
        // by heap verification.  some options might cause heap verifiction to be less
        // effective depending on the scenario.

        HEAPVERIFY_NO_RANGE_CHECKS  = 0x10,   // Excludes checking if an OBJECTREF is within the bounds of the managed heap
        HEAPVERIFY_NO_MEM_FILL      = 0x20,   // Excludes filling unused segment portions with fill pattern
        HEAPVERIFY_POST_GC_ONLY     = 0x40,   // Performs heap verification post-GCs only (instead of before and after each GC)
        HEAPVERIFY_DEEP_ON_COMPACT  = 0x80    // Performs deep object verfication only on compacting GCs.
    };

    typedef enum {
        CONFIG_SYSTEM,
        CONFIG_APPLICATION,
        CONFIG_SYSTEMONLY
    } ConfigSearch;

    enum  GCStressFlags {
        GCSTRESS_NONE               = 0,
        GCSTRESS_ALLOC              = 1,    // GC on all allocs and 'easy' places
        GCSTRESS_TRANSITION         = 2,    // GC on transitions to preemtive GC
        GCSTRESS_INSTR_JIT          = 4,    // GC on every allowable JITed instr
        GCSTRESS_INSTR_NGEN         = 8,    // GC on every allowable NGEN instr
        GCSTRESS_UNIQUE             = 16,   // GC only on a unique stack trace
    };

    // This is treated like a constructor--it is not allowed to fail.  We have it like this because we don't 
    // have a CRT to run a static constructor for us.  For now, at least, we don't want to do any heavy-weight
    // snooping of the environment to control any of these settings, so don't add any code like that here.
    void Construct()
    {
        m_gcStressMode = GCSTRESS_NONE;
    }

    uint32_t ShouldInjectFault(uint32_t faultType) const { UNREFERENCED_PARAMETER(faultType); return FALSE; }
   
    int     GetHeapVerifyLevel();
    bool    IsHeapVerifyEnabled()                 { return GetHeapVerifyLevel() != 0; }

    GCStressFlags GetGCStressLevel()        const { return (GCStressFlags) m_gcStressMode; }
    void    SetGCStressLevel(int val)             { m_gcStressMode = (UInt8) val;}
    bool    IsGCStressMix()                 const { return false; }

    int     GetGCtraceStart()               const { return 0; }
    int     GetGCtraceEnd  ()               const { return 1000000000; }
    int     GetGCtraceFac  ()               const { return 0; }
    int     GetGCprnLvl    ()               const { return 0; }
    bool    IsGCBreakOnOOMEnabled()         const { return false; }
#ifdef USE_PORTABLE_HELPERS
    // CORERT-TODO: remove this
    //              https://github.com/dotnet/corert/issues/2033
    int     GetGCgen0size  ()               const { return 100 * 1024 * 1024; }
#else
    int     GetGCgen0size  ()               const { return 0; }
#endif
    void    SetGCgen0size  (int iSize)            { UNREFERENCED_PARAMETER(iSize); }
    int     GetSegmentSize ()               const { return 0; }
    void    SetSegmentSize (int iSize)            { UNREFERENCED_PARAMETER(iSize); }
    int     GetGCconcurrent();
    void    SetGCconcurrent(int val)              { UNREFERENCED_PARAMETER(val); }
    int     GetGCLatencyMode()              const { return 1; }
    int     GetGCForceCompact()             const { return 0; }
    int     GetGCRetainVM ()                const { return 0; }
    int     GetGCTrimCommit()               const { return 0; }
    int     GetGCLOHCompactionMode()        const { return 0; }

    bool    GetGCAllowVeryLargeObjects ()   const { return false; }

    // We need conservative GC enabled for some edge cases around ICastable support. This doesn't have much
    // impact, it just makes the GC slightly more flexible in dealing with interior references (e.g. we can
    // conservatively report an interior reference inside a GC free object or in the non-valid tail of the
    // heap).
    bool    GetGCConservative()             const { return true; }

    bool    GetGCNoAffinitize()             const { return false; }
    int     GetGCHeapCount()                const { return 0; }
};
extern EEConfig* g_pConfig;

#ifdef VERIFY_HEAP
class SyncBlockCache;

extern SyncBlockCache g_sSyncBlockCache;

class SyncBlockCache
{
public:
    static SyncBlockCache *GetSyncBlockCache() { return &g_sSyncBlockCache; }
    void GCWeakPtrScan(void *pCallback, uintptr_t pCtx, int dummy)
    {
        UNREFERENCED_PARAMETER(pCallback);
        UNREFERENCED_PARAMETER(pCtx);
        UNREFERENCED_PARAMETER(dummy);
    }
    void GCDone(uint32_t demoting, int max_gen)
    {
        UNREFERENCED_PARAMETER(demoting);
        UNREFERENCED_PARAMETER(max_gen);
    }
    void VerifySyncTableEntry() {}

    DWORD GetActiveCount()
    {
        return 0;
    }
};

#endif // VERIFY_HEAP

EXTERN_C UInt32 _tls_index;
inline UInt16 GetClrInstanceId()
{
    return (UInt16)_tls_index;
}

class IGCHeap;
typedef DPTR(IGCHeap) PTR_IGCHeap;
typedef DPTR(uint32_t) PTR_uint32_t;

enum CLRDataEnumMemoryFlags : int;

enum ThreadType
{
    ThreadType_GC = 137,
};

#undef ClrFlsSetThreadType
#define ClrFlsSetThreadType(threadType) SetGCSpecialThread(threadType)
void SetGCSpecialThread(ThreadType threadType);

#if defined(ENABLE_PERF_COUNTERS) || defined(FEATURE_EVENT_TRACE)
// Note this is not updated in a thread safe way so the value may not be accurate. We get
// it accurately in full GCs if the handle count is requested.
extern DWORD g_dwHandles;
#endif // ENABLE_PERF_COUNTERS || FEATURE_EVENT_TRACE