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 | // CGENSYS.H - |
5 | // |
6 | // Generic header for choosing system-dependent helpers |
7 | // |
8 | |
9 | |
10 | |
11 | #ifndef __cgensys_h__ |
12 | #define __cgensys_h__ |
13 | |
14 | class MethodDesc; |
15 | class Stub; |
16 | class Thread; |
17 | class CrawlFrame; |
18 | struct EE_ILEXCEPTION_CLAUSE; |
19 | struct TransitionBlock; |
20 | struct VASigCookie; |
21 | struct CORCOMPILE_EXTERNAL_METHOD_THUNK; |
22 | class ComPlusCallMethodDesc; |
23 | |
24 | #include <cgencpu.h> |
25 | |
26 | |
27 | #ifdef EnC_SUPPORTED |
28 | void ResumeAtJit(PT_CONTEXT pContext, LPVOID oldFP); |
29 | #endif |
30 | |
31 | #if defined(_TARGET_X86_) |
32 | void ResumeAtJitEH (CrawlFrame* pCf, BYTE* startPC, EE_ILEXCEPTION_CLAUSE *EHClausePtr, DWORD nestingLevel, Thread *pThread, BOOL unwindStack); |
33 | int CallJitEHFilter (CrawlFrame* pCf, BYTE* startPC, EE_ILEXCEPTION_CLAUSE *EHClausePtr, DWORD nestingLevel, OBJECTREF thrownObj); |
34 | void CallJitEHFinally(CrawlFrame* pCf, BYTE* startPC, EE_ILEXCEPTION_CLAUSE *EHClausePtr, DWORD nestingLevel); |
35 | #endif // _TARGET_X86_ |
36 | |
37 | //These are in util.cpp |
38 | extern size_t GetLogicalProcessorCacheSizeFromOS(); |
39 | extern size_t GetIntelDeterministicCacheEnum(); |
40 | extern size_t GetIntelDescriptorValuesCache(); |
41 | extern DWORD GetLogicalCpuCountFromOS(); |
42 | extern DWORD GetLogicalCpuCountFallback(); |
43 | |
44 | |
45 | // Try to determine the largest last-level cache size of the machine - return 0 if unknown or no L2/L3 cache |
46 | size_t GetCacheSizePerLogicalCpu(BOOL bTrueSize = TRUE); |
47 | |
48 | |
49 | #ifdef FEATURE_COMINTEROP |
50 | extern "C" UINT32 STDCALL CLRToCOMWorker(TransitionBlock * pTransitionBlock, ComPlusCallMethodDesc * pMD); |
51 | extern "C" void GenericComPlusCallStub(void); |
52 | |
53 | extern "C" void GenericComCallStub(void); |
54 | #endif // FEATURE_COMINTEROP |
55 | |
56 | // Non-CPU-specific helper functions called by the CPU-dependent code |
57 | extern "C" PCODE STDCALL PreStubWorker(TransitionBlock * pTransitionBlock, MethodDesc * pMD); |
58 | |
59 | extern "C" void STDCALL VarargPInvokeStubWorker(TransitionBlock * pTransitionBlock, VASigCookie * pVASigCookie, MethodDesc * pMD); |
60 | extern "C" void STDCALL VarargPInvokeStub(void); |
61 | extern "C" void STDCALL VarargPInvokeStub_RetBuffArg(void); |
62 | |
63 | extern "C" void STDCALL GenericPInvokeCalliStubWorker(TransitionBlock * pTransitionBlock, VASigCookie * pVASigCookie, PCODE pUnmanagedTarget); |
64 | extern "C" void STDCALL GenericPInvokeCalliHelper(void); |
65 | |
66 | extern "C" PCODE STDCALL ExternalMethodFixupWorker(TransitionBlock * pTransitionBlock, TADDR pIndirection, DWORD sectionIndex, Module * pModule); |
67 | extern "C" void STDCALL ExternalMethodFixupStub(void); |
68 | extern "C" void STDCALL ExternalMethodFixupPatchLabel(void); |
69 | |
70 | extern "C" void STDCALL VirtualMethodFixupStub(void); |
71 | extern "C" void STDCALL VirtualMethodFixupPatchLabel(void); |
72 | |
73 | extern "C" void STDCALL TransparentProxyStub(void); |
74 | extern "C" void STDCALL TransparentProxyStub_CrossContext(); |
75 | extern "C" void STDCALL TransparentProxyStubPatchLabel(void); |
76 | |
77 | #ifdef FEATURE_READYTORUN |
78 | extern "C" void STDCALL DelayLoad_MethodCall(); |
79 | |
80 | extern "C" void STDCALL DelayLoad_Helper(); |
81 | extern "C" void STDCALL DelayLoad_Helper_Obj(); |
82 | extern "C" void STDCALL DelayLoad_Helper_ObjObj(); |
83 | #endif |
84 | |
85 | // Returns information about the CPU processor. |
86 | // Note that this information may be the least-common-denominator in the |
87 | // case of a multi-proc machine. |
88 | |
89 | #ifdef _TARGET_X86_ |
90 | void GetSpecificCpuInfo(CORINFO_CPU * cpuInfo); |
91 | #else |
92 | inline void GetSpecificCpuInfo(CORINFO_CPU * cpuInfo) |
93 | { |
94 | LIMITED_METHOD_CONTRACT; |
95 | cpuInfo->dwCPUType = 0; |
96 | cpuInfo->dwFeatures = 0; |
97 | cpuInfo->dwExtendedFeatures = 0; |
98 | } |
99 | |
100 | #endif // !_TARGET_X86_ |
101 | |
102 | #if (defined(_TARGET_X86_) || defined(_TARGET_AMD64_)) && !defined(CROSSGEN_COMPILE) |
103 | extern "C" DWORD __stdcall getcpuid(DWORD arg, unsigned char result[16]); |
104 | extern "C" DWORD __stdcall getextcpuid(DWORD arg1, DWORD arg2, unsigned char result[16]); |
105 | extern "C" DWORD __stdcall xmmYmmStateSupport(); |
106 | #endif |
107 | |
108 | inline bool TargetHasAVXSupport() |
109 | { |
110 | #if (defined(_TARGET_X86_) || defined(_TARGET_AMD64_)) && !defined(CROSSGEN_COMPILE) |
111 | unsigned char buffer[16]; |
112 | // All x86/AMD64 targets support cpuid. |
113 | (void) getcpuid(1, buffer); |
114 | // getcpuid executes cpuid with eax set to its first argument, and ecx cleared. |
115 | // It returns the resulting eax, ebx, ecx and edx (in that order) in buffer[]. |
116 | // The AVX feature is ECX bit 28. |
117 | return ((buffer[11] & 0x10) != 0); |
118 | #endif // (defined(_TARGET_X86_) || defined(_TARGET_AMD64_)) && !defined(CROSSGEN_COMPILE) |
119 | return false; |
120 | } |
121 | |
122 | #ifdef FEATURE_PREJIT |
123 | // Can code compiled for "minReqdCpuType" be used on "actualCpuType" |
124 | inline BOOL IsCompatibleCpuInfo(const CORINFO_CPU * actualCpuInfo, |
125 | const CORINFO_CPU * minReqdCpuInfo) |
126 | { |
127 | LIMITED_METHOD_CONTRACT; |
128 | return ((minReqdCpuInfo->dwFeatures & actualCpuInfo->dwFeatures) == |
129 | minReqdCpuInfo->dwFeatures); |
130 | } |
131 | #endif // FEATURE_PREJIT |
132 | |
133 | |
134 | #ifndef DACCESS_COMPILE |
135 | // Given an address in a slot, figure out if the prestub will be called |
136 | BOOL DoesSlotCallPrestub(PCODE pCode); |
137 | #endif |
138 | |
139 | #ifdef DACCESS_COMPILE |
140 | |
141 | // Used by dac/strike to make sense of non-jit/non-jit-helper call targets |
142 | // generated by the runtime. |
143 | BOOL GetAnyThunkTarget (T_CONTEXT *pctx, TADDR *pTarget, TADDR *pTargetMethodDesc); |
144 | |
145 | #endif // DACCESS_COMPILE |
146 | |
147 | |
148 | |
149 | // |
150 | // ResetProcessorStateHolder saves/restores processor state around calls to |
151 | // mscorlib during exception handling. |
152 | // |
153 | class ResetProcessorStateHolder |
154 | { |
155 | #if defined(_TARGET_AMD64_) |
156 | ULONG m_mxcsr; |
157 | #endif |
158 | |
159 | public: |
160 | |
161 | ResetProcessorStateHolder () |
162 | { |
163 | #if defined(_TARGET_AMD64_) |
164 | m_mxcsr = _mm_getcsr(); |
165 | _mm_setcsr(0x1f80); |
166 | #endif // _TARGET_AMD64_ |
167 | } |
168 | |
169 | ~ResetProcessorStateHolder () |
170 | { |
171 | #if defined(_TARGET_AMD64_) |
172 | _mm_setcsr(m_mxcsr); |
173 | #endif // _TARGET_AMD64_ |
174 | } |
175 | }; |
176 | |
177 | |
178 | #endif // !__cgensys_h__ |
179 | |