This repository has been archived by the owner on Nov 1, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 509
/
Copy pathgcenv.h
249 lines (212 loc) · 9.08 KB
/
gcenv.h
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
// 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 "gcenv.ee.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;
#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