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
|
// 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.
//
//
/*============================================================
**
** 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"
#undef GetCurrentTime
#pragma warning(push)
#pragma warning(disable:4324)
#if !defined(CROSS_COMPILE) && defined(_TARGET_ARM_) && !defined(PLATFORM_UNIX)
#include "arm_neon.h"
#endif
#include "marvin32.h"
#pragma warning(pop)
//
//
// PARSE NUMBERS
//
//
#define MinRadix 2
#define MaxRadix 36
class ParseNumbers {
enum FmtFlags {
LeftAlign = 0x1, //Ensure that these conform to the values specified in the managed files.
CenterAlign = 0x2,
RightAlign = 0x4,
PrefixSpace = 0x8,
PrintSign = 0x10,
PrintBase = 0x20,
TreatAsUnsigned = 0x10,
PrintAsI1 = 0x40,
PrintAsI2 = 0x80,
PrintAsI4 = 0x100,
PrintRadixBase = 0x200,
AlternateForm = 0x400};
public:
static INT32 GrabInts(const INT32 radix, __in_ecount(length) WCHAR *buffer, const int length, int *i, BOOL isUnsigned);
static INT64 GrabLongs(const INT32 radix, __in_ecount(length) WCHAR *buffer, const int length, int *i, BOOL isUnsigned);
static FCDECL5(LPVOID, IntToString, INT32 l, INT32 radix, INT32 width, CLR_CHAR paddingChar, INT32 flags);
static FCDECL5_VII(LPVOID, LongToString, INT64 l, INT32 radix, INT32 width, CLR_CHAR paddingChar, INT32 flags);
static FCDECL4(INT32, StringToInt, StringObject * s, INT32 radix, INT32 flags, INT32* currPos);
static FCDECL4(INT64, StringToLong, StringObject * s, INT32 radix, INT32 flags, INT32* currPos);
};
//
//
// EXCEPTION NATIVE
//
//
void FreeExceptionData(ExceptionData *pedata);
class ExceptionNative
{
private:
enum ExceptionMessageKind {
ThreadAbort = 1,
ThreadInterrupted = 2,
OutOfMemory = 3
};
public:
static FCDECL1(FC_BOOL_RET, IsImmutableAgileException, Object* pExceptionUNSAFE);
static FCDECL1(FC_BOOL_RET, IsTransient, INT32 hresult);
static FCDECL3(StringObject *, StripFileInfo, Object *orefExcepUNSAFE, StringObject *orefStrUNSAFE, CLR_BOOL isRemoteStackTrace);
static void QCALLTYPE GetMessageFromNativeResources(ExceptionMessageKind kind, QCall::StringHandleOnStack retMesg);
static FCDECL0(VOID, PrepareForForeignExceptionRaise);
static FCDECL1(Object*, CopyStackTrace, Object* pStackTraceUNSAFE);
static FCDECL1(Object*, CopyDynamicMethods, Object* pDynamicMethodsUNSAFE);
static FCDECL3(VOID, GetStackTracesDeepCopy, Object* pExceptionObjectUnsafe, Object **pStackTraceUnsafe, Object **pDynamicMethodsUnsafe);
static FCDECL3(VOID, SaveStackTracesFromDeepCopy, Object* pExceptionObjectUnsafe, Object *pStackTraceUnsafe, Object *pDynamicMethodsUnsafe);
// NOTE: caller cleans up any partially initialized BSTRs in pED
static void GetExceptionData(OBJECTREF, ExceptionData *);
// Note: these are on the PInvoke class to hide these from the user.
static FCDECL0(EXCEPTION_POINTERS*, GetExceptionPointers);
static FCDECL0(INT32, GetExceptionCode);
};
class MemoryNative
{
public:
static void QCALLTYPE Clear(void *dst, size_t length);
static FCDECL3(VOID, BulkMoveWithWriteBarrier, void *dst, void *src, size_t byteCount);
};
//
// Buffer
//
class Buffer {
public:
// BlockCopy
// This method from one primitive array to another based
// upon an offset into each an a byte count.
static FCDECL5(VOID, BlockCopy, ArrayBase *src, int srcOffset, ArrayBase *dst, int dstOffset, int count);
static FCDECL5(VOID, InternalBlockCopy, ArrayBase *src, int srcOffset, ArrayBase *dst, int dstOffset, int count);
static FCDECL2(FC_UINT8_RET, GetByte, ArrayBase *arrayUNSAFE, INT32 index);
static FCDECL3(VOID, SetByte, ArrayBase *arrayUNSAFE, INT32 index, UINT8 bData);
static FCDECL1(FC_BOOL_RET, IsPrimitiveTypeArray, ArrayBase *arrayUNSAFE);
static FCDECL1(INT32, ByteLength, ArrayBase *arrayUNSAFE);
static void QCALLTYPE MemMove(void *dst, void *src, size_t length);
};
#define MIN_GC_MEMORYPRESSURE_THRESHOLD 100000
#define RELATIVE_GC_RATIO 8
const UINT NEW_PRESSURE_COUNT = 4;
class GCInterface {
private:
static MethodDesc *m_pCacheMethod;
static UINT64 m_ulMemPressure;
static UINT64 m_ulThreshold;
static INT32 m_gc_counts[3];
static UINT64 m_addPressure[NEW_PRESSURE_COUNT];
static UINT64 m_remPressure[NEW_PRESSURE_COUNT];
static UINT m_iteration;
public:
static CrstStatic m_MemoryPressureLock;
static FORCEINLINE UINT64 InterlockedAdd(UINT64 *pAugend, UINT64 addend);
static FORCEINLINE UINT64 InterlockedSub(UINT64 *pMinuend, UINT64 subtrahend);
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, WaitForFullGCApproach, int millisecondsTimeout);
static FCDECL1(int, WaitForFullGCComplete, int millisecondsTimeout);
static FCDECL1(int, GetGenerationWR, LPVOID handle);
static FCDECL1(int, GetGeneration, Object* objUNSAFE);
static
INT64 QCALLTYPE GetTotalMemory();
static
void QCALLTYPE Collect(INT32 generation, INT32 mode);
static
void QCALLTYPE WaitForPendingFinalizers();
static FCDECL0(int, GetMaxGeneration);
static FCDECL1(void, KeepAlive, Object *obj);
static FCDECL1(void, SuppressFinalize, Object *obj);
static FCDECL1(void, ReRegisterForFinalize, Object *obj);
static FCDECL2(int, CollectionCount, INT32 generation, INT32 getSpecialGCCount);
static FCDECL0(INT64, GetAllocatedBytesForCurrentThread);
static
int QCALLTYPE StartNoGCRegion(INT64 totalSize, BOOL lohSizeKnown, INT64 lohSize, BOOL disallowFullBlockingGC);
static
int QCALLTYPE EndNoGCRegion();
static
void QCALLTYPE _AddMemoryPressure(UINT64 bytesAllocated);
static
void QCALLTYPE _RemoveMemoryPressure(UINT64 bytesAllocated);
static void RemoveMemoryPressure(UINT64 bytesAllocated);
static void AddMemoryPressure(UINT64 bytesAllocated);
NOINLINE static void SendEtwRemoveMemoryPressureEvent(UINT64 bytesAllocated);
static void SendEtwAddMemoryPressureEvent(UINT64 bytesAllocated);
// New less sensitive implementation of Add/RemoveMemoryPressure:
static void CheckCollectionCount();
static void NewRemoveMemoryPressure(UINT64 bytesAllocated);
static void NewAddMemoryPressure(UINT64 bytesAllocated);
private:
// Out-of-line helper to avoid EH prolog/epilog in functions that otherwise don't throw.
NOINLINE static void GarbageCollectModeAny(int generation);
};
class COMInterlocked
{
public:
static FCDECL2(INT32, Exchange, INT32 *location, INT32 value);
static FCDECL2_IV(INT64, Exchange64, INT64 *location, INT64 value);
static FCDECL2(LPVOID, ExchangePointer, LPVOID* location, LPVOID value);
static FCDECL3(INT32, CompareExchange, INT32* location, INT32 value, INT32 comparand);
static FCDECL4(INT32, CompareExchangeReliableResult, INT32* location, INT32 value, INT32 comparand, CLR_BOOL* succeeded);
static FCDECL3_IVV(INT64, CompareExchange64, INT64* location, INT64 value, INT64 comparand);
static FCDECL3(LPVOID, CompareExchangePointer, LPVOID* location, LPVOID value, LPVOID comparand);
static FCDECL2_IV(float, ExchangeFloat, float *location, float value);
static FCDECL2_IV(double, ExchangeDouble, double *location, double value);
static FCDECL3_IVV(float, CompareExchangeFloat, float *location, float value, float comparand);
static FCDECL3_IVV(double, CompareExchangeDouble, double *location, double value, double 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);
static FCDECL2_VV(void, ExchangeGeneric, FC_TypedByRef location, FC_TypedByRef value);
static FCDECL3_VVI(void, CompareExchangeGeneric, FC_TypedByRef location, FC_TypedByRef value, LPVOID comparand);
static FCDECL0(void, FCMemoryBarrier);
static void QCALLTYPE MemoryBarrierProcessWide();
};
class ManagedLoggingHelper {
public:
static FCDECL6(INT32, GetRegistryLoggingValues, CLR_BOOL* bLoggingEnabled, CLR_BOOL* bLogToConsole, INT32 *bLogLevel, CLR_BOOL* bPerfWarnings, CLR_BOOL* bCorrectnessWarnings, CLR_BOOL* bSafeHandleStackTraces);
};
class ValueTypeHelper {
public:
static FCDECL1(FC_BOOL_RET, CanCompareBits, Object* obj);
static FCDECL2(FC_BOOL_RET, FastEqualsCheck, Object* obj1, Object* obj2);
static FCDECL1(INT32, GetHashCode, Object* objRef);
static FCDECL1(INT32, GetHashCodeOfPtr, LPVOID ptr);
};
typedef const BYTE * PCBYTE;
class COMNlsHashProvider {
public:
COMNlsHashProvider();
INT32 HashString(LPCWSTR szStr, SIZE_T strLen);
INT32 HashSortKey(PCBYTE pSrc, SIZE_T cbSrc);
static COMNlsHashProvider s_NlsHashProvider;
private:
PBYTE pEntropy;
PCSYMCRYPT_MARVIN32_EXPANDED_SEED pDefaultSeed;
PCBYTE GetEntropy();
PCSYMCRYPT_MARVIN32_EXPANDED_SEED GetDefaultSeed();
void InitializeDefaultSeed();
};
#ifdef FEATURE_COREFX_GLOBALIZATION
class CoreFxGlobalization {
public:
static INT32 QCALLTYPE HashSortKey(PCBYTE pSortKey, INT32 cbSortKey);
};
#endif // FEATURE_COREFX_GLOBALIZATION
class StreamNative {
public:
static FCDECL1(FC_BOOL_RET, HasOverriddenBeginEndRead, Object *stream);
static FCDECL1(FC_BOOL_RET, HasOverriddenBeginEndWrite, Object *stream);
};
#endif // _COMUTILNATIVE_H_
|