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 | // vars.hpp |
6 | // |
7 | // Global variables |
8 | // |
9 | |
10 | |
11 | #ifndef _VARS_HPP |
12 | #define _VARS_HPP |
13 | |
14 | // This will need ifdefs for non-x86 processors (ia64 is pointer to 128bit instructions)! |
15 | #define SLOT PBYTE |
16 | typedef DPTR(SLOT) PTR_SLOT; |
17 | |
18 | typedef LPVOID DictionaryEntry; |
19 | |
20 | /* Define the implementation dependent size types */ |
21 | |
22 | #ifndef _INTPTR_T_DEFINED |
23 | #ifdef _WIN64 |
24 | typedef __int64 intptr_t; |
25 | #else |
26 | typedef int intptr_t; |
27 | #endif |
28 | #define _INTPTR_T_DEFINED |
29 | #endif |
30 | |
31 | #ifndef _UINTPTR_T_DEFINED |
32 | #ifdef _WIN64 |
33 | typedef unsigned __int64 uintptr_t; |
34 | #else |
35 | typedef unsigned int uintptr_t; |
36 | #endif |
37 | #define _UINTPTR_T_DEFINED |
38 | #endif |
39 | |
40 | #ifndef _PTRDIFF_T_DEFINED |
41 | #ifdef _WIN64 |
42 | typedef __int64 ptrdiff_t; |
43 | #else |
44 | typedef int ptrdiff_t; |
45 | #endif |
46 | #define _PTRDIFF_T_DEFINED |
47 | #endif |
48 | |
49 | |
50 | #ifndef _SIZE_T_DEFINED |
51 | #ifdef _WIN64 |
52 | typedef unsigned __int64 size_t; |
53 | #else |
54 | typedef unsigned int size_t; |
55 | #endif |
56 | #define _SIZE_T_DEFINED |
57 | #endif |
58 | |
59 | |
60 | #ifndef _WCHAR_T_DEFINED |
61 | typedef unsigned short wchar_t; |
62 | #define _WCHAR_T_DEFINED |
63 | #endif |
64 | |
65 | #include "util.hpp" |
66 | #include <corpriv.h> |
67 | #include <cordbpriv.h> |
68 | |
69 | |
70 | #include "eeprofinterfaces.h" |
71 | #include "eehash.h" |
72 | |
73 | #include "profilepriv.h" |
74 | |
75 | #include "gcinterface.h" |
76 | |
77 | class ClassLoader; |
78 | class LoaderHeap; |
79 | class IGCHeap; |
80 | class Object; |
81 | class StringObject; |
82 | class ArrayClass; |
83 | class MethodTable; |
84 | class MethodDesc; |
85 | class SyncBlockCache; |
86 | class SyncTableEntry; |
87 | class ThreadStore; |
88 | namespace ETW { class CEtwTracer; }; |
89 | class DebugInterface; |
90 | class DebugInfoManager; |
91 | class EEDbgInterfaceImpl; |
92 | class EECodeManager; |
93 | class Crst; |
94 | #ifdef FEATURE_COMINTEROP |
95 | class RCWCleanupList; |
96 | #endif // FEATURE_COMINTEROP |
97 | class BBSweep; |
98 | |
99 | // |
100 | // loader handles are opaque types that track object pointers that have a lifetime |
101 | // that matches that of a loader allocator |
102 | // |
103 | struct LOADERHANDLE__ |
104 | { |
105 | void* unused; |
106 | }; |
107 | typedef TADDR LOADERHANDLE; |
108 | |
109 | |
110 | #ifdef DACCESS_COMPILE |
111 | void OBJECTHANDLE_EnumMemoryRegions(OBJECTHANDLE handle); |
112 | void OBJECTREF_EnumMemoryRegions(OBJECTREF ref); |
113 | #endif |
114 | |
115 | |
116 | #ifdef USE_CHECKED_OBJECTREFS |
117 | |
118 | |
119 | //========================================================================= |
120 | // In the retail build, OBJECTREF is typedef'd to "Object*". |
121 | // In the debug build, we use operator overloading to detect |
122 | // common programming mistakes that create GC holes. The critical |
123 | // rules are: |
124 | // |
125 | // 1. Your thread must have disabled preemptive GC before |
126 | // reading or writing any OBJECTREF. When preemptive GC is enabled, |
127 | // another other thread can suspend you at any time and |
128 | // move or discard objects. |
129 | // 2. You must guard your OBJECTREF's using a root pointer across |
130 | // any code that might trigger a GC. |
131 | // |
132 | // Each of the overloads validate that: |
133 | // |
134 | // 1. Preemptive GC is currently disabled |
135 | // 2. The object looks consistent (checked by comparing the |
136 | // object's methodtable pointer with that of the class.) |
137 | // |
138 | // Limitations: |
139 | // - Can't say |
140 | // |
141 | // if (or) {} |
142 | // |
143 | // must say |
144 | // |
145 | // if (or != NULL) {} |
146 | // |
147 | // |
148 | //========================================================================= |
149 | class OBJECTREF { |
150 | private: |
151 | // Holds the real object pointer. |
152 | // The union gives us better debugger pretty printing |
153 | union { |
154 | Object *m_asObj; |
155 | class StringObject* m_asString; |
156 | class ArrayBase* m_asArray; |
157 | class PtrArray* m_asPtrArray; |
158 | class DelegateObject* m_asDelegate; |
159 | |
160 | class ReflectClassBaseObject* m_asReflectClass; |
161 | class ExecutionContextObject* m_asExecutionContext; |
162 | class AppDomainBaseObject* m_asAppDomainBase; |
163 | class PermissionSetObject* m_asPermissionSetObject; |
164 | }; |
165 | |
166 | public: |
167 | //------------------------------------------------------------- |
168 | // Default constructor, for non-initializing declarations: |
169 | // |
170 | // OBJECTREF or; |
171 | //------------------------------------------------------------- |
172 | OBJECTREF(); |
173 | |
174 | //------------------------------------------------------------- |
175 | // Copy constructor, for passing OBJECTREF's as function arguments. |
176 | //------------------------------------------------------------- |
177 | OBJECTREF(const OBJECTREF & objref); |
178 | |
179 | //------------------------------------------------------------- |
180 | // To allow NULL to be used as an OBJECTREF. |
181 | //------------------------------------------------------------- |
182 | OBJECTREF(TADDR nul); |
183 | |
184 | //------------------------------------------------------------- |
185 | // Test against NULL. |
186 | //------------------------------------------------------------- |
187 | int operator!() const; |
188 | |
189 | //------------------------------------------------------------- |
190 | // Compare two OBJECTREF's. |
191 | //------------------------------------------------------------- |
192 | int operator==(const OBJECTREF &objref) const; |
193 | |
194 | //------------------------------------------------------------- |
195 | // Compare two OBJECTREF's. |
196 | //------------------------------------------------------------- |
197 | int operator!=(const OBJECTREF &objref) const; |
198 | |
199 | //------------------------------------------------------------- |
200 | // Forward method calls. |
201 | //------------------------------------------------------------- |
202 | Object* operator->(); |
203 | const Object* operator->() const; |
204 | |
205 | //------------------------------------------------------------- |
206 | // Assignment. We don't validate the destination so as not |
207 | // to break the sequence: |
208 | // |
209 | // OBJECTREF or; |
210 | // or = ...; |
211 | //------------------------------------------------------------- |
212 | OBJECTREF& operator=(const OBJECTREF &objref); |
213 | OBJECTREF& operator=(TADDR nul); |
214 | |
215 | // allow explict casts |
216 | explicit OBJECTREF(Object *pObject); |
217 | |
218 | void Validate(BOOL bDeep = TRUE, BOOL = TRUE, BOOL bVerifySyncBlock = TRUE); |
219 | |
220 | }; |
221 | |
222 | //------------------------------------------------------------- |
223 | // template class REF for different types of REF class to be used |
224 | // in the debug mode |
225 | // Template type should be a class that extends Object |
226 | //------------------------------------------------------------- |
227 | |
228 | |
229 | |
230 | template <class T> |
231 | class REF : public OBJECTREF |
232 | { |
233 | public: |
234 | |
235 | //------------------------------------------------------------- |
236 | // Default constructor, for non-initializing declarations: |
237 | // |
238 | // OBJECTREF or; |
239 | //------------------------------------------------------------- |
240 | REF() :OBJECTREF () |
241 | { |
242 | LIMITED_METHOD_CONTRACT; |
243 | // no op |
244 | } |
245 | |
246 | //------------------------------------------------------------- |
247 | // Copy constructor, for passing OBJECTREF's as function arguments. |
248 | //------------------------------------------------------------- |
249 | explicit REF(const OBJECTREF& objref) : OBJECTREF(objref) |
250 | { |
251 | LIMITED_METHOD_CONTRACT; |
252 | //no op |
253 | } |
254 | |
255 | |
256 | //------------------------------------------------------------- |
257 | // To allow NULL to be used as an OBJECTREF. |
258 | //------------------------------------------------------------- |
259 | REF(TADDR nul) : OBJECTREF (nul) |
260 | { |
261 | LIMITED_METHOD_CONTRACT; |
262 | // no op |
263 | } |
264 | |
265 | explicit REF(T* pObject) : OBJECTREF(pObject) |
266 | { |
267 | LIMITED_METHOD_CONTRACT; |
268 | // no op |
269 | } |
270 | |
271 | //------------------------------------------------------------- |
272 | // Forward method calls. |
273 | //------------------------------------------------------------- |
274 | T* operator->() |
275 | { |
276 | // What kind of statement can we make about member methods on Object |
277 | // except that we need to be in COOPERATIVE when touching them? |
278 | STATIC_CONTRACT_MODE_COOPERATIVE; |
279 | return (T *)OBJECTREF::operator->(); |
280 | } |
281 | |
282 | const T* operator->() const |
283 | { |
284 | // What kind of statement can we make about member methods on Object |
285 | // except that we need to be in COOPERATIVE when touching them? |
286 | STATIC_CONTRACT_MODE_COOPERATIVE; |
287 | return (const T *)OBJECTREF::operator->(); |
288 | } |
289 | |
290 | //------------------------------------------------------------- |
291 | // Assignment. We don't validate the destination so as not |
292 | // to break the sequence: |
293 | // |
294 | // OBJECTREF or; |
295 | // or = ...; |
296 | //------------------------------------------------------------- |
297 | REF<T> &operator=(OBJECTREF &objref) |
298 | { |
299 | STATIC_CONTRACT_NOTHROW; |
300 | STATIC_CONTRACT_GC_NOTRIGGER; |
301 | STATIC_CONTRACT_CANNOT_TAKE_LOCK; |
302 | STATIC_CONTRACT_MODE_COOPERATIVE; |
303 | return (REF<T>&)OBJECTREF::operator=(objref); |
304 | } |
305 | |
306 | }; |
307 | |
308 | // the while (0) syntax below is to force a trailing semicolon on users of the macro |
309 | #define VALIDATEOBJECTREF(objref) do {if ((objref) != NULL) (objref).Validate();} while (0) |
310 | #define VALIDATEOBJECT(obj) do {if ((obj) != NULL) (obj)->Validate();} while (0) |
311 | |
312 | #define ObjectToOBJECTREF(obj) (OBJECTREF(obj)) |
313 | #define OBJECTREFToObject(objref) ((objref).operator-> ()) |
314 | #define ObjectToSTRINGREF(obj) (STRINGREF(obj)) |
315 | #define STRINGREFToObject(objref) (*( (StringObject**) &(objref) )) |
316 | |
317 | #else // _DEBUG_IMPL |
318 | |
319 | #define VALIDATEOBJECTREF(objref) |
320 | #define VALIDATEOBJECT(obj) |
321 | |
322 | #define ObjectToOBJECTREF(obj) ((PTR_Object) (obj)) |
323 | #define OBJECTREFToObject(objref) ((PTR_Object) (objref)) |
324 | #define ObjectToSTRINGREF(obj) ((PTR_StringObject) (obj)) |
325 | #define STRINGREFToObject(objref) ((PTR_StringObject) (objref)) |
326 | |
327 | #endif // _DEBUG_IMPL |
328 | |
329 | |
330 | // <TODO> Get rid of these! Don't use them any more!</TODO> |
331 | #define MAX_CLASSNAME_LENGTH 1024 |
332 | #define MAX_NAMESPACE_LENGTH 1024 |
333 | |
334 | class EEConfig; |
335 | class ClassLoaderList; |
336 | class Module; |
337 | class ArrayTypeDesc; |
338 | |
339 | #define EXTERN extern |
340 | |
341 | // For [<I1, etc. up to and including [Object |
342 | GARY_DECL(PTR_ArrayTypeDesc, g_pPredefinedArrayTypes, ELEMENT_TYPE_MAX); |
343 | |
344 | extern "C" Volatile<LONG> g_TrapReturningThreads; |
345 | |
346 | EXTERN HINSTANCE g_pMSCorEE; |
347 | EXTERN BBSweep g_BBSweep; |
348 | EXTERN IBCLogger g_IBCLogger; |
349 | |
350 | #ifdef _DEBUG |
351 | // next two variables are used to enforce an ASSERT in Thread::DbgFindThread |
352 | // that does not allow g_TrapReturningThreads to creep up unchecked. |
353 | EXTERN Volatile<LONG> g_trtChgStamp; |
354 | EXTERN Volatile<LONG> g_trtChgInFlight; |
355 | EXTERN const char * g_ExceptionFile; |
356 | EXTERN DWORD g_ExceptionLine; |
357 | EXTERN void * g_ExceptionEIP; |
358 | #endif |
359 | EXTERN void * g_LastAccessViolationEIP; |
360 | |
361 | GPTR_DECL(EEConfig, g_pConfig); // configuration data (from the registry) |
362 | GPTR_DECL(MethodTable, g_pObjectClass); |
363 | GPTR_DECL(MethodTable, g_pRuntimeTypeClass); |
364 | GPTR_DECL(MethodTable, g_pCanonMethodTableClass); // System.__Canon |
365 | GPTR_DECL(MethodTable, g_pStringClass); |
366 | GPTR_DECL(MethodTable, g_pArrayClass); |
367 | GPTR_DECL(MethodTable, g_pSZArrayHelperClass); |
368 | GPTR_DECL(MethodTable, g_pNullableClass); |
369 | GPTR_DECL(MethodTable, g_pByReferenceClass); |
370 | GPTR_DECL(MethodTable, g_pExceptionClass); |
371 | GPTR_DECL(MethodTable, g_pThreadAbortExceptionClass); |
372 | GPTR_DECL(MethodTable, g_pOutOfMemoryExceptionClass); |
373 | GPTR_DECL(MethodTable, g_pStackOverflowExceptionClass); |
374 | GPTR_DECL(MethodTable, g_pExecutionEngineExceptionClass); |
375 | GPTR_DECL(MethodTable, g_pThreadAbortExceptionClass); |
376 | GPTR_DECL(MethodTable, g_pDelegateClass); |
377 | GPTR_DECL(MethodTable, g_pMulticastDelegateClass); |
378 | GPTR_DECL(MethodTable, g_pFreeObjectMethodTable); |
379 | GPTR_DECL(MethodTable, g_pValueTypeClass); |
380 | GPTR_DECL(MethodTable, g_pEnumClass); |
381 | GPTR_DECL(MethodTable, g_pThreadClass); |
382 | GPTR_DECL(MethodTable, g_pOverlappedDataClass); |
383 | |
384 | GPTR_DECL(MethodTable, g_TypedReferenceMT); |
385 | |
386 | GPTR_DECL(MethodTable, g_pByteArrayMT); |
387 | |
388 | #ifdef FEATURE_COMINTEROP |
389 | GPTR_DECL(MethodTable, g_pBaseCOMObject); |
390 | GPTR_DECL(MethodTable, g_pBaseRuntimeClass); |
391 | #endif |
392 | |
393 | #ifdef FEATURE_ICASTABLE |
394 | GPTR_DECL(MethodTable, g_pICastableInterface); |
395 | #endif // FEATURE_ICASTABLE |
396 | |
397 | GPTR_DECL(MethodDesc, g_pExecuteBackoutCodeHelperMethod); |
398 | |
399 | GPTR_DECL(MethodDesc, g_pObjectFinalizerMD); |
400 | |
401 | #ifdef FEATURE_INTEROP_DEBUGGING |
402 | GVAL_DECL(DWORD, g_debuggerWordTLSIndex); |
403 | #endif |
404 | GVAL_DECL(DWORD, g_TlsIndex); |
405 | |
406 | // Global System Information |
407 | extern SYSTEM_INFO g_SystemInfo; |
408 | |
409 | // <TODO>@TODO - PROMOTE.</TODO> |
410 | // <TODO>@TODO - I'd like to make these private members of CLRException some day.</TODO> |
411 | EXTERN OBJECTHANDLE g_pPreallocatedOutOfMemoryException; |
412 | EXTERN OBJECTHANDLE g_pPreallocatedStackOverflowException; |
413 | EXTERN OBJECTHANDLE g_pPreallocatedExecutionEngineException; |
414 | EXTERN OBJECTHANDLE g_pPreallocatedRudeThreadAbortException; |
415 | |
416 | // We may not be able to create a normal thread abort exception if OOM or StackOverFlow. |
417 | // When this happens, we will use our pre-allocated thread abort exception. |
418 | EXTERN OBJECTHANDLE g_pPreallocatedThreadAbortException; |
419 | |
420 | // we use this as a dummy object to indicate free space in the handle tables -- this object is never visible to the world |
421 | EXTERN OBJECTHANDLE g_pPreallocatedSentinelObject; |
422 | |
423 | // We use this object to return a preallocated System.Exception instance when we have nothing |
424 | // better to return. |
425 | EXTERN OBJECTHANDLE g_pPreallocatedBaseException; |
426 | |
427 | GPTR_DECL(Thread,g_pFinalizerThread); |
428 | GPTR_DECL(Thread,g_pSuspensionThread); |
429 | |
430 | // Global SyncBlock cache |
431 | typedef DPTR(SyncTableEntry) PTR_SyncTableEntry; |
432 | GPTR_DECL(SyncTableEntry, g_pSyncTable); |
433 | |
434 | #ifdef FEATURE_COMINTEROP |
435 | // Global RCW cleanup list |
436 | typedef DPTR(RCWCleanupList) PTR_RCWCleanupList; |
437 | GPTR_DECL(RCWCleanupList,g_pRCWCleanupList); |
438 | #endif // FEATURE_COMINTEROP |
439 | |
440 | // support for Event Tracing for Windows (ETW) |
441 | EXTERN ETW::CEtwTracer* g_pEtwTracer; |
442 | |
443 | #ifdef STRESS_LOG |
444 | class StressLog; |
445 | typedef DPTR(StressLog) PTR_StressLog; |
446 | GPTR_DECL(StressLog, g_pStressLog); |
447 | #endif |
448 | |
449 | |
450 | // |
451 | // Support for the COM+ Debugger. |
452 | // |
453 | GPTR_DECL(DebugInterface, g_pDebugInterface); |
454 | GVAL_DECL(DWORD, g_CORDebuggerControlFlags); |
455 | #ifdef DEBUGGING_SUPPORTED |
456 | GPTR_DECL(EEDbgInterfaceImpl, g_pEEDbgInterfaceImpl); |
457 | #endif // DEBUGGING_SUPPORTED |
458 | |
459 | #ifdef PROFILING_SUPPORTED |
460 | EXTERN HINSTANCE g_pDebuggerDll; |
461 | #endif |
462 | |
463 | // Global default for Concurrent GC. The default is on (value 1) |
464 | EXTERN int g_IGCconcurrent; |
465 | extern int g_IGCHoardVM; |
466 | |
467 | #ifdef GCTRIMCOMMIT |
468 | extern int g_IGCTrimCommit; |
469 | #endif |
470 | |
471 | extern BOOL g_fEnableETW; |
472 | extern BOOL g_fEnableARM; |
473 | |
474 | // Returns a BOOL to indicate if the runtime is active or not |
475 | BOOL IsRuntimeActive(); |
476 | |
477 | // |
478 | // Can we run managed code? |
479 | // |
480 | struct LoaderLockCheck |
481 | { |
482 | enum kind |
483 | { |
484 | ForMDA, |
485 | ForCorrectness, |
486 | None, |
487 | }; |
488 | }; |
489 | BOOL CanRunManagedCode(LoaderLockCheck::kind checkKind, HINSTANCE hInst = 0); |
490 | inline BOOL CanRunManagedCode(HINSTANCE hInst = 0) |
491 | { |
492 | return CanRunManagedCode(LoaderLockCheck::ForMDA, hInst); |
493 | } |
494 | |
495 | // |
496 | // Global state variable indicating if the EE is in its init phase. |
497 | // |
498 | EXTERN bool g_fEEInit; |
499 | |
500 | // |
501 | // Global state variable indicating if the EE has been started up. |
502 | // |
503 | EXTERN Volatile<BOOL> g_fEEStarted; |
504 | |
505 | #ifdef FEATURE_COMINTEROP |
506 | // |
507 | // Global state variable indicating if COM has been started up. |
508 | // |
509 | EXTERN BOOL g_fComStarted; |
510 | #endif |
511 | |
512 | |
513 | // |
514 | // Global state variables indicating which stage of shutdown we are in |
515 | // |
516 | GVAL_DECL(DWORD, g_fEEShutDown); |
517 | EXTERN DWORD g_fFastExitProcess; |
518 | EXTERN BOOL g_fFatalErrorOccurredOnGCThread; |
519 | #ifndef DACCESS_COMPILE |
520 | EXTERN BOOL g_fSuspendOnShutdown; |
521 | EXTERN BOOL g_fSuspendFinalizerOnShutdown; |
522 | #endif // DACCESS_COMPILE |
523 | EXTERN Volatile<LONG> g_fForbidEnterEE; |
524 | GVAL_DECL(bool, g_fProcessDetach); |
525 | EXTERN bool g_fManagedAttach; |
526 | EXTERN bool g_fNoExceptions; |
527 | #ifdef FEATURE_COMINTEROP |
528 | EXTERN bool g_fShutDownCOM; |
529 | #endif // FEATURE_COMINTEROP |
530 | |
531 | // Indicates whether we're executing shut down as a result of DllMain |
532 | // (DLL_PROCESS_DETACH). See comments at code:EEShutDown for details. |
533 | inline BOOL IsAtProcessExit() |
534 | { |
535 | SUPPORTS_DAC; |
536 | return g_fProcessDetach; |
537 | } |
538 | |
539 | enum FWStatus |
540 | { |
541 | FWS_WaitInterrupt = 0x00000001, |
542 | }; |
543 | |
544 | EXTERN DWORD g_FinalizerWaiterStatus; |
545 | extern ULONGLONG g_ObjFinalizeStartTime; |
546 | extern Volatile<BOOL> g_FinalizerIsRunning; |
547 | extern Volatile<ULONG> g_FinalizerLoopCount; |
548 | |
549 | #if defined(FEATURE_PAL) && defined(FEATURE_EVENT_TRACE) |
550 | extern Volatile<BOOL> g_TriggerHeapDump; |
551 | #endif // FEATURE_PAL |
552 | |
553 | extern LONG GetProcessedExitProcessEventCount(); |
554 | |
555 | #ifndef DACCESS_COMPILE |
556 | // |
557 | // Allow use of native images? |
558 | // |
559 | extern bool g_fAllowNativeImages; |
560 | |
561 | // |
562 | // Default install library |
563 | // |
564 | EXTERN const WCHAR g_pwBaseLibrary[]; |
565 | EXTERN const WCHAR g_pwBaseLibraryName[]; |
566 | EXTERN const char g_psBaseLibrary[]; |
567 | EXTERN const char g_psBaseLibraryName[]; |
568 | EXTERN const char g_psBaseLibrarySatelliteAssemblyName[]; |
569 | |
570 | #endif // DACCESS_COMPILE |
571 | |
572 | // |
573 | // Do we own the lifetime of the process, ie. is it an EXE? |
574 | // |
575 | EXTERN bool g_fWeControlLifetime; |
576 | |
577 | #ifdef _DEBUG |
578 | // The following should only be used for assertions. (Famous last words). |
579 | EXTERN bool dbg_fDrasticShutdown; |
580 | #endif |
581 | EXTERN bool g_fInControlC; |
582 | |
583 | // There is a global table of prime numbers that's available for e.g. hashing |
584 | extern const DWORD g_rgPrimes[71]; |
585 | |
586 | // |
587 | // Macros to check debugger and profiler settings. |
588 | // |
589 | inline bool CORDebuggerPendingAttach() |
590 | { |
591 | LIMITED_METHOD_CONTRACT; |
592 | SUPPORTS_DAC; |
593 | // If we're in rude shutdown, then pretend the debugger is detached. |
594 | // We want shutdown to be as simple as possible, so this avoids |
595 | // us trying to do elaborate operations while exiting. |
596 | return (g_CORDebuggerControlFlags & DBCF_PENDING_ATTACH) && !IsAtProcessExit(); |
597 | } |
598 | |
599 | inline bool CORDebuggerAttached() |
600 | { |
601 | LIMITED_METHOD_CONTRACT; |
602 | SUPPORTS_DAC; |
603 | // If we're in rude shutdown, then pretend the debugger is detached. |
604 | // We want shutdown to be as simple as possible, so this avoids |
605 | // us trying to do elaborate operations while exiting. |
606 | return (g_CORDebuggerControlFlags & DBCF_ATTACHED) && !IsAtProcessExit(); |
607 | } |
608 | |
609 | #define CORDebuggerAllowJITOpts(dwDebuggerBits) \ |
610 | (((dwDebuggerBits) & DACF_ALLOW_JIT_OPTS) \ |
611 | || \ |
612 | ((g_CORDebuggerControlFlags & DBCF_ALLOW_JIT_OPT) && \ |
613 | !((dwDebuggerBits) & DACF_USER_OVERRIDE))) |
614 | |
615 | #define CORDebuggerEnCMode(dwDebuggerBits) \ |
616 | ((dwDebuggerBits) & DACF_ENC_ENABLED) |
617 | |
618 | #define CORDebuggerTraceCall() \ |
619 | (CORDebuggerAttached() && GetThread()->IsTraceCall()) |
620 | |
621 | |
622 | |
623 | // |
624 | // Define stuff for precedence between profiling and debugging |
625 | // flags that can both be set. |
626 | // |
627 | |
628 | #if defined(PROFILING_SUPPORTED) || defined(PROFILING_SUPPORTED_DATA) |
629 | |
630 | #ifdef DEBUGGING_SUPPORTED |
631 | |
632 | #define CORDisableJITOptimizations(dwDebuggerBits) \ |
633 | (CORProfilerDisableOptimizations() || \ |
634 | !CORDebuggerAllowJITOpts(dwDebuggerBits)) |
635 | |
636 | #else // !DEBUGGING_SUPPORTED |
637 | |
638 | #define CORDisableJITOptimizations(dwDebuggerBits) \ |
639 | CORProfilerDisableOptimizations() |
640 | |
641 | #endif// DEBUGGING_SUPPORTED |
642 | |
643 | #else // !defined(PROFILING_SUPPORTED) && !defined(PROFILING_SUPPORTED_DATA) |
644 | |
645 | #ifdef DEBUGGING_SUPPORTED |
646 | |
647 | #define CORDisableJITOptimizations(dwDebuggerBits) \ |
648 | !CORDebuggerAllowJITOpts(dwDebuggerBits) |
649 | |
650 | #else // DEBUGGING_SUPPORTED |
651 | |
652 | #define CORDisableJITOptimizations(dwDebuggerBits) FALSE |
653 | |
654 | #endif// DEBUGGING_SUPPORTED |
655 | |
656 | #endif// defined(PROFILING_SUPPORTED) || defined(PROFILING_SUPPORTED_DATA) |
657 | |
658 | |
659 | |
660 | |
661 | // |
662 | // IJW needs the shim HINSTANCE |
663 | // |
664 | EXTERN HINSTANCE g_hInstShim; |
665 | |
666 | #ifndef FEATURE_PAL |
667 | GVAL_DECL(SIZE_T, g_runtimeLoadedBaseAddress); |
668 | GVAL_DECL(SIZE_T, g_runtimeVirtualSize); |
669 | #endif // !FEATURE_PAL |
670 | |
671 | |
672 | #ifndef MAXULONG |
673 | #define MAXULONG 0xffffffff |
674 | #endif |
675 | |
676 | #ifndef MAXULONGLONG |
677 | #define MAXULONGLONG UI64(0xffffffffffffffff) |
678 | #endif |
679 | |
680 | // #ADID_vs_ADIndex |
681 | // code:ADID is an ID for an appdomain that is sparse and remains unique within the process for the lifetime of the process. |
682 | // Remoting and (I believe) the thread pool use the former as a way of referring to appdomains outside of their normal lifetime safely. |
683 | // Interop also uses ADID to handle issues involving unloaded domains. |
684 | // |
685 | // code:ADIndex is an ID for an appdomain that's dense and may be reused once the appdomain is unloaded. |
686 | // This is useful for fast array based lookup from a number to an appdomain property. |
687 | struct ADIndex |
688 | { |
689 | DWORD m_dwIndex; |
690 | ADIndex () |
691 | : m_dwIndex(0) |
692 | {} |
693 | explicit ADIndex (DWORD id) |
694 | : m_dwIndex(id) |
695 | { |
696 | SUPPORTS_DAC; |
697 | } |
698 | BOOL operator==(const ADIndex& ad) const |
699 | { |
700 | return m_dwIndex == ad.m_dwIndex; |
701 | } |
702 | BOOL operator!=(const ADIndex& ad) const |
703 | { |
704 | return m_dwIndex != ad.m_dwIndex; |
705 | } |
706 | }; |
707 | |
708 | // An ADID is a number that represents an appdomain. They are allcoated with code:SystemDomain::GetNewAppDomainId |
709 | // ADIDs are NOT reused today, so they are unique even after the appdomain dies. |
710 | // |
711 | // see also code:BaseDomain::m_dwId |
712 | // see also code:ADIndex |
713 | // see also code:ADIndex#ADID_vs_ADIndex |
714 | struct ADID |
715 | { |
716 | DWORD m_dwId; |
717 | ADID () |
718 | : m_dwId(0) |
719 | {LIMITED_METHOD_CONTRACT;} |
720 | explicit ADID (DWORD id) |
721 | : m_dwId(id) |
722 | {LIMITED_METHOD_CONTRACT;} |
723 | BOOL operator==(const ADID& ad) const |
724 | { |
725 | LIMITED_METHOD_DAC_CONTRACT; |
726 | return m_dwId == ad.m_dwId; |
727 | } |
728 | BOOL operator!=(const ADID& ad) const |
729 | { |
730 | LIMITED_METHOD_CONTRACT; |
731 | return m_dwId != ad.m_dwId; |
732 | } |
733 | }; |
734 | |
735 | struct TPIndex |
736 | { |
737 | DWORD m_dwIndex; |
738 | TPIndex () |
739 | : m_dwIndex(0) |
740 | {} |
741 | explicit TPIndex (DWORD id) |
742 | : m_dwIndex(id) |
743 | {} |
744 | BOOL operator==(const TPIndex& tpindex) const |
745 | { |
746 | return m_dwIndex == tpindex.m_dwIndex; |
747 | } |
748 | BOOL operator!=(const TPIndex& tpindex) const |
749 | { |
750 | return m_dwIndex != tpindex.m_dwIndex; |
751 | } |
752 | }; |
753 | |
754 | // Every Module is assigned a ModuleIndex, regardless of whether the Module is domain |
755 | // neutral or domain specific. When a domain specific Module is unloaded, its ModuleIndex |
756 | // can be reused. |
757 | |
758 | // ModuleIndexes are not the same as ModuleIDs. The main purpose of a ModuleIndex is |
759 | // to have a compact way to refer to any Module (domain neutral or domain specific). |
760 | // The main purpose of a ModuleID is to facilitate looking up the DomainLocalModule |
761 | // that corresponds to a given Module in a given AppDomain. |
762 | |
763 | struct ModuleIndex |
764 | { |
765 | SIZE_T m_dwIndex; |
766 | ModuleIndex () |
767 | : m_dwIndex(0) |
768 | {} |
769 | explicit ModuleIndex (SIZE_T id) |
770 | : m_dwIndex(id) |
771 | { LIMITED_METHOD_DAC_CONTRACT; } |
772 | BOOL operator==(const ModuleIndex& ad) const |
773 | { |
774 | return m_dwIndex == ad.m_dwIndex; |
775 | } |
776 | BOOL operator!=(const ModuleIndex& ad) const |
777 | { |
778 | return m_dwIndex != ad.m_dwIndex; |
779 | } |
780 | }; |
781 | |
782 | //----------------------------------------------------------------------------- |
783 | // GSCookies (guard-stack cookies) for detecting buffer overruns |
784 | //----------------------------------------------------------------------------- |
785 | |
786 | typedef DPTR(GSCookie) PTR_GSCookie; |
787 | |
788 | #ifndef DACCESS_COMPILE |
789 | // const is so that it gets placed in the .text section (which is read-only) |
790 | // volatile is so that accesses to it do not get optimized away because of the const |
791 | // |
792 | |
793 | extern "C" RAW_KEYWORD(volatile) const GSCookie s_gsCookie; |
794 | |
795 | inline |
796 | GSCookie * GetProcessGSCookiePtr() { return const_cast<GSCookie *>(&s_gsCookie); } |
797 | |
798 | #else |
799 | |
800 | extern __GlobalVal< GSCookie > s_gsCookie; |
801 | |
802 | inline |
803 | PTR_GSCookie GetProcessGSCookiePtr() { return PTR_GSCookie(&s_gsCookie); } |
804 | |
805 | #endif //!DACCESS_COMPILE |
806 | |
807 | inline |
808 | GSCookie GetProcessGSCookie() { return *(RAW_KEYWORD(volatile) GSCookie *)(&s_gsCookie); } |
809 | |
810 | class CEECompileInfo; |
811 | extern CEECompileInfo *g_pCEECompileInfo; |
812 | |
813 | #ifdef FEATURE_READYTORUN_COMPILER |
814 | extern bool g_fReadyToRunCompilation; |
815 | #endif |
816 | |
817 | // Returns true if this is NGen compilation process. |
818 | // This is a superset of CompilationDomain::IsCompilationDomain() as there is more |
819 | // than one AppDomain in ngen (the DefaultDomain) |
820 | inline BOOL IsCompilationProcess() |
821 | { |
822 | #ifdef CROSSGEN_COMPILE |
823 | return TRUE; |
824 | #else |
825 | return FALSE; |
826 | #endif |
827 | } |
828 | |
829 | // Flag for cross-platform ngen: Removes all execution of managed or third-party code in the ngen compilation process. |
830 | inline BOOL NingenEnabled() |
831 | { |
832 | #ifdef CROSSGEN_COMPILE |
833 | return TRUE; |
834 | #else |
835 | return FALSE; |
836 | #endif |
837 | } |
838 | |
839 | // Passed to JitManager APIs to determine whether to avoid calling into the host. |
840 | // The profiling API stackwalking uses this to ensure to avoid re-entering the host |
841 | // (particularly SQL) from a hijacked thread. |
842 | enum HostCallPreference |
843 | { |
844 | AllowHostCalls, |
845 | NoHostCalls, |
846 | }; |
847 | |
848 | #endif /* _VARS_HPP */ |
849 | |