617785de94db26ad08310ae8ece421566e203e4d
[platform/upstream/coreclr.git] / src / vm / comutilnative.h
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.
4 //
5
6 //
7
8 /*============================================================
9 **
10 ** Header:  COMUtilNative
11 ** 
12 **
13 ** Purpose: A dumping ground for classes which aren't large
14 ** enough to get their own file in the VM.
15 **
16 **
17 ===========================================================*/
18 #ifndef _COMUTILNATIVE_H_
19 #define _COMUTILNATIVE_H_
20
21 #include "object.h"
22 #include "util.hpp"
23 #include "cgensys.h"
24 #include "fcall.h"
25 #include "qcall.h"
26 #include "windows.h"
27 #undef GetCurrentTime
28
29
30 #pragma warning(push)
31 #pragma warning(disable:4324)
32 #if !defined(CROSS_COMPILE) && defined(_TARGET_ARM_) && !defined(PLATFORM_UNIX)
33 #include "arm_neon.h"
34 #endif
35 #include "marvin32.h"
36 #pragma warning(pop)
37
38 //
39 //
40 // EXCEPTION NATIVE
41 //
42 //
43
44 void FreeExceptionData(ExceptionData *pedata);
45
46 class ExceptionNative
47 {
48 private:
49     enum ExceptionMessageKind {
50         ThreadAbort = 1,
51         ThreadInterrupted = 2,
52         OutOfMemory = 3
53     };
54
55 public:
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);
65
66
67     // NOTE: caller cleans up any partially initialized BSTRs in pED
68     static void      GetExceptionData(OBJECTREF, ExceptionData *);
69
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);
73 };
74
75 class MemoryNative
76 {
77 public:
78     static void QCALLTYPE Clear(void *dst, size_t length);
79     static FCDECL3(VOID, BulkMoveWithWriteBarrier, void *dst, void *src, size_t byteCount);
80 };
81
82 //
83 // Buffer
84 //
85 class Buffer {
86 public:
87
88     // BlockCopy
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);
96
97     static void QCALLTYPE MemMove(void *dst, void *src, size_t length);
98 };
99
100 #define MIN_GC_MEMORYPRESSURE_THRESHOLD 100000
101 #define RELATIVE_GC_RATIO 8
102
103 const UINT NEW_PRESSURE_COUNT = 4;
104
105 class GCInterface {
106 private:
107
108     static MethodDesc *m_pCacheMethod;
109     static UINT64   m_ulMemPressure;
110     static UINT64   m_ulThreshold;
111     static INT32    m_gc_counts[3];
112
113     static UINT64   m_addPressure[NEW_PRESSURE_COUNT];
114     static UINT64   m_remPressure[NEW_PRESSURE_COUNT];
115     static UINT     m_iteration;
116     
117 public:
118     static CrstStatic m_MemoryPressureLock;
119
120     static FORCEINLINE UINT64 InterlockedAdd(UINT64 *pAugend, UINT64 addend);
121     static FORCEINLINE UINT64 InterlockedSub(UINT64 *pMinuend, UINT64 subtrahend);
122
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);
133
134     static 
135     INT64 QCALLTYPE GetTotalMemory();
136
137     static 
138     void QCALLTYPE Collect(INT32 generation, INT32 mode);
139
140     static
141     void QCALLTYPE WaitForPendingFinalizers();
142
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);
148     
149     static FCDECL0(INT64,    GetAllocatedBytesForCurrentThread);
150
151     static 
152     int QCALLTYPE StartNoGCRegion(INT64 totalSize, BOOL lohSizeKnown, INT64 lohSize, BOOL disallowFullBlockingGC);
153
154     static 
155     int QCALLTYPE EndNoGCRegion();
156
157     static
158     void QCALLTYPE _AddMemoryPressure(UINT64 bytesAllocated);
159     
160     static
161     void QCALLTYPE _RemoveMemoryPressure(UINT64 bytesAllocated);
162
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);
167
168     // New less sensitive implementation of Add/RemoveMemoryPressure:
169     static void CheckCollectionCount();
170     static void NewRemoveMemoryPressure(UINT64 bytesAllocated);
171     static void NewAddMemoryPressure(UINT64 bytesAllocated);
172
173 private:
174     // Out-of-line helper to avoid EH prolog/epilog in functions that otherwise don't throw.
175     NOINLINE static void GarbageCollectModeAny(int generation);
176 };
177
178 class COMInterlocked
179 {
180 public:
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);
196
197         static FCDECL0(void, FCMemoryBarrier);
198         static void QCALLTYPE MemoryBarrierProcessWide();
199 };
200
201 class ValueTypeHelper {
202 public:
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);
207 };
208
209
210 typedef const BYTE  * PCBYTE;
211
212 class COMNlsHashProvider {
213 public:
214     COMNlsHashProvider();
215
216     INT32 HashString(LPCWSTR szStr, SIZE_T strLen);
217     INT32 HashSortKey(PCBYTE pSrc, SIZE_T cbSrc);
218
219     static COMNlsHashProvider s_NlsHashProvider;
220
221 private:
222     PBYTE pEntropy;
223     PCSYMCRYPT_MARVIN32_EXPANDED_SEED pDefaultSeed;
224
225     PCBYTE GetEntropy();
226     PCSYMCRYPT_MARVIN32_EXPANDED_SEED GetDefaultSeed();
227     void InitializeDefaultSeed();
228 };
229
230 #ifdef FEATURE_COREFX_GLOBALIZATION
231 class CoreFxGlobalization {
232 public:
233   static INT32 QCALLTYPE HashSortKey(PCBYTE pSortKey, INT32 cbSortKey);
234 };
235 #endif // FEATURE_COREFX_GLOBALIZATION
236
237 class StreamNative {
238 public:
239     static FCDECL1(FC_BOOL_RET, HasOverriddenBeginEndRead, Object *stream);
240     static FCDECL1(FC_BOOL_RET, HasOverriddenBeginEndWrite, Object *stream);
241 };
242
243 #endif // _COMUTILNATIVE_H_