-
Notifications
You must be signed in to change notification settings - Fork 5.4k
Expand file tree
/
Copy pathcomutilnative.h
More file actions
305 lines (243 loc) · 11.7 KB
/
comutilnative.h
File metadata and controls
305 lines (243 loc) · 11.7 KB
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
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
//
//
/*============================================================
**
** Header: COMUtilNative
**
**
** Purpose: A dumping ground for classes which aren't large
** enough to get their own file in the VM.
**
**
===========================================================*/
#ifndef _COMUTILNATIVE_H_
#define _COMUTILNATIVE_H_
#include "object.h"
#include "util.hpp"
#include "cgensys.h"
#include "fcall.h"
#include "qcall.h"
#include "windows.h"
//
//
// EXCEPTION NATIVE
//
//
class ExceptionNative
{
public:
static FCDECL1(FC_BOOL_RET, IsImmutableAgileException, Object* pExceptionUNSAFE);
static FCDECL1(FC_BOOL_RET, IsTransient, INT32 hresult);
static FCDECL0(VOID, PrepareForForeignExceptionRaise);
#ifdef FEATURE_COMINTEROP
// NOTE: caller cleans up any partially initialized BSTRs in pED
static void GetExceptionData(OBJECTREF, ExceptionData *);
#endif
// Note: these are on the PInvoke class to hide these from the user.
static FCDECL0(EXCEPTION_POINTERS*, GetExceptionPointers);
static FCDECL0(INT32, GetExceptionCode);
static FCDECL0(UINT32, GetExceptionCount);
};
extern "C" void QCALLTYPE ExceptionNative_GetFrozenStackTrace(QCall::ObjectHandleOnStack exception, QCall::ObjectHandleOnStack ret);
enum class ExceptionMessageKind {
ThreadAbort = 1,
ThreadInterrupted = 2,
OutOfMemory = 3
};
extern "C" void QCALLTYPE ExceptionNative_GetMessageFromNativeResources(ExceptionMessageKind kind, QCall::StringHandleOnStack retMesg);
extern "C" void QCALLTYPE ExceptionNative_GetMethodFromStackTrace(QCall::ObjectHandleOnStack array, QCall::ObjectHandleOnStack retMethodInfo);
extern "C" void QCALLTYPE ExceptionNative_ThrowAmbiguousResolutionException(
MethodTable* pTargetClass,
MethodTable* pInterfaceMT,
MethodDesc* pInterfaceMD);
extern "C" void QCALLTYPE ExceptionNative_ThrowEntryPointNotFoundException(
MethodTable* pTargetClass,
MethodTable* pInterfaceMT,
MethodDesc* pInterfaceMD);
extern "C" void QCALLTYPE ExceptionNative_ThrowMethodAccessException(MethodDesc* caller, MethodDesc* callee);
extern "C" void QCALLTYPE ExceptionNative_ThrowFieldAccessException(MethodDesc* caller, FieldDesc* callee);
extern "C" void QCALLTYPE ExceptionNative_ThrowClassAccessException(MethodDesc* caller, EnregisteredTypeHandle callee);
//
// Buffer
//
class Buffer
{
public:
static FCDECL3(VOID, BulkMoveWithWriteBarrier, void *dst, void *src, size_t byteCount);
};
const UINT MEM_PRESSURE_COUNT = 4;
struct GCGenerationInfo
{
UINT64 sizeBefore;
UINT64 fragmentationBefore;
UINT64 sizeAfter;
UINT64 fragmentationAfter;
};
#include "pshpack4.h"
class GCMemoryInfoData : public Object
{
public:
UINT64 highMemLoadThresholdBytes;
UINT64 totalAvailableMemoryBytes;
UINT64 lastRecordedMemLoadBytes;
UINT64 lastRecordedHeapSizeBytes;
UINT64 lastRecordedFragmentationBytes;
UINT64 totalCommittedBytes;
UINT64 promotedBytes;
UINT64 pinnedObjectCount;
UINT64 finalizationPendingCount;
UINT64 index;
UINT32 generation;
UINT32 pauseTimePercent;
UINT8 isCompaction;
UINT8 isConcurrent;
#ifndef UNIX_X86_ABI
UINT8 padding[6];
#endif
GCGenerationInfo generationInfo0;
GCGenerationInfo generationInfo1;
GCGenerationInfo generationInfo2;
GCGenerationInfo generationInfo3;
GCGenerationInfo generationInfo4;
UINT64 pauseDuration0;
UINT64 pauseDuration1;
};
#include "poppack.h"
#ifdef USE_CHECKED_OBJECTREFS
typedef REF<GCMemoryInfoData> GCMEMORYINFODATA;
typedef REF<GCMemoryInfoData> GCMEMORYINFODATAREF;
#else // USE_CHECKED_OBJECTREFS
typedef GCMemoryInfoData * GCMEMORYINFODATA;
typedef GCMemoryInfoData * GCMEMORYINFODATAREF;
#endif // USE_CHECKED_OBJECTREFS
using EnumerateConfigurationValuesCallback = void (*)(void* context, const char* name, const char* publicKey, GCConfigurationType type, int64_t data);
struct GCHeapHardLimitInfo
{
UINT64 heapHardLimit;
UINT64 heapHardLimitPercent;
UINT64 heapHardLimitSOH;
UINT64 heapHardLimitLOH;
UINT64 heapHardLimitPOH;
UINT64 heapHardLimitSOHPercent;
UINT64 heapHardLimitLOHPercent;
UINT64 heapHardLimitPOHPercent;
};
class GCInterface {
private:
static INT32 m_gc_counts[3];
static UINT64 m_addPressure[MEM_PRESSURE_COUNT];
static UINT64 m_remPressure[MEM_PRESSURE_COUNT];
static UINT m_iteration;
public:
static FORCEINLINE UINT64 InterlockedAdd(UINT64 *pAugend, UINT64 addend);
static FORCEINLINE UINT64 InterlockedSub(UINT64 *pMinuend, UINT64 subtrahend);
static FCDECL0(INT64, GetTotalPauseDuration);
static FCDECL2(void, GetMemoryInfo, Object* objUNSAFE, int kind);
static FCDECL0(UINT32, GetMemoryLoad);
static FCDECL0(int, GetGcLatencyMode);
static FCDECL1(int, SetGcLatencyMode, int newLatencyMode);
static FCDECL0(int, GetLOHCompactionMode);
static FCDECL1(void, SetLOHCompactionMode, int newLOHCompactionyMode);
static FCDECL2(FC_BOOL_RET, RegisterForFullGCNotification, UINT32 gen2Percentage, UINT32 lohPercentage);
static FCDECL0(FC_BOOL_RET, CancelFullGCNotification);
static FCDECL1(int, GetGenerationInternal, Object* objUNSAFE);
static FCDECL0(UINT64, GetSegmentSize);
static FCDECL0(int, GetLastGCPercentTimeInGC);
static FCDECL1(UINT64, GetGenerationSize, int gen);
static FCDECL0(int, GetMaxGeneration);
static FCDECL0(FC_BOOL_RET, IsServerGC);
static FCDECL1(void, SuppressFinalize, Object *obj);
static FCDECL2(int, CollectionCount, INT32 generation, INT32 getSpecialGCCount);
static FCDECL0(INT64, GetAllocatedBytesForCurrentThread);
static FCDECL0(INT64, GetTotalAllocatedBytesApproximate);
// Helper FCalls for managed AddMemoryPressure/RemoveMemoryPressure implementation
static FCDECL0(INT64, GetCurrentObjSize);
static FCDECL0(INT64, GetNow);
static FCDECL1(INT64, GetLastGCStartTime, INT32 generation);
static FCDECL1(INT64, GetLastGCDuration, INT32 generation);
static FCDECL1(VOID, SendEtwAddMemoryPressureEvent, UINT64 bytesAllocated);
static FCDECL1(VOID, SendEtwRemoveMemoryPressureEvent, UINT64 bytesAllocated);
// Wrapper methods that call managed implementation
static void AddMemoryPressure(UINT64 bytesAllocated);
static void RemoveMemoryPressure(UINT64 bytesAllocated);
static void EnumerateConfigurationValues(void* configurationContext, EnumerateConfigurationValuesCallback callback);
static int RefreshMemoryLimit();
static enable_no_gc_region_callback_status EnableNoGCRegionCallback(NoGCRegionCallbackFinalizerWorkItem* callback, INT64 totalSize);
static uint64_t GetGenerationBudget(int generation);
};
extern "C" INT64 QCALLTYPE GCInterface_GetTotalAllocatedBytesPrecise();
extern "C" void QCALLTYPE GCInterface_AllocateNewArray(void* typeHandlePtr, INT32 length, INT32 flags, QCall::ObjectHandleOnStack ret);
extern "C" INT64 QCALLTYPE GCInterface_GetTotalMemory();
extern "C" void QCALLTYPE GCInterface_Collect(INT32 generation, INT32 mode, CLR_BOOL lowMemoryPressure);
extern "C" void* QCALLTYPE GCInterface_GetNextFinalizableObject(QCall::ObjectHandleOnStack pObj);
extern "C" void QCALLTYPE GCInterface_WaitForPendingFinalizers();
#ifdef FEATURE_BASICFREEZE
extern "C" void* QCALLTYPE GCInterface_RegisterFrozenSegment(void *pSection, SIZE_T sizeSection);
extern "C" void QCALLTYPE GCInterface_UnregisterFrozenSegment(void *segmentHandle);
#endif // FEATURE_BASICFREEZE
extern "C" int QCALLTYPE GCInterface_WaitForFullGCApproach(int millisecondsTimeout);
extern "C" int QCALLTYPE GCInterface_WaitForFullGCComplete(int millisecondsTimeout);
extern "C" int QCALLTYPE GCInterface_StartNoGCRegion(INT64 totalSize, BOOL lohSizeKnown, INT64 lohSize, BOOL disallowFullBlockingGC);
extern "C" int QCALLTYPE GCInterface_EndNoGCRegion();
extern "C" void QCALLTYPE GCInterface_AddMemoryPressureForExternal(UINT64 bytesAllocated);
extern "C" void QCALLTYPE GCInterface_RemoveMemoryPressureForExternal(UINT64 bytesAllocated);
extern "C" void QCALLTYPE GCInterface_ReRegisterForFinalize(QCall::ObjectHandleOnStack pObj);
extern "C" void QCALLTYPE GCInterface_EnumerateConfigurationValues(void* configurationContext, EnumerateConfigurationValuesCallback callback);
extern "C" int QCALLTYPE GCInterface_RefreshMemoryLimit(GCHeapHardLimitInfo heapHardLimitInfo);
extern "C" enable_no_gc_region_callback_status QCALLTYPE GCInterface_EnableNoGCRegionCallback(NoGCRegionCallbackFinalizerWorkItem* callback, INT64 totalSize);
extern "C" uint64_t QCALLTYPE GCInterface_GetGenerationBudget(int generation);
//
// EnvironmentNative
//
class EnvironmentNative
{
public:
// Functions on the System.Environment class
static FCDECL1(VOID,SetExitCode,INT32 exitcode);
static FCDECL0(INT32, GetExitCode);
};
extern "C" void QCALLTYPE Environment_Exit(INT32 exitcode);
extern "C" void QCALLTYPE Environment_FailFast(QCall::StackCrawlMarkHandle mark, PCWSTR message, QCall::ObjectHandleOnStack exception, PCWSTR errorSource);
// Returns the number of logical processors that can be used by managed code
extern "C" INT32 QCALLTYPE Environment_GetProcessorCount();
extern "C" void QCALLTYPE GetTypeLoadExceptionMessage(UINT32 resId, QCall::StringHandleOnStack retString);
extern "C" void QCALLTYPE GetFileLoadExceptionMessage(UINT32 hr, QCall::StringHandleOnStack retString);
extern "C" void QCALLTYPE FileLoadException_GetMessageForHR(UINT32 hresult, QCall::StringHandleOnStack retString);
class ObjectNative
{
public:
static FCDECL1(INT32, TryGetHashCode, Object* vThisRef);
static FCDECL2(FC_BOOL_RET, ContentEquals, Object *pThisRef, Object *pCompareRef);
};
extern "C" INT32 QCALLTYPE ObjectNative_GetHashCodeSlow(QCall::ObjectHandleOnStack objHandle);
extern "C" void QCALLTYPE ObjectNative_AllocateUninitializedClone(QCall::ObjectHandleOnStack objHandle);
class COMInterlocked
{
public:
static FCDECL2(INT32, Exchange32, INT32 *location, INT32 value);
static FCDECL2_IV(INT64, Exchange64, INT64 *location, INT64 value);
static FCDECL3(INT32, CompareExchange32, INT32* location, INT32 value, INT32 comparand);
static FCDECL3_IVV(INT64, CompareExchange64, INT64* location, INT64 value, INT64 comparand);
static FCDECL2(LPVOID, ExchangeObject, LPVOID* location, LPVOID value);
static FCDECL3(LPVOID, CompareExchangeObject, LPVOID* location, LPVOID value, LPVOID comparand);
static FCDECL2(INT32, ExchangeAdd32, INT32 *location, INT32 value);
static FCDECL2_IV(INT64, ExchangeAdd64, INT64 *location, INT64 value);
};
class MethodTableNative {
public:
static FCDECL1(UINT32, GetNumInstanceFieldBytes, MethodTable* mt);
static FCDECL1(CorElementType, GetPrimitiveCorElementType, MethodTable* mt);
static FCDECL2(MethodTable*, GetMethodTableMatchingParentClass, MethodTable* mt, MethodTable* parent);
static FCDECL1(MethodTable*, InstantiationArg0, MethodTable* mt);
static FCDECL1(OBJECTHANDLE, GetLoaderAllocatorHandle, MethodTable* mt);
};
extern "C" BOOL QCALLTYPE MethodTable_AreTypesEquivalent(MethodTable* mta, MethodTable* mtb);
extern "C" BOOL QCALLTYPE MethodTable_CanCompareBitsOrUseFastGetHashCode(MethodTable* mt);
extern "C" BOOL QCALLTYPE TypeHandle_CanCastTo_NoCacheLookup(void* fromTypeHnd, void* toTypeHnd);
extern "C" INT32 QCALLTYPE TypeHandle_GetCorElementType(void* typeHnd);
extern "C" INT32 QCALLTYPE ValueType_GetHashCodeStrategy(MethodTable* mt, QCall::ObjectHandleOnStack objHandle, UINT32* fieldOffset, UINT32* fieldSize, MethodTable** fieldMT);
BOOL CanCompareBitsOrUseFastGetHashCode(MethodTable* mt);
extern "C" BOOL QCALLTYPE Stream_HasOverriddenSlow(MethodTable* pMT, BOOL isRead);
#endif // _COMUTILNATIVE_H_