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
116typedef VPTR(class LoaderAllocator) PTR_LoaderAllocator;
117typedef VPTR(class AppDomain) PTR_AppDomain;
118typedef VPTR(class AppDomainBaseObject) PTR_AppDomainBaseObject;
119typedef DPTR(class ArrayBase) PTR_ArrayBase;
120typedef DPTR(class ArrayTypeDesc) PTR_ArrayTypeDesc;
121typedef DPTR(class Assembly) PTR_Assembly;
122typedef DPTR(class AssemblyBaseObject) PTR_AssemblyBaseObject;
123typedef DPTR(class AssemblyNameBaseObject) PTR_AssemblyNameBaseObject;
124typedef VPTR(class BaseDomain) PTR_BaseDomain;
125typedef DPTR(class ClassLoader) PTR_ClassLoader;
126typedef DPTR(class ComCallMethodDesc) PTR_ComCallMethodDesc;
127typedef VPTR(class CompilationDomain) PTR_CompilationDomain;
128typedef DPTR(class ComPlusCallMethodDesc) PTR_ComPlusCallMethodDesc;
129typedef VPTR(class DebugInterface) PTR_DebugInterface;
130typedef DPTR(class Dictionary) PTR_Dictionary;
131typedef VPTR(class DomainAssembly) PTR_DomainAssembly;
132typedef VPTR(class DomainFile) PTR_DomainFile;
133typedef VPTR(class DomainModule) PTR_DomainModule;
134typedef DPTR(struct FailedAssembly) PTR_FailedAssembly;
135typedef VPTR(class EditAndContinueModule) PTR_EditAndContinueModule;
136typedef DPTR(class EEClass) PTR_EEClass;
137typedef DPTR(class DelegateEEClass) PTR_DelegateEEClass;
138typedef DPTR(struct DomainLocalModule) PTR_DomainLocalModule;
139typedef VPTR(class EECodeManager) PTR_EECodeManager;
140typedef DPTR(class EEConfig) PTR_EEConfig;
141typedef VPTR(class EEDbgInterfaceImpl) PTR_EEDbgInterfaceImpl;
142typedef VPTR(class DebugInfoManager) PTR_DebugInfoManager;
143typedef DPTR(class FieldDesc) PTR_FieldDesc;
144typedef VPTR(class Frame) PTR_Frame;
145typedef VPTR(class ICodeManager) PTR_ICodeManager;
146typedef VPTR(class IJitManager) PTR_IJitManager;
147typedef VPTR(struct IUnknown) PTR_IUnknown;
148typedef DPTR(class InstMethodHashTable) PTR_InstMethodHashTable;
149typedef DPTR(class MetaSig) PTR_MetaSig;
150typedef DPTR(class MethodDesc) PTR_MethodDesc;
151typedef DPTR(class MethodDescChunk) PTR_MethodDescChunk;
152typedef DPTR(class MethodImpl) PTR_MethodImpl;
153typedef DPTR(class MethodTable) PTR_MethodTable;
154typedef DPTR(class MscorlibBinder) PTR_MscorlibBinder;
155typedef VPTR(class Module) PTR_Module;
156typedef DPTR(class NDirectMethodDesc) PTR_NDirectMethodDesc;
157typedef VPTR(class Thread) PTR_Thread;
158typedef DPTR(class Object) PTR_Object;
159typedef DPTR(PTR_Object) PTR_PTR_Object;
160typedef DPTR(class ObjHeader) PTR_ObjHeader;
161typedef DPTR(class Precode) PTR_Precode;
162typedef VPTR(class ReflectionModule) PTR_ReflectionModule;
163typedef DPTR(class ReflectClassBaseObject) PTR_ReflectClassBaseObject;
164typedef DPTR(class ReflectMethodObject) PTR_ReflectMethodObject;
165typedef DPTR(class ReflectFieldObject) PTR_ReflectFieldObject;
166typedef DPTR(class ReflectModuleBaseObject) PTR_ReflectModuleBaseObject;
167typedef DPTR(class ReJitManager) PTR_ReJitManager;
168typedef DPTR(struct ReJitInfo) PTR_ReJitInfo;
169typedef DPTR(struct SharedReJitInfo) PTR_SharedReJitInfo;
170typedef DPTR(class StringObject) PTR_StringObject;
171typedef DPTR(class TypeHandle) PTR_TypeHandle;
172typedef VPTR(class VirtualCallStubManager) PTR_VirtualCallStubManager;
173typedef VPTR(class VirtualCallStubManagerManager) PTR_VirtualCallStubManagerManager;
174typedef VPTR(class IGCHeap) PTR_IGCHeap;
175
176//
177// _UNCHECKED_OBJECTREF is for code that can't deal with DEBUG OBJECTREFs
178//
179typedef PTR_Object _UNCHECKED_OBJECTREF;
180typedef DPTR(PTR_Object) PTR_UNCHECKED_OBJECTREF;
181
182#ifdef USE_CHECKED_OBJECTREFS
183class OBJECTREF;
184#else
185typedef PTR_Object OBJECTREF;
186#endif
187typedef DPTR(OBJECTREF) PTR_OBJECTREF;
188typedef DPTR(PTR_OBJECTREF) PTR_PTR_OBJECTREF;
189
190EXTERN_C Thread* STDCALL GetThread();
191BOOL 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().
196const bool CURRENT_THREAD_AVAILABLE = false;
197Thread * 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
210EXTERN_C AppDomain* STDCALL GetAppDomain();
211#endif //!DACCESS_COMPILE
212
213inline void RetailBreak()
214{
215#ifdef _TARGET_X86_
216 __asm int 3
217#else
218 DebugBreak();
219#endif
220}
221
222extern 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
228FORCEINLINE 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
276namespace 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
383inline 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
393inline VOID UnsafeEELeaveCriticalSection(LPCRITICAL_SECTION lpCriticalSection)
394{
395 STATIC_CONTRACT_NOTHROW;
396 STATIC_CONTRACT_GC_NOTRIGGER;
397
398 UnsafeLeaveCriticalSection(lpCriticalSection);
399 DECTHREADLOCKCOUNT();
400}
401
402inline 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
418HRESULT EnsureRtlFunctions();
419HINSTANCE 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
439void 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.
446struct DummyGlobalContract
447{
448 int *m_CannotThrowLineNums; //= NULL;
449 LPVOID *m_CannotThrowRecords; //= NULL;
450};
451
452extern 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
483extern INT64 g_PauseTime; // Total duration of all pauses in the runtime
484extern Volatile<BOOL> g_IsPaused; // True if the runtime is Paused for FAS
485extern CLREventStatic g_ClrResumeEvent; // Event fired when the runtime is resumed after a Pause for FAS
486INT64 AdditionalWait(INT64 sPauseTime, INT64 sTime, INT64 expDuration);
487
488#endif // !_common_h_
489
490
491