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 | // common.h - precompiled headers include for the COM+ Execution Engine |
6 | // |
7 | |
8 | // |
9 | |
10 | |
11 | #ifndef _common_h_ |
12 | #define _common_h_ |
13 | |
14 | #if defined(_MSC_VER) && defined(_X86_) && !defined(FPO_ON) |
15 | #pragma optimize("y", on) // Small critical routines, don't put in EBP frame |
16 | #define FPO_ON 1 |
17 | #define COMMON_TURNED_FPO_ON 1 |
18 | #endif |
19 | |
20 | #define USE_COM_CONTEXT_DEF |
21 | |
22 | #if defined(_DEBUG) && !defined(CROSSGEN_COMPILE) |
23 | #define DEBUG_REGDISPLAY |
24 | #endif |
25 | |
26 | #ifdef _MSC_VER |
27 | |
28 | // These don't seem useful, so turning them off is no big deal |
29 | #pragma warning(disable:4201) // nameless struct/union |
30 | #pragma warning(disable:4510) // can't generate default constructor |
31 | //#pragma warning(disable:4511) // can't generate copy constructor |
32 | #pragma warning(disable:4512) // can't generate assignment constructor |
33 | #pragma warning(disable:4610) // user defined constructor required |
34 | #pragma warning(disable:4211) // nonstandard extention used (char name[0] in structs) |
35 | #pragma warning(disable:4268) // 'const' static/global data initialized with compiler generated default constructor fills the object with zeros |
36 | #pragma warning(disable:4238) // nonstandard extension used : class rvalue used as lvalue |
37 | #pragma warning(disable:4291) // no matching operator delete found |
38 | #pragma warning(disable:4345) // behavior change: an object of POD type constructed with an initializer of the form () will be default-initialized |
39 | |
40 | // Depending on the code base, you may want to not disable these |
41 | #pragma warning(disable:4245) // assigning signed / unsigned |
42 | //#pragma warning(disable:4146) // unary minus applied to unsigned |
43 | //#pragma warning(disable:4244) // loss of data int -> char .. |
44 | #pragma warning(disable:4127) // conditional expression is constant |
45 | #pragma warning(disable:4100) // unreferenced formal parameter |
46 | |
47 | #pragma warning(1:4189) // local variable initialized but not used |
48 | |
49 | #ifndef DEBUG |
50 | #pragma warning(disable:4505) // unreferenced local function has been removed |
51 | //#pragma warning(disable:4702) // unreachable code |
52 | #pragma warning(disable:4313) // 'format specifier' in format string conflicts with argument %d of type 'type' |
53 | #endif // !DEBUG |
54 | |
55 | // CONSIDER put these back in |
56 | #pragma warning(disable:4063) // bad switch value for enum (only in Disasm.cpp) |
57 | #pragma warning(disable:4710) // function not inlined |
58 | #pragma warning(disable:4527) // user-defined destructor required |
59 | #pragma warning(disable:4513) // destructor could not be generated |
60 | |
61 | // <TODO>TODO we really probably need this one put back in!!!</TODO> |
62 | //#pragma warning(disable:4701) // local variable may be used without being initialized |
63 | #endif // _MSC_VER |
64 | |
65 | #define _CRT_DEPENDENCY_ //this code depends on the crt file functions |
66 | |
67 | |
68 | #include <stdint.h> |
69 | #include <stddef.h> |
70 | #include <winwrap.h> |
71 | |
72 | |
73 | #include <windef.h> |
74 | #include <winnt.h> |
75 | #include <stdlib.h> |
76 | #include <wchar.h> |
77 | #include <objbase.h> |
78 | #include <stddef.h> |
79 | #include <float.h> |
80 | #include <math.h> |
81 | #include <time.h> |
82 | #include <limits.h> |
83 | #include <assert.h> |
84 | |
85 | #include <olectl.h> |
86 | |
87 | #ifdef _MSC_VER |
88 | //non inline intrinsics are faster |
89 | #pragma function(memcpy,memcmp,strcmp,strcpy,strlen,strcat) |
90 | #endif // _MSC_VER |
91 | |
92 | #include "volatile.h" |
93 | |
94 | // make all the unsafe redefinitions available |
95 | #include "unsafe.h" |
96 | |
97 | #include <../../debug/inc/dbgtargetcontext.h> |
98 | |
99 | //----------------------------------------------------------------------------------------------------------- |
100 | |
101 | #include "strongname.h" |
102 | #include "stdmacros.h" |
103 | |
104 | #define POISONC ((UINT_PTR)((sizeof(int *) == 4)?0xCCCCCCCCL:I64(0xCCCCCCCCCCCCCCCC))) |
105 | |
106 | #include "ndpversion.h" |
107 | #include "switches.h" |
108 | #include "holder.h" |
109 | #include "classnames.h" |
110 | #include "util.hpp" |
111 | #include "corpriv.h" |
112 | //#include "WarningControl.h" |
113 | |
114 | #include <daccess.h> |
115 | |
116 | typedef VPTR(class LoaderAllocator) PTR_LoaderAllocator; |
117 | typedef VPTR(class AppDomain) PTR_AppDomain; |
118 | typedef VPTR(class AppDomainBaseObject) PTR_AppDomainBaseObject; |
119 | typedef DPTR(class ArrayBase) PTR_ArrayBase; |
120 | typedef DPTR(class ArrayTypeDesc) PTR_ArrayTypeDesc; |
121 | typedef DPTR(class Assembly) PTR_Assembly; |
122 | typedef DPTR(class AssemblyBaseObject) PTR_AssemblyBaseObject; |
123 | typedef DPTR(class AssemblyNameBaseObject) PTR_AssemblyNameBaseObject; |
124 | typedef VPTR(class BaseDomain) PTR_BaseDomain; |
125 | typedef DPTR(class ClassLoader) PTR_ClassLoader; |
126 | typedef DPTR(class ComCallMethodDesc) PTR_ComCallMethodDesc; |
127 | typedef VPTR(class CompilationDomain) PTR_CompilationDomain; |
128 | typedef DPTR(class ComPlusCallMethodDesc) PTR_ComPlusCallMethodDesc; |
129 | typedef VPTR(class DebugInterface) PTR_DebugInterface; |
130 | typedef DPTR(class Dictionary) PTR_Dictionary; |
131 | typedef VPTR(class DomainAssembly) PTR_DomainAssembly; |
132 | typedef VPTR(class DomainFile) PTR_DomainFile; |
133 | typedef VPTR(class DomainModule) PTR_DomainModule; |
134 | typedef DPTR(struct FailedAssembly) PTR_FailedAssembly; |
135 | typedef VPTR(class EditAndContinueModule) PTR_EditAndContinueModule; |
136 | typedef DPTR(class EEClass) PTR_EEClass; |
137 | typedef DPTR(class DelegateEEClass) PTR_DelegateEEClass; |
138 | typedef DPTR(struct DomainLocalModule) PTR_DomainLocalModule; |
139 | typedef VPTR(class EECodeManager) PTR_EECodeManager; |
140 | typedef DPTR(class EEConfig) PTR_EEConfig; |
141 | typedef VPTR(class EEDbgInterfaceImpl) PTR_EEDbgInterfaceImpl; |
142 | typedef VPTR(class DebugInfoManager) PTR_DebugInfoManager; |
143 | typedef DPTR(class FieldDesc) PTR_FieldDesc; |
144 | typedef VPTR(class Frame) PTR_Frame; |
145 | typedef VPTR(class ICodeManager) PTR_ICodeManager; |
146 | typedef VPTR(class IJitManager) PTR_IJitManager; |
147 | typedef VPTR(struct IUnknown) PTR_IUnknown; |
148 | typedef DPTR(class InstMethodHashTable) PTR_InstMethodHashTable; |
149 | typedef DPTR(class MetaSig) PTR_MetaSig; |
150 | typedef DPTR(class MethodDesc) PTR_MethodDesc; |
151 | typedef DPTR(class MethodDescChunk) PTR_MethodDescChunk; |
152 | typedef DPTR(class MethodImpl) PTR_MethodImpl; |
153 | typedef DPTR(class MethodTable) PTR_MethodTable; |
154 | typedef DPTR(class MscorlibBinder) PTR_MscorlibBinder; |
155 | typedef VPTR(class Module) PTR_Module; |
156 | typedef DPTR(class NDirectMethodDesc) PTR_NDirectMethodDesc; |
157 | typedef VPTR(class Thread) PTR_Thread; |
158 | typedef DPTR(class Object) PTR_Object; |
159 | typedef DPTR(PTR_Object) PTR_PTR_Object; |
160 | typedef DPTR(class ObjHeader) PTR_ObjHeader; |
161 | typedef DPTR(class Precode) PTR_Precode; |
162 | typedef VPTR(class ReflectionModule) PTR_ReflectionModule; |
163 | typedef DPTR(class ReflectClassBaseObject) PTR_ReflectClassBaseObject; |
164 | typedef DPTR(class ReflectMethodObject) PTR_ReflectMethodObject; |
165 | typedef DPTR(class ReflectFieldObject) PTR_ReflectFieldObject; |
166 | typedef DPTR(class ReflectModuleBaseObject) PTR_ReflectModuleBaseObject; |
167 | typedef DPTR(class ReJitManager) PTR_ReJitManager; |
168 | typedef DPTR(struct ReJitInfo) PTR_ReJitInfo; |
169 | typedef DPTR(struct SharedReJitInfo) PTR_SharedReJitInfo; |
170 | typedef DPTR(class StringObject) PTR_StringObject; |
171 | typedef DPTR(class TypeHandle) PTR_TypeHandle; |
172 | typedef VPTR(class VirtualCallStubManager) PTR_VirtualCallStubManager; |
173 | typedef VPTR(class VirtualCallStubManagerManager) PTR_VirtualCallStubManagerManager; |
174 | typedef VPTR(class IGCHeap) PTR_IGCHeap; |
175 | |
176 | // |
177 | // _UNCHECKED_OBJECTREF is for code that can't deal with DEBUG OBJECTREFs |
178 | // |
179 | typedef PTR_Object _UNCHECKED_OBJECTREF; |
180 | typedef DPTR(PTR_Object) PTR_UNCHECKED_OBJECTREF; |
181 | |
182 | #ifdef USE_CHECKED_OBJECTREFS |
183 | class OBJECTREF; |
184 | #else |
185 | typedef PTR_Object OBJECTREF; |
186 | #endif |
187 | typedef DPTR(OBJECTREF) PTR_OBJECTREF; |
188 | typedef DPTR(PTR_OBJECTREF) PTR_PTR_OBJECTREF; |
189 | |
190 | EXTERN_C Thread* STDCALL GetThread(); |
191 | BOOL SetThread(Thread*); |
192 | |
193 | // This is a mechanism by which macros can make the Thread pointer available to inner scopes |
194 | // that is robust to code changes. If the outer Thread no longer is available for some reason |
195 | // (e.g. code refactoring), this GET_THREAD() macro will fall back to calling GetThread(). |
196 | const bool CURRENT_THREAD_AVAILABLE = false; |
197 | Thread * const CURRENT_THREAD = NULL; |
198 | #define GET_THREAD() (CURRENT_THREAD_AVAILABLE ? CURRENT_THREAD : GetThread()) |
199 | |
200 | #define MAKE_CURRENT_THREAD_AVAILABLE() \ |
201 | Thread * __pThread = GET_THREAD(); \ |
202 | MAKE_CURRENT_THREAD_AVAILABLE_EX(__pThread) |
203 | |
204 | #define MAKE_CURRENT_THREAD_AVAILABLE_EX(__pThread) \ |
205 | Thread * CURRENT_THREAD = __pThread; \ |
206 | const bool CURRENT_THREAD_AVAILABLE = true; \ |
207 | (void)CURRENT_THREAD_AVAILABLE; /* silence "local variable initialized but not used" warning */ \ |
208 | |
209 | #ifndef DACCESS_COMPILE |
210 | EXTERN_C AppDomain* STDCALL GetAppDomain(); |
211 | #endif //!DACCESS_COMPILE |
212 | |
213 | inline void RetailBreak() |
214 | { |
215 | #ifdef _TARGET_X86_ |
216 | __asm int 3 |
217 | #else |
218 | DebugBreak(); |
219 | #endif |
220 | } |
221 | |
222 | extern BOOL isMemoryReadable(const TADDR start, unsigned len); |
223 | |
224 | #ifndef memcpyUnsafe_f |
225 | #define memcpyUnsafe_f |
226 | |
227 | // use this when you want to memcpy something that contains GC refs |
228 | FORCEINLINE void* memcpyUnsafe(void *dest, const void *src, size_t len) |
229 | { |
230 | WRAPPER_NO_CONTRACT; |
231 | return memcpy(dest, src, len); |
232 | } |
233 | |
234 | #endif // !memcpyUnsafe_f |
235 | |
236 | // |
237 | // By default logging, and debug GC are enabled under debug |
238 | // |
239 | // These can be enabled in non-debug by removing the #ifdef _DEBUG |
240 | // allowing one to log/check_gc a free build. |
241 | // |
242 | #if defined(_DEBUG) && !defined(DACCESS_COMPILE) && !defined(CROSSGEN_COMPILE) |
243 | |
244 | //If memcpy has been defined to PAL_memcpy, we undefine it so that this case |
245 | //can be covered by the if !defined(memcpy) block below |
246 | #ifdef FEATURE_PAL |
247 | #if IS_REDEFINED_IN_PAL(memcpy) |
248 | #undef memcpy |
249 | #endif //IS_REDEFINED_IN_PAL |
250 | #endif //FEATURE_PAL |
251 | |
252 | // You should be using CopyValueClass if you are doing an memcpy |
253 | // in the CG heap. |
254 | #if !defined(memcpy) |
255 | FORCEINLINE void* memcpyNoGCRefs(void * dest, const void * src, size_t len) { |
256 | WRAPPER_NO_CONTRACT; |
257 | |
258 | #ifndef FEATURE_PAL |
259 | return memcpy(dest, src, len); |
260 | #else //FEATURE_PAL |
261 | return PAL_memcpy(dest, src, len); |
262 | #endif //FEATURE_PAL |
263 | |
264 | } |
265 | extern "C" void * __cdecl GCSafeMemCpy(void *, const void *, size_t); |
266 | #define memcpy(dest, src, len) GCSafeMemCpy(dest, src, len) |
267 | #endif // !defined(memcpy) |
268 | #else // !_DEBUG && !DACCESS_COMPILE && !CROSSGEN_COMPILE |
269 | FORCEINLINE void* memcpyNoGCRefs(void * dest, const void * src, size_t len) { |
270 | WRAPPER_NO_CONTRACT; |
271 | |
272 | return memcpy(dest, src, len); |
273 | } |
274 | #endif // !_DEBUG && !DACCESS_COMPILE && !CROSSGEN_COMPILE |
275 | |
276 | namespace Loader |
277 | { |
278 | typedef enum |
279 | { |
280 | Load, //should load |
281 | DontLoad, //should not load |
282 | SafeLookup //take no locks, no allocations |
283 | } LoadFlag; |
284 | } |
285 | |
286 | // src/inc |
287 | #include "utilcode.h" |
288 | #include "log.h" |
289 | #include "loaderheap.h" |
290 | #include "fixuppointer.h" |
291 | #include "lazycow.h" |
292 | |
293 | // src/vm |
294 | #include "gcenv.interlocked.h" |
295 | #include "gcenv.interlocked.inl" |
296 | |
297 | #include "util.hpp" |
298 | #include "ibclogger.h" |
299 | #include "eepolicy.h" |
300 | |
301 | #include "vars.hpp" |
302 | #include "crst.h" |
303 | #include "argslot.h" |
304 | #include "stublink.h" |
305 | #include "cgensys.h" |
306 | #include "ceemain.h" |
307 | #include "hash.h" |
308 | #include "eecontract.h" |
309 | #include "pedecoder.h" |
310 | #include "sstring.h" |
311 | #include "slist.h" |
312 | #include "yieldprocessornormalized.h" |
313 | |
314 | #include "eeconfig.h" |
315 | |
316 | #include "spinlock.h" |
317 | #include "declsec.h" |
318 | |
319 | #ifdef FEATURE_COMINTEROP |
320 | #include "stdinterfaces.h" |
321 | #endif |
322 | |
323 | #include "typehandle.h" |
324 | #include "perfcounters.h" |
325 | #include "methodtable.h" |
326 | #include "typectxt.h" |
327 | |
328 | #include "eehash.h" |
329 | |
330 | #include "vars.hpp" |
331 | #include "eventstore.hpp" |
332 | |
333 | #include "synch.h" |
334 | #include "regdisp.h" |
335 | #include "stackframe.h" |
336 | #include "gms.h" |
337 | #include "stackprobe.h" |
338 | #include "fcall.h" |
339 | #include "syncblk.h" |
340 | #include "gcdesc.h" |
341 | #include "specialstatics.h" |
342 | #include "object.h" // <NICE> We should not really need to put this so early... </NICE> |
343 | #include "gchelpers.h" |
344 | #include "pefile.h" |
345 | #include "clrex.h" |
346 | #include "clsload.hpp" // <NICE> We should not really need to put this so early... </NICE> |
347 | #include "siginfo.hpp" |
348 | #include "binder.h" |
349 | #include "jitinterface.h" // <NICE> We should not really need to put this so early... </NICE> |
350 | #include "ceeload.h" |
351 | #include "memberload.h" |
352 | #include "genericdict.h" |
353 | #include "class.h" |
354 | #include "codeman.h" |
355 | #include "threads.h" |
356 | #include "clrex.inl" |
357 | #ifdef FEATURE_COMINTEROP |
358 | #include "windowsruntime.h" |
359 | #include "windowsstring.h" |
360 | #endif |
361 | #include "loaderallocator.hpp" |
362 | #include "appdomain.hpp" |
363 | #include "appdomain.inl" |
364 | #include "assembly.hpp" |
365 | #include "pefile.inl" |
366 | #include "excep.h" |
367 | #include "method.hpp" |
368 | #include "callingconvention.h" |
369 | #include "frames.h" |
370 | #include "qcall.h" |
371 | #include "callhelpers.h" |
372 | |
373 | #include "stackwalk.h" |
374 | #include "stackingallocator.h" |
375 | #include "interoputil.h" |
376 | #include "wrappers.h" |
377 | #include "dynamicmethod.h" |
378 | |
379 | #include "gcstress.h" |
380 | |
381 | #ifndef DACCESS_COMPILE |
382 | |
383 | inline VOID UnsafeEEEnterCriticalSection(LPCRITICAL_SECTION lpCriticalSection) |
384 | { |
385 | STATIC_CONTRACT_NOTHROW; |
386 | STATIC_CONTRACT_GC_NOTRIGGER; |
387 | STATIC_CONTRACT_CAN_TAKE_LOCK; |
388 | |
389 | UnsafeEnterCriticalSection(lpCriticalSection); |
390 | INCTHREADLOCKCOUNT(); |
391 | } |
392 | |
393 | inline VOID UnsafeEELeaveCriticalSection(LPCRITICAL_SECTION lpCriticalSection) |
394 | { |
395 | STATIC_CONTRACT_NOTHROW; |
396 | STATIC_CONTRACT_GC_NOTRIGGER; |
397 | |
398 | UnsafeLeaveCriticalSection(lpCriticalSection); |
399 | DECTHREADLOCKCOUNT(); |
400 | } |
401 | |
402 | inline BOOL UnsafeEETryEnterCriticalSection(LPCRITICAL_SECTION lpCriticalSection) |
403 | { |
404 | STATIC_CONTRACT_NOTHROW; |
405 | STATIC_CONTRACT_GC_NOTRIGGER; |
406 | STATIC_CONTRACT_CAN_TAKE_LOCK; |
407 | |
408 | BOOL fEnteredCriticalSection = UnsafeTryEnterCriticalSection(lpCriticalSection); |
409 | if(fEnteredCriticalSection) |
410 | { |
411 | INCTHREADLOCKCOUNT(); |
412 | } |
413 | return fEnteredCriticalSection; |
414 | } |
415 | |
416 | #endif // !DACCESS_COMPILE |
417 | |
418 | HRESULT EnsureRtlFunctions(); |
419 | HINSTANCE GetModuleInst(); |
420 | |
421 | #if defined(_TARGET_X86_) || defined(_TARGET_AMD64_) |
422 | // |
423 | // Strong memory model. No memory barrier necessary before writing object references into GC heap. |
424 | // |
425 | #define GCHeapMemoryBarrier() |
426 | #else |
427 | // |
428 | // The weak memory model forces us to raise memory barriers before writing object references into GC heap. This is required |
429 | // for both security and to make most managed code written against strong memory model work. Under normal circumstances, this memory |
430 | // barrier is part of GC write barrier. However, there are a few places in the VM that set cards manually without going through |
431 | // regular GC write barrier. These places need to this macro. This macro is usually used before memcpy-like operation followed |
432 | // by SetCardsAfterBulkCopy. |
433 | // |
434 | #define GCHeapMemoryBarrier() MemoryBarrier() |
435 | #endif |
436 | |
437 | |
438 | // use this when you want to memcpy something that contains GC refs |
439 | void memmoveGCRefs(void *dest, const void *src, size_t len); |
440 | |
441 | |
442 | #if defined(_DEBUG) |
443 | |
444 | // This catches CANNOTTHROW macros that occur outside the scope of a CONTRACT. |
445 | // Note that it's important for m_CannotThrowLineNums to be NULL. |
446 | struct DummyGlobalContract |
447 | { |
448 | int *m_CannotThrowLineNums; //= NULL; |
449 | LPVOID *m_CannotThrowRecords; //= NULL; |
450 | }; |
451 | |
452 | extern DummyGlobalContract ___contract; |
453 | |
454 | #endif // defined(_DEBUG) |
455 | |
456 | |
457 | // All files get to see all of these .inl files to make sure all files |
458 | // get the benefit of inlining. |
459 | #include "ceeload.inl" |
460 | #include "typedesc.inl" |
461 | #include "class.inl" |
462 | #include "methodtable.inl" |
463 | #include "typehandle.inl" |
464 | #include "object.inl" |
465 | #include "clsload.inl" |
466 | #include "domainfile.inl" |
467 | #include "method.inl" |
468 | #include "stackprobe.inl" |
469 | #include "syncblk.inl" |
470 | #include "threads.inl" |
471 | #include "eehash.inl" |
472 | #ifdef FEATURE_COMINTEROP |
473 | #include "WinRTRedirector.h" |
474 | #include "winrtredirector.inl" |
475 | #endif // FEATURE_COMINTEROP |
476 | |
477 | #if defined(COMMON_TURNED_FPO_ON) |
478 | #pragma optimize("", on) // Go back to command line default optimizations |
479 | #undef COMMON_TURNED_FPO_ON |
480 | #undef FPO_ON |
481 | #endif |
482 | |
483 | extern INT64 g_PauseTime; // Total duration of all pauses in the runtime |
484 | extern Volatile<BOOL> g_IsPaused; // True if the runtime is Paused for FAS |
485 | extern CLREventStatic g_ClrResumeEvent; // Event fired when the runtime is resumed after a Pause for FAS |
486 | INT64 AdditionalWait(INT64 sPauseTime, INT64 sTime, INT64 expDuration); |
487 | |
488 | #endif // !_common_h_ |
489 | |
490 | |
491 | |