1 // Licensed to the .NET Foundation under one or more agreements.
2 // The .NET Foundation licenses this file to you under the MIT license.
3 // See the LICENSE file in the project root for more information.
8 /*============================================================
10 ** Header: COMUtilNative
13 ** Purpose: A dumping ground for classes which aren't large
14 ** enough to get their own file in the VM.
17 ===========================================================*/
18 #ifndef _COMUTILNATIVE_H_
19 #define _COMUTILNATIVE_H_
31 #pragma warning(disable:4324)
32 #if !defined(CROSS_COMPILE) && defined(_TARGET_ARM_) && !defined(PLATFORM_UNIX)
44 void FreeExceptionData(ExceptionData *pedata);
49 enum ExceptionMessageKind {
51 ThreadInterrupted = 2,
56 static FCDECL1(FC_BOOL_RET, IsImmutableAgileException, Object* pExceptionUNSAFE);
57 static FCDECL1(FC_BOOL_RET, IsTransient, INT32 hresult);
58 static FCDECL3(StringObject *, StripFileInfo, Object *orefExcepUNSAFE, StringObject *orefStrUNSAFE, CLR_BOOL isRemoteStackTrace);
59 static void QCALLTYPE GetMessageFromNativeResources(ExceptionMessageKind kind, QCall::StringHandleOnStack retMesg);
60 static FCDECL0(VOID, PrepareForForeignExceptionRaise);
61 static FCDECL1(Object*, CopyStackTrace, Object* pStackTraceUNSAFE);
62 static FCDECL1(Object*, CopyDynamicMethods, Object* pDynamicMethodsUNSAFE);
63 static FCDECL3(VOID, GetStackTracesDeepCopy, Object* pExceptionObjectUnsafe, Object **pStackTraceUnsafe, Object **pDynamicMethodsUnsafe);
64 static FCDECL3(VOID, SaveStackTracesFromDeepCopy, Object* pExceptionObjectUnsafe, Object *pStackTraceUnsafe, Object *pDynamicMethodsUnsafe);
67 // NOTE: caller cleans up any partially initialized BSTRs in pED
68 static void GetExceptionData(OBJECTREF, ExceptionData *);
70 // Note: these are on the PInvoke class to hide these from the user.
71 static FCDECL0(EXCEPTION_POINTERS*, GetExceptionPointers);
72 static FCDECL0(INT32, GetExceptionCode);
78 static void QCALLTYPE Clear(void *dst, size_t length);
79 static FCDECL3(VOID, BulkMoveWithWriteBarrier, void *dst, void *src, size_t byteCount);
89 // This method from one primitive array to another based
90 // upon an offset into each an a byte count.
91 static FCDECL5(VOID, BlockCopy, ArrayBase *src, int srcOffset, ArrayBase *dst, int dstOffset, int count);
92 static FCDECL2(FC_UINT8_RET, GetByte, ArrayBase *arrayUNSAFE, INT32 index);
93 static FCDECL3(VOID, SetByte, ArrayBase *arrayUNSAFE, INT32 index, UINT8 bData);
94 static FCDECL1(FC_BOOL_RET, IsPrimitiveTypeArray, ArrayBase *arrayUNSAFE);
95 static FCDECL1(INT32, ByteLength, ArrayBase *arrayUNSAFE);
97 static void QCALLTYPE MemMove(void *dst, void *src, size_t length);
100 #define MIN_GC_MEMORYPRESSURE_THRESHOLD 100000
101 #define RELATIVE_GC_RATIO 8
103 const UINT NEW_PRESSURE_COUNT = 4;
108 static MethodDesc *m_pCacheMethod;
109 static UINT64 m_ulMemPressure;
110 static UINT64 m_ulThreshold;
111 static INT32 m_gc_counts[3];
113 static UINT64 m_addPressure[NEW_PRESSURE_COUNT];
114 static UINT64 m_remPressure[NEW_PRESSURE_COUNT];
115 static UINT m_iteration;
118 static CrstStatic m_MemoryPressureLock;
120 static FORCEINLINE UINT64 InterlockedAdd(UINT64 *pAugend, UINT64 addend);
121 static FORCEINLINE UINT64 InterlockedSub(UINT64 *pMinuend, UINT64 subtrahend);
123 static FCDECL0(int, GetGcLatencyMode);
124 static FCDECL1(int, SetGcLatencyMode, int newLatencyMode);
125 static FCDECL0(int, GetLOHCompactionMode);
126 static FCDECL1(void, SetLOHCompactionMode, int newLOHCompactionyMode);
127 static FCDECL2(FC_BOOL_RET, RegisterForFullGCNotification, UINT32 gen2Percentage, UINT32 lohPercentage);
128 static FCDECL0(FC_BOOL_RET, CancelFullGCNotification);
129 static FCDECL1(int, WaitForFullGCApproach, int millisecondsTimeout);
130 static FCDECL1(int, WaitForFullGCComplete, int millisecondsTimeout);
131 static FCDECL1(int, GetGenerationWR, LPVOID handle);
132 static FCDECL1(int, GetGeneration, Object* objUNSAFE);
135 INT64 QCALLTYPE GetTotalMemory();
138 void QCALLTYPE Collect(INT32 generation, INT32 mode);
141 void QCALLTYPE WaitForPendingFinalizers();
143 static FCDECL0(int, GetMaxGeneration);
144 static FCDECL1(void, KeepAlive, Object *obj);
145 static FCDECL1(void, SuppressFinalize, Object *obj);
146 static FCDECL1(void, ReRegisterForFinalize, Object *obj);
147 static FCDECL2(int, CollectionCount, INT32 generation, INT32 getSpecialGCCount);
149 static FCDECL0(INT64, GetAllocatedBytesForCurrentThread);
152 int QCALLTYPE StartNoGCRegion(INT64 totalSize, BOOL lohSizeKnown, INT64 lohSize, BOOL disallowFullBlockingGC);
155 int QCALLTYPE EndNoGCRegion();
158 void QCALLTYPE _AddMemoryPressure(UINT64 bytesAllocated);
161 void QCALLTYPE _RemoveMemoryPressure(UINT64 bytesAllocated);
163 static void RemoveMemoryPressure(UINT64 bytesAllocated);
164 static void AddMemoryPressure(UINT64 bytesAllocated);
165 NOINLINE static void SendEtwRemoveMemoryPressureEvent(UINT64 bytesAllocated);
166 static void SendEtwAddMemoryPressureEvent(UINT64 bytesAllocated);
168 // New less sensitive implementation of Add/RemoveMemoryPressure:
169 static void CheckCollectionCount();
170 static void NewRemoveMemoryPressure(UINT64 bytesAllocated);
171 static void NewAddMemoryPressure(UINT64 bytesAllocated);
174 // Out-of-line helper to avoid EH prolog/epilog in functions that otherwise don't throw.
175 NOINLINE static void GarbageCollectModeAny(int generation);
181 static FCDECL2(INT32, Exchange, INT32 *location, INT32 value);
182 static FCDECL2_IV(INT64, Exchange64, INT64 *location, INT64 value);
183 static FCDECL2(LPVOID, ExchangePointer, LPVOID* location, LPVOID value);
184 static FCDECL3(INT32, CompareExchange, INT32* location, INT32 value, INT32 comparand);
185 static FCDECL4(INT32, CompareExchangeReliableResult, INT32* location, INT32 value, INT32 comparand, CLR_BOOL* succeeded);
186 static FCDECL3_IVV(INT64, CompareExchange64, INT64* location, INT64 value, INT64 comparand);
187 static FCDECL3(LPVOID, CompareExchangePointer, LPVOID* location, LPVOID value, LPVOID comparand);
188 static FCDECL2_IV(float, ExchangeFloat, float *location, float value);
189 static FCDECL2_IV(double, ExchangeDouble, double *location, double value);
190 static FCDECL3_IVV(float, CompareExchangeFloat, float *location, float value, float comparand);
191 static FCDECL3_IVV(double, CompareExchangeDouble, double *location, double value, double comparand);
192 static FCDECL2(LPVOID, ExchangeObject, LPVOID* location, LPVOID value);
193 static FCDECL3(LPVOID, CompareExchangeObject, LPVOID* location, LPVOID value, LPVOID comparand);
194 static FCDECL2(INT32, ExchangeAdd32, INT32 *location, INT32 value);
195 static FCDECL2_IV(INT64, ExchangeAdd64, INT64 *location, INT64 value);
197 static FCDECL0(void, FCMemoryBarrier);
198 static void QCALLTYPE MemoryBarrierProcessWide();
201 class ValueTypeHelper {
203 static FCDECL1(FC_BOOL_RET, CanCompareBits, Object* obj);
204 static FCDECL2(FC_BOOL_RET, FastEqualsCheck, Object* obj1, Object* obj2);
205 static FCDECL1(INT32, GetHashCode, Object* objRef);
206 static FCDECL1(INT32, GetHashCodeOfPtr, LPVOID ptr);
210 typedef const BYTE * PCBYTE;
212 class COMNlsHashProvider {
214 COMNlsHashProvider();
216 INT32 HashString(LPCWSTR szStr, SIZE_T strLen);
217 INT32 HashSortKey(PCBYTE pSrc, SIZE_T cbSrc);
219 static COMNlsHashProvider s_NlsHashProvider;
223 PCSYMCRYPT_MARVIN32_EXPANDED_SEED pDefaultSeed;
226 PCSYMCRYPT_MARVIN32_EXPANDED_SEED GetDefaultSeed();
227 void InitializeDefaultSeed();
230 #ifdef FEATURE_COREFX_GLOBALIZATION
231 class CoreFxGlobalization {
233 static INT32 QCALLTYPE HashSortKey(PCBYTE pSortKey, INT32 cbSortKey);
235 #endif // FEATURE_COREFX_GLOBALIZATION
239 static FCDECL1(FC_BOOL_RET, HasOverriddenBeginEndRead, Object *stream);
240 static FCDECL1(FC_BOOL_RET, HasOverriddenBeginEndWrite, Object *stream);
243 #endif // _COMUTILNATIVE_H_