Fix crossgen with large version bubble enabled
[platform/upstream/coreclr.git] / src / gc / gcinterface.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 #ifndef _GC_INTERFACE_H_
6 #define _GC_INTERFACE_H_
7
8 // The major version of the GC/EE interface. Breaking changes to this interface
9 // require bumps in the major version number.
10 #define GC_INTERFACE_MAJOR_VERSION 3
11
12 // The minor version of the GC/EE interface. Non-breaking changes are required
13 // to bump the minor version number. GCs and EEs with minor version number
14 // mismatches can still interopate correctly, with some care.
15 #define GC_INTERFACE_MINOR_VERSION 1
16
17 struct ScanContext;
18 struct gc_alloc_context;
19 class CrawlFrame;
20
21 // Callback passed to GcScanRoots.
22 typedef void promote_func(PTR_PTR_Object, ScanContext*, uint32_t);
23
24 // Callback passed to GcEnumAllocContexts.
25 typedef void enum_alloc_context_func(gc_alloc_context*, void*);
26
27 // Callback passed to CreateBackgroundThread.
28 typedef uint32_t (__stdcall *GCBackgroundThreadFunction)(void* param);
29
30 // Struct often used as a parameter to callbacks.
31 typedef struct
32 {
33     promote_func*  f;
34     ScanContext*   sc;
35     CrawlFrame *   cf;
36 } GCCONTEXT;
37
38 // SUSPEND_REASON is the reason why the GC wishes to suspend the EE,
39 // used as an argument to IGCToCLR::SuspendEE.
40 typedef enum
41 {
42     SUSPEND_FOR_GC = 1,
43     SUSPEND_FOR_GC_PREP = 6
44 } SUSPEND_REASON;
45
46 typedef enum
47 {
48     walk_for_gc = 1,
49     walk_for_bgc = 2,
50     walk_for_loh = 3
51 } walk_surv_type;
52
53 // Different operations that can be done by GCToEEInterface::StompWriteBarrier
54 enum class WriteBarrierOp
55 {
56     StompResize,
57     StompEphemeral,
58     Initialize,
59     SwitchToWriteWatch,
60     SwitchToNonWriteWatch
61 };
62
63 // Arguments to GCToEEInterface::StompWriteBarrier
64 struct WriteBarrierParameters
65 {
66     // The operation that StompWriteBarrier will perform.
67     WriteBarrierOp operation;
68
69     // Whether or not the runtime is currently suspended. If it is not,
70     // the EE will need to suspend it before bashing the write barrier.
71     // Used for all operations.
72     bool is_runtime_suspended;
73
74     // Whether or not the GC has moved the ephemeral generation to no longer
75     // be at the top of the heap. When the ephemeral generation is at the top
76     // of the heap, and the write barrier observes that a pointer is greater than
77     // g_ephemeral_low, it does not need to check that the pointer is less than
78     // g_ephemeral_high because there is nothing in the GC heap above the ephemeral
79     // generation. When this is not the case, however, the GC must inform the EE
80     // so that the EE can switch to a write barrier that checks that a pointer
81     // is both greater than g_ephemeral_low and less than g_ephemeral_high.
82     // Used for WriteBarrierOp::StompResize.
83     bool requires_upper_bounds_check;
84
85     // The new card table location. May or may not be the same as the previous
86     // card table. Used for WriteBarrierOp::Initialize and WriteBarrierOp::StompResize.
87     uint32_t* card_table;
88
89     // The new card bundle table location. May or may not be the same as the previous
90     // card bundle table. Used for WriteBarrierOp::Initialize and WriteBarrierOp::StompResize.
91     uint32_t* card_bundle_table;
92
93     // The heap's new low boundary. May or may not be the same as the previous
94     // value. Used for WriteBarrierOp::Initialize and WriteBarrierOp::StompResize.
95     uint8_t* lowest_address;
96
97     // The heap's new high boundary. May or may not be the same as the previous
98     // value. Used for WriteBarrierOp::Initialize and WriteBarrierOp::StompResize.
99     uint8_t* highest_address;
100
101     // The new start of the ephemeral generation. 
102     // Used for WriteBarrierOp::StompEphemeral.
103     uint8_t* ephemeral_low;
104
105     // The new end of the ephemeral generation.
106     // Used for WriteBarrierOp::StompEphemeral.
107     uint8_t* ephemeral_high;
108
109     // The new write watch table, if we are using our own write watch
110     // implementation. Used for WriteBarrierOp::SwitchToWriteWatch only.
111     uint8_t* write_watch_table;
112 };
113
114 // Opaque type for tracking object pointers
115 #ifndef DACCESS_COMPILE
116 struct OBJECTHANDLE__
117 {
118     void* unused;
119 };
120 typedef struct OBJECTHANDLE__* OBJECTHANDLE;
121 #else
122 typedef uintptr_t OBJECTHANDLE;
123 #endif
124
125  /*
126   * Scanning callback.
127   */
128 typedef void (CALLBACK *HANDLESCANPROC)(PTR_UNCHECKED_OBJECTREF pref, uintptr_t *pExtraInfo, uintptr_t param1, uintptr_t param2);
129
130 #include "gcinterface.ee.h"
131
132 // The allocation context must be known to the VM for use in the allocation
133 // fast path and known to the GC for performing the allocation. Every Thread
134 // has its own allocation context that it hands to the GC when allocating.
135 struct gc_alloc_context
136 {
137     uint8_t*       alloc_ptr;
138     uint8_t*       alloc_limit;
139     int64_t        alloc_bytes; //Number of bytes allocated on SOH by this context
140     int64_t        alloc_bytes_loh; //Number of bytes allocated on LOH by this context
141     // These two fields are deliberately not exposed past the EE-GC interface.
142     void*          gc_reserved_1;
143     void*          gc_reserved_2;
144     int            alloc_count;
145 public:
146
147     void init()
148     {
149         LIMITED_METHOD_CONTRACT;
150
151         alloc_ptr = 0;
152         alloc_limit = 0;
153         alloc_bytes = 0;
154         alloc_bytes_loh = 0;
155         gc_reserved_1 = 0;
156         gc_reserved_2 = 0;
157         alloc_count = 0;
158     }
159 };
160
161 #include "gcinterface.dac.h"
162
163 // stub type to abstract a heap segment
164 struct gc_heap_segment_stub;
165 typedef gc_heap_segment_stub *segment_handle;
166
167 struct segment_info
168 {
169     void * pvMem; // base of the allocation, not the first object (must add ibFirstObject)
170     size_t ibFirstObject;   // offset to the base of the first object in the segment
171     size_t ibAllocated; // limit of allocated memory in the segment (>= firstobject)
172     size_t ibCommit; // limit of committed memory in the segment (>= allocated)
173     size_t ibReserved; // limit of reserved memory in the segment (>= commit)
174 };
175
176 #ifdef PROFILING_SUPPORTED
177 #define GC_PROFILING       //Turn on profiling
178 #endif // PROFILING_SUPPORTED
179
180 #define LARGE_OBJECT_SIZE ((size_t)(85000))
181
182 // The minimum size of an object is three pointers wide: one for the syncblock,
183 // one for the object header, and one for the first field in the object.
184 #define min_obj_size ((sizeof(uint8_t*) + sizeof(uintptr_t) + sizeof(size_t)))
185
186 // The bit shift used to convert a memory address into an index into the
187 // Software Write Watch table.
188 #define SOFTWARE_WRITE_WATCH_AddressToTableByteIndexShift 0xc
189
190 class Object;
191 class IGCHeap;
192 class IGCHandleManager;
193
194 #ifdef WRITE_BARRIER_CHECK
195 //always defined, but should be 0 in Server GC
196 extern uint8_t* g_GCShadow;
197 extern uint8_t* g_GCShadowEnd;
198 // saves the g_lowest_address in between GCs to verify the consistency of the shadow segment
199 extern uint8_t* g_shadow_lowest_address;
200 #endif
201
202 /*
203  * GCEventProvider represents one of the two providers that the GC can
204  * fire events from: the default and private providers.
205  */
206 enum GCEventProvider
207 {
208     GCEventProvider_Default = 0,
209     GCEventProvider_Private = 1
210 };
211
212 // Event levels corresponding to events that can be fired by the GC.
213 enum GCEventLevel
214 {
215     GCEventLevel_None = 0,
216     GCEventLevel_Fatal = 1,
217     GCEventLevel_Error = 2,
218     GCEventLevel_Warning = 3,
219     GCEventLevel_Information = 4,
220     GCEventLevel_Verbose = 5,
221     GCEventLevel_Max = 6,
222     GCEventLevel_LogAlways = 255
223 };
224
225 // Event keywords corresponding to events that can be fired by the GC. These
226 // numbers come from the ETW manifest itself - please make changes to this enum
227 // if you add, remove, or change keyword sets that are used by the GC!
228 enum GCEventKeyword
229 {
230     GCEventKeyword_None                          =       0x0,
231     GCEventKeyword_GC                            =       0x1,
232     // Duplicate on purpose, GCPrivate is the same keyword as GC, 
233     // with a different provider
234     GCEventKeyword_GCPrivate                     =       0x1,
235     GCEventKeyword_GCHandle                      =       0x2,
236     GCEventKeyword_GCHandlePrivate               =    0x4000,
237     GCEventKeyword_GCHeapDump                    =  0x100000,
238     GCEventKeyword_GCSampledObjectAllocationHigh =  0x200000,
239     GCEventKeyword_GCHeapSurvivalAndMovement     =  0x400000,
240     GCEventKeyword_GCHeapCollect                 =  0x800000,
241     GCEventKeyword_GCHeapAndTypeNames            = 0x1000000,
242     GCEventKeyword_GCSampledObjectAllocationLow  = 0x2000000,
243     GCEventKeyword_All = GCEventKeyword_GC
244       | GCEventKeyword_GCPrivate
245       | GCEventKeyword_GCHandle
246       | GCEventKeyword_GCHandlePrivate
247       | GCEventKeyword_GCHeapDump
248       | GCEventKeyword_GCSampledObjectAllocationHigh
249       | GCEventKeyword_GCHeapSurvivalAndMovement
250       | GCEventKeyword_GCHeapCollect
251       | GCEventKeyword_GCHeapAndTypeNames
252       | GCEventKeyword_GCSampledObjectAllocationLow
253 };
254
255 // !!!!!!!!!!!!!!!!!!!!!!!
256 // make sure you change the def in bcl\system\gc.cs 
257 // if you change this!
258 enum collection_mode
259 {
260     collection_non_blocking = 0x00000001,
261     collection_blocking = 0x00000002,
262     collection_optimized = 0x00000004,
263     collection_compacting = 0x00000008
264 #ifdef STRESS_HEAP
265     , collection_gcstress = 0x80000000
266 #endif // STRESS_HEAP
267 };
268
269 // !!!!!!!!!!!!!!!!!!!!!!!
270 // make sure you change the def in bcl\system\gc.cs 
271 // if you change this!
272 enum wait_full_gc_status
273 {
274     wait_full_gc_success = 0,
275     wait_full_gc_failed = 1,
276     wait_full_gc_cancelled = 2,
277     wait_full_gc_timeout = 3,
278     wait_full_gc_na = 4
279 };
280
281 // !!!!!!!!!!!!!!!!!!!!!!!
282 // make sure you change the def in bcl\system\gc.cs 
283 // if you change this!
284 enum start_no_gc_region_status
285 {
286     start_no_gc_success = 0,
287     start_no_gc_no_memory = 1,
288     start_no_gc_too_large = 2,
289     start_no_gc_in_progress = 3
290 };
291
292 enum end_no_gc_region_status
293 {
294     end_no_gc_success = 0,
295     end_no_gc_not_in_progress = 1,
296     end_no_gc_induced = 2,
297     end_no_gc_alloc_exceeded = 3
298 };
299
300 typedef enum 
301 {
302     /*
303      * WEAK HANDLES
304      *
305      * Weak handles are handles that track an object as long as it is alive,
306      * but do not keep the object alive if there are no strong references to it.
307      *
308      */
309
310     /*
311      * SHORT-LIVED WEAK HANDLES
312      *
313      * Short-lived weak handles are weak handles that track an object until the
314      * first time it is detected to be unreachable.  At this point, the handle is
315      * severed, even if the object will be visible from a pending finalization
316      * graph.  This further implies that short weak handles do not track
317      * across object resurrections.
318      *
319      */
320     HNDTYPE_WEAK_SHORT   = 0,
321
322     /*
323      * LONG-LIVED WEAK HANDLES
324      *
325      * Long-lived weak handles are weak handles that track an object until the
326      * object is actually reclaimed.  Unlike short weak handles, long weak handles
327      * continue to track their referents through finalization and across any
328      * resurrections that may occur.
329      *
330      */
331     HNDTYPE_WEAK_LONG    = 1,
332     HNDTYPE_WEAK_DEFAULT = 1,
333
334     /*
335      * STRONG HANDLES
336      *
337      * Strong handles are handles which function like a normal object reference.
338      * The existence of a strong handle for an object will cause the object to
339      * be promoted (remain alive) through a garbage collection cycle.
340      *
341      */
342     HNDTYPE_STRONG       = 2,
343     HNDTYPE_DEFAULT      = 2,
344
345     /*
346      * PINNED HANDLES
347      *
348      * Pinned handles are strong handles which have the added property that they
349      * prevent an object from moving during a garbage collection cycle.  This is
350      * useful when passing a pointer to object innards out of the runtime while GC
351      * may be enabled.
352      *
353      * NOTE:  PINNING AN OBJECT IS EXPENSIVE AS IT PREVENTS THE GC FROM ACHIEVING
354      *        OPTIMAL PACKING OF OBJECTS DURING EPHEMERAL COLLECTIONS.  THIS TYPE
355      *        OF HANDLE SHOULD BE USED SPARINGLY!
356      */
357     HNDTYPE_PINNED       = 3,
358
359     /*
360      * VARIABLE HANDLES
361      *
362      * Variable handles are handles whose type can be changed dynamically.  They
363      * are larger than other types of handles, and are scanned a little more often,
364      * but are useful when the handle owner needs an efficient way to change the
365      * strength of a handle on the fly.
366      * 
367      */
368     HNDTYPE_VARIABLE     = 4,
369
370     /*
371      * REFCOUNTED HANDLES
372      *
373      * Refcounted handles are handles that behave as strong handles while the
374      * refcount on them is greater than 0 and behave as weak handles otherwise.
375      *
376      * N.B. These are currently NOT general purpose.
377      *      The implementation is tied to COM Interop.
378      *
379      */
380     HNDTYPE_REFCOUNTED   = 5,
381
382     /*
383      * DEPENDENT HANDLES
384      *
385      * Dependent handles are two handles that need to have the same lifetime.  One handle refers to a secondary object 
386      * that needs to have the same lifetime as the primary object. The secondary object should not cause the primary 
387      * object to be referenced, but as long as the primary object is alive, so must be the secondary
388      *
389      * They are currently used for EnC for adding new field members to existing instantiations under EnC modes where
390      * the primary object is the original instantiation and the secondary represents the added field.
391      *
392      * They are also used to implement the ConditionalWeakTable class in mscorlib.dll. If you want to use
393      * these from managed code, they are exposed to BCL through the managed DependentHandle class.
394      *
395      *
396      */
397     HNDTYPE_DEPENDENT    = 6,
398
399     /*
400      * PINNED HANDLES for asynchronous operation
401      *
402      * Pinned handles are strong handles which have the added property that they
403      * prevent an object from moving during a garbage collection cycle.  This is
404      * useful when passing a pointer to object innards out of the runtime while GC
405      * may be enabled.
406      *
407      * NOTE:  PINNING AN OBJECT IS EXPENSIVE AS IT PREVENTS THE GC FROM ACHIEVING
408      *        OPTIMAL PACKING OF OBJECTS DURING EPHEMERAL COLLECTIONS.  THIS TYPE
409      *        OF HANDLE SHOULD BE USED SPARINGLY!
410      */
411     HNDTYPE_ASYNCPINNED  = 7,
412
413     /*
414      * SIZEDREF HANDLES
415      *
416      * SizedRef handles are strong handles. Each handle has a piece of user data associated
417      * with it that stores the size of the object this handle refers to. These handles
418      * are scanned as strong roots during each GC but only during full GCs would the size
419      * be calculated.
420      *
421      */
422     HNDTYPE_SIZEDREF     = 8,
423
424     /*
425      * WINRT WEAK HANDLES
426      *
427      * WinRT weak reference handles hold two different types of weak handles to any
428      * RCW with an underlying COM object that implements IWeakReferenceSource.  The
429      * object reference itself is a short weak handle to the RCW.  In addition an
430      * IWeakReference* to the underlying COM object is stored, allowing the handle
431      * to create a new RCW if the existing RCW is collected.  This ensures that any
432      * code holding onto a WinRT weak reference can always access an RCW to the
433      * underlying COM object as long as it has not been released by all of its strong
434      * references.
435      */
436     HNDTYPE_WEAK_WINRT   = 9
437 } HandleType;
438
439 typedef enum
440 {
441     GC_HEAP_INVALID = 0,
442     GC_HEAP_WKS     = 1,
443     GC_HEAP_SVR     = 2
444 } GCHeapType;
445
446 typedef bool (* walk_fn)(Object*, void*);
447 typedef void (* gen_walk_fn)(void* context, int generation, uint8_t* range_start, uint8_t* range_end, uint8_t* range_reserved);
448 typedef void (* record_surv_fn)(uint8_t* begin, uint8_t* end, ptrdiff_t reloc, void* context, bool compacting_p, bool bgc_p);
449 typedef void (* fq_walk_fn)(bool, void*);
450 typedef void (* fq_scan_fn)(Object** ppObject, ScanContext *pSC, uint32_t dwFlags);
451 typedef void (* handle_scan_fn)(Object** pRef, Object* pSec, uint32_t flags, ScanContext* context, bool isDependent);
452 typedef bool (* async_pin_enum_fn)(Object* object, void* context);
453
454
455
456 class IGCHandleStore {
457 public:
458
459     virtual void Uproot() = 0;
460
461     virtual bool ContainsHandle(OBJECTHANDLE handle) = 0;
462
463     virtual OBJECTHANDLE CreateHandleOfType(Object* object, HandleType type) = 0;
464
465     virtual OBJECTHANDLE CreateHandleOfType(Object* object, HandleType type, int heapToAffinitizeTo) = 0;
466
467     virtual OBJECTHANDLE CreateHandleWithExtraInfo(Object* object, HandleType type, void* pExtraInfo) = 0;
468
469     virtual OBJECTHANDLE CreateDependentHandle(Object* primary, Object* secondary) = 0;
470
471     // Relocates async pinned handles from a condemned handle store to the default domain's handle store.
472     //
473     // The two callbacks are called when:
474     //   1. clearIfComplete is called whenever the handle table observes an async pin that is still live.
475     //      The callback gives a chance for the EE to unpin the referents if the overlapped operation is complete.
476     //   2. setHandle is called whenever the GC has relocated the async pin to a new handle table. The passed-in
477     //      handle is the newly-allocated handle in the default domain that should be assigned to the overlapped object.
478     virtual void RelocateAsyncPinnedHandles(IGCHandleStore* pTarget, void (*clearIfComplete)(Object*), void (*setHandle)(Object*, OBJECTHANDLE)) = 0;
479
480     virtual bool EnumerateAsyncPinnedHandles(async_pin_enum_fn callback, void* context) = 0;
481
482     virtual ~IGCHandleStore() {};
483 };
484
485 class IGCHandleManager {
486 public:
487
488     virtual bool Initialize() = 0;
489
490     virtual void Shutdown() = 0;
491
492     virtual void* GetHandleContext(OBJECTHANDLE handle) = 0;
493
494     virtual IGCHandleStore* GetGlobalHandleStore() = 0;
495
496     virtual IGCHandleStore* CreateHandleStore(void* context) = 0;
497
498     virtual void DestroyHandleStore(IGCHandleStore* store) = 0;
499
500     virtual OBJECTHANDLE CreateGlobalHandleOfType(Object* object, HandleType type) = 0;
501
502     virtual OBJECTHANDLE CreateDuplicateHandle(OBJECTHANDLE handle) = 0;
503
504     virtual void DestroyHandleOfType(OBJECTHANDLE handle, HandleType type) = 0;
505
506     virtual void DestroyHandleOfUnknownType(OBJECTHANDLE handle) = 0;
507
508     virtual void SetExtraInfoForHandle(OBJECTHANDLE handle, HandleType type, void* pExtraInfo) = 0;
509
510     virtual void* GetExtraInfoFromHandle(OBJECTHANDLE handle) = 0;
511
512     virtual void StoreObjectInHandle(OBJECTHANDLE handle, Object* object) = 0;
513
514     virtual bool StoreObjectInHandleIfNull(OBJECTHANDLE handle, Object* object) = 0;
515
516     virtual void SetDependentHandleSecondary(OBJECTHANDLE handle, Object* object) = 0;
517
518     virtual Object* GetDependentHandleSecondary(OBJECTHANDLE handle) = 0;
519
520     virtual Object* InterlockedCompareExchangeObjectInHandle(OBJECTHANDLE handle, Object* object, Object* comparandObject) = 0;
521
522     virtual HandleType HandleFetchType(OBJECTHANDLE handle) = 0;
523
524     virtual void TraceRefCountedHandles(HANDLESCANPROC callback, uintptr_t param1, uintptr_t param2) = 0;
525 };
526
527 // IGCHeap is the interface that the VM will use when interacting with the GC.
528 class IGCHeap {
529 public:
530     /*
531     ===========================================================================
532     Hosting APIs. These are used by GC hosting. The code that
533     calls these methods may possibly be moved behind the interface -
534     today, the VM handles the setting of segment size and max gen 0 size.
535     (See src/vm/corehost.cpp)
536     ===========================================================================
537     */
538
539     // Returns whether or not the given size is a valid segment size.
540     virtual bool IsValidSegmentSize(size_t size) = 0;
541
542     // Returns whether or not the given size is a valid gen 0 max size.
543     virtual bool IsValidGen0MaxSize(size_t size) = 0;
544
545     // Gets a valid segment size.
546     virtual size_t GetValidSegmentSize(bool large_seg = false) = 0;
547
548     // Sets the limit for reserved virtual memory.
549     virtual void SetReservedVMLimit(size_t vmlimit) = 0;
550
551     /*
552     ===========================================================================
553     Concurrent GC routines. These are used in various places in the VM
554     to synchronize with the GC, when the VM wants to update something that
555     the GC is potentially using, if it's doing a background GC.
556
557     Concrete examples of this are moving async pinned handles across appdomains
558     and profiling/ETW scenarios.
559     ===========================================================================
560     */
561
562     // Blocks until any running concurrent GCs complete.
563     virtual void WaitUntilConcurrentGCComplete() = 0;
564
565     // Returns true if a concurrent GC is in progress, false otherwise.
566     virtual bool IsConcurrentGCInProgress() = 0;
567
568     // Temporarily enables concurrent GC, used during profiling.
569     virtual void TemporaryEnableConcurrentGC() = 0;
570
571     // Temporarily disables concurrent GC, used during profiling.
572     virtual void TemporaryDisableConcurrentGC() = 0;
573
574     // Returns whether or not Concurrent GC is enabled.
575     virtual bool IsConcurrentGCEnabled() = 0;
576
577     // Wait for a concurrent GC to complete if one is in progress, with the given timeout.
578     virtual HRESULT WaitUntilConcurrentGCCompleteAsync(int millisecondsTimeout) = 0;    // Use in native threads. TRUE if succeed. FALSE if failed or timeout
579
580
581     /*
582     ===========================================================================
583     Finalization routines. These are used by the finalizer thread to communicate
584     with the GC.
585     ===========================================================================
586     */
587
588     // Finalizes an app domain by finalizing objects within that app domain.
589     virtual bool FinalizeAppDomain(void* pDomain, bool fRunFinalizers) = 0;
590
591     // Finalizes all registered objects for shutdown, even if they are still reachable.
592     virtual void SetFinalizeQueueForShutdown(bool fHasLock) = 0;
593
594     // Gets the number of finalizable objects.
595     virtual size_t GetNumberOfFinalizable() = 0;
596
597     // Traditionally used by the finalizer thread on shutdown to determine
598     // whether or not to time out. Returns true if the GC lock has not been taken.
599     virtual bool ShouldRestartFinalizerWatchDog() = 0;
600
601     // Gets the next finalizable object.
602     virtual Object* GetNextFinalizable() = 0;
603
604     // Sets whether or not the GC should report all finalizable objects as
605     // ready to be finalized, instead of only collectable objects.
606     virtual void SetFinalizeRunOnShutdown(bool value) = 0;
607
608     /*
609     ===========================================================================
610     BCL routines. These are routines that are directly exposed by mscorlib
611     as a part of the `System.GC` class. These routines behave in the same
612     manner as the functions on `System.GC`.
613     ===========================================================================
614     */
615
616     // Gets memory related information -
617     // highMemLoadThreshold - physical memory load (in percentage) when GC will start to 
618     // react aggressively to reclaim memory.
619     // totalPhysicalMem - the total amount of phyiscal memory available on the machine and the memory
620     // limit set on the container if running in a container.
621     // lastRecordedMemLoad - physical memory load in percentage recorded in the last GC
622     // lastRecordedHeapSize - total managed heap size recorded in the last GC
623     // lastRecordedFragmentation - total fragmentation in the managed heap recorded in the last GC
624     virtual void GetMemoryInfo(uint32_t* highMemLoadThreshold, 
625                                uint64_t* totalPhysicalMem, 
626                                uint32_t* lastRecordedMemLoad,
627                                size_t* lastRecordedHeapSize,
628                                size_t* lastRecordedFragmentation) = 0;
629
630     // Gets the current GC latency mode.
631     virtual int GetGcLatencyMode() = 0;
632
633     // Sets the current GC latency mode. newLatencyMode has already been
634     // verified by mscorlib to be valid.
635     virtual int SetGcLatencyMode(int newLatencyMode) = 0;
636
637     // Gets the current LOH compaction mode.
638     virtual int GetLOHCompactionMode() = 0;
639
640     // Sets the current LOH compaction mode. newLOHCompactionMode has
641     // already been verified by mscorlib to be valid.
642     virtual void SetLOHCompactionMode(int newLOHCompactionMode) = 0;
643
644     // Registers for a full GC notification, raising a notification if the gen 2 or
645     // LOH object heap thresholds are exceeded.
646     virtual bool RegisterForFullGCNotification(uint32_t gen2Percentage, uint32_t lohPercentage) = 0;
647
648     // Cancels a full GC notification that was requested by `RegisterForFullGCNotification`.
649     virtual bool CancelFullGCNotification() = 0;
650
651     // Returns the status of a registered notification for determining whether a blocking
652     // Gen 2 collection is about to be initiated, with the given timeout.
653     virtual int WaitForFullGCApproach(int millisecondsTimeout) = 0;
654
655     // Returns the status of a registered notification for determining whether a blocking
656     // Gen 2 collection has completed, with the given timeout.
657     virtual int WaitForFullGCComplete(int millisecondsTimeout) = 0;
658
659     // Returns the generation in which obj is found. Also used by the VM
660     // in some places, in particular syncblk code.
661     virtual unsigned WhichGeneration(Object* obj) = 0;
662
663     // Returns the number of GCs that have transpired in the given generation
664     // since the beginning of the life of the process. Also used by the VM
665     // for debug code and app domains.
666     virtual int CollectionCount(int generation, int get_bgc_fgc_coutn = 0) = 0;
667
668     // Begins a no-GC region, returning a code indicating whether entering the no-GC
669     // region was successful.
670     virtual int StartNoGCRegion(uint64_t totalSize, bool lohSizeKnown, uint64_t lohSize, bool disallowFullBlockingGC) = 0;
671
672     // Exits a no-GC region.
673     virtual int EndNoGCRegion() = 0;
674
675     // Gets the total number of bytes in use.
676     virtual size_t GetTotalBytesInUse() = 0;
677
678     // Forces a garbage collection of the given generation. Also used extensively
679     // throughout the VM.
680     virtual HRESULT GarbageCollect(int generation = -1, bool low_memory_p = false, int mode = collection_blocking) = 0;
681
682     // Gets the largest GC generation. Also used extensively throughout the VM.
683     virtual unsigned GetMaxGeneration() = 0;
684
685     // Indicates that an object's finalizer should not be run upon the object's collection.
686     virtual void SetFinalizationRun(Object* obj) = 0;
687
688     // Indicates that an object's finalizer should be run upon the object's collection.
689     virtual bool RegisterForFinalization(int gen, Object* obj) = 0;
690
691     /*
692     ===========================================================================
693     Miscellaneous routines used by the VM.
694     ===========================================================================
695     */
696
697     // Initializes the GC heap, returning whether or not the initialization
698     // was successful.
699     virtual HRESULT Initialize() = 0;
700
701     // Returns whether nor this GC was promoted by the last GC.
702     virtual bool IsPromoted(Object* object) = 0;
703
704     // Returns true if this pointer points into a GC heap, false otherwise.
705     virtual bool IsHeapPointer(void* object, bool small_heap_only = false) = 0;
706
707     // Return the generation that has been condemned by the current GC.
708     virtual unsigned GetCondemnedGeneration() = 0;
709
710     // Returns whether or not a GC is in progress.
711     virtual bool IsGCInProgressHelper(bool bConsiderGCStart = false) = 0;
712
713     // Returns the number of GCs that have occured. Mainly used for
714     // sanity checks asserting that a GC has not occured.
715     virtual unsigned GetGcCount() = 0;
716
717     // Gets whether or not the home heap of this alloc context matches the heap
718     // associated with this thread.
719     virtual bool IsThreadUsingAllocationContextHeap(gc_alloc_context* acontext, int thread_number) = 0;
720     
721     // Returns whether or not this object resides in an ephemeral generation.
722     virtual bool IsEphemeral(Object* object) = 0;
723
724     // Blocks until a GC is complete, returning a code indicating the wait was successful.
725     virtual uint32_t WaitUntilGCComplete(bool bConsiderGCStart = false) = 0;
726
727     // "Fixes" an allocation context by binding its allocation pointer to a
728     // location on the heap.
729     virtual void FixAllocContext(gc_alloc_context* acontext, void* arg, void* heap) = 0;
730
731     // Gets the total survived size plus the total allocated bytes on the heap.
732     virtual size_t GetCurrentObjSize() = 0;
733
734     // Sets whether or not a GC is in progress.
735     virtual void SetGCInProgress(bool fInProgress) = 0;
736
737     // Gets whether or not the GC runtime structures are in a valid state for heap traversal.
738     virtual bool RuntimeStructuresValid() = 0;
739
740     // Tells the GC when the VM is suspending threads.
741     virtual void SetSuspensionPending(bool fSuspensionPending) = 0;
742
743     // Tells the GC how many YieldProcessor calls are equal to one scaled yield processor call.
744     virtual void SetYieldProcessorScalingFactor(float yieldProcessorScalingFactor) = 0;
745
746     /*
747     ============================================================================
748     Add/RemoveMemoryPressure support routines. These are on the interface
749     for now, but we should move Add/RemoveMemoryPressure from the VM to the GC.
750     When that occurs, these three routines can be removed from the interface.
751     ============================================================================
752     */
753
754     // Get the timestamp corresponding to the last GC that occured for the
755     // given generation.
756     virtual size_t GetLastGCStartTime(int generation) = 0;
757
758     // Gets the duration of the last GC that occured for the given generation.
759     virtual size_t GetLastGCDuration(int generation) = 0;
760
761     // Gets a timestamp for the current moment in time.
762     virtual size_t GetNow() = 0;
763
764     /*
765     ===========================================================================
766     Allocation routines. These all call into the GC's allocator and may trigger a garbage
767     collection. All allocation routines return NULL when the allocation request
768     couldn't be serviced due to being out of memory.
769     ===========================================================================
770     */
771
772     // Allocates an object on the given allocation context with the given size and flags.
773     // It is the responsibility of the caller to ensure that the passed-in alloc context is
774     // owned by the thread that is calling this function. If using per-thread alloc contexts,
775     // no lock is needed; callers not using per-thread alloc contexts will need to acquire
776     // a lock to ensure that the calling thread has unique ownership over this alloc context;
777     virtual Object* Alloc(gc_alloc_context* acontext, size_t size, uint32_t flags) = 0;
778
779     // Allocates an object on the large object heap with the given size and flags.
780     virtual Object* AllocLHeap(size_t size, uint32_t flags) = 0;
781
782     // Allocates an object on the given allocation context, aligned to 64 bits,
783     // with the given size and flags.
784     // It is the responsibility of the caller to ensure that the passed-in alloc context is
785     // owned by the thread that is calling this function. If using per-thread alloc contexts,
786     // no lock is needed; callers not using per-thread alloc contexts will need to acquire
787     // a lock to ensure that the calling thread has unique ownership over this alloc context.
788     virtual Object* AllocAlign8(gc_alloc_context* acontext, size_t size, uint32_t flags) = 0;
789
790     // This is for the allocator to indicate it's done allocating a large object during a 
791     // background GC as the BGC threads also need to walk LOH.
792     virtual void PublishObject(uint8_t* obj) = 0;
793
794     // Signals the WaitForGCEvent event, indicating that a GC has completed.
795     virtual void SetWaitForGCEvent() = 0;
796
797     // Resets the state of the WaitForGCEvent back to an unsignalled state.
798     virtual void ResetWaitForGCEvent() = 0;
799
800     /*
801     ===========================================================================
802     Heap verification routines. These are used during heap verification only.
803     ===========================================================================
804     */
805     // Returns whether or not this object is in the fixed heap.
806     virtual bool IsObjectInFixedHeap(Object* pObj) = 0;
807
808     // Walks an object and validates its members.
809     virtual void ValidateObjectMember(Object* obj) = 0;
810
811     // Retrieves the next object after the given object. When the EE
812     // is not suspended, the result is not accurate - if the input argument
813     // is in Gen0, the function could return zeroed out memory as the next object.
814     virtual Object* NextObj(Object* object) = 0;
815
816     // Given an interior pointer, return a pointer to the object
817     // containing that pointer. This is safe to call only when the EE is suspended.
818     // When fCollectedGenOnly is true, it only returns the object if it's found in 
819     // the generation(s) that are being collected.
820     virtual Object* GetContainingObject(void* pInteriorPtr, bool fCollectedGenOnly) = 0;
821
822     /*
823     ===========================================================================
824     Profiling routines. Used for event tracing and profiling to broadcast
825     information regarding the heap.
826     ===========================================================================
827     */
828
829     // Walks an object, invoking a callback on each member.
830     virtual void DiagWalkObject(Object* obj, walk_fn fn, void* context) = 0;
831
832     // Walk the heap object by object.
833     virtual void DiagWalkHeap(walk_fn fn, void* context, int gen_number, bool walk_large_object_heap_p) = 0;
834     
835     // Walks the survivors and get the relocation information if objects have moved.
836     virtual void DiagWalkSurvivorsWithType(void* gc_context, record_surv_fn fn, void* diag_context, walk_surv_type type) = 0;
837
838     // Walks the finalization queue.
839     virtual void DiagWalkFinalizeQueue(void* gc_context, fq_walk_fn fn) = 0;
840
841     // Scan roots on finalizer queue. This is a generic function.
842     virtual void DiagScanFinalizeQueue(fq_scan_fn fn, ScanContext* context) = 0;
843
844     // Scan handles for profiling or ETW.
845     virtual void DiagScanHandles(handle_scan_fn fn, int gen_number, ScanContext* context) = 0;
846
847     // Scan dependent handles for profiling or ETW.
848     virtual void DiagScanDependentHandles(handle_scan_fn fn, int gen_number, ScanContext* context) = 0;
849
850     // Describes all generations to the profiler, invoking a callback on each generation.
851     virtual void DiagDescrGenerations(gen_walk_fn fn, void* context) = 0;
852
853     // Traces all GC segments and fires ETW events with information on them.
854     virtual void DiagTraceGCSegments() = 0;
855
856     /*
857     ===========================================================================
858     GC Stress routines. Used only when running under GC Stress.
859     ===========================================================================
860     */
861
862     // Returns TRUE if GC actually happens, otherwise FALSE. The passed alloc context
863     // must not be null.
864     virtual bool StressHeap(gc_alloc_context* acontext) = 0;
865
866     /*
867     ===========================================================================
868     Routines to register read only segments for frozen objects. 
869     Only valid if FEATURE_BASICFREEZE is defined.
870     ===========================================================================
871     */
872
873     // Registers a frozen segment with the GC.
874     virtual segment_handle RegisterFrozenSegment(segment_info *pseginfo) = 0;
875
876     // Unregisters a frozen segment.
877     virtual void UnregisterFrozenSegment(segment_handle seg) = 0;
878
879     // Indicates whether an object is in a frozen segment.
880     virtual bool IsInFrozenSegment(Object *object) = 0;
881
882     /*
883     ===========================================================================
884     Routines for informing the GC about which events are enabled.
885     ===========================================================================
886     */
887
888     // Enables or disables the given keyword or level on the default event provider.
889     virtual void ControlEvents(GCEventKeyword keyword, GCEventLevel level) = 0;
890
891     // Enables or disables the given keyword or level on the private event provider.
892     virtual void ControlPrivateEvents(GCEventKeyword keyword, GCEventLevel level) = 0;
893
894     IGCHeap() {}
895     virtual ~IGCHeap() {}
896 };
897
898 #ifdef WRITE_BARRIER_CHECK
899 void updateGCShadow(Object** ptr, Object* val);
900 #endif
901
902 //constants for the flags parameter to the gc call back
903
904 #define GC_CALL_INTERIOR            0x1
905 #define GC_CALL_PINNED              0x2
906 #define GC_CALL_CHECK_APP_DOMAIN    0x4
907
908 //flags for IGCHeapAlloc(...)
909 #define GC_ALLOC_FINALIZE 0x1
910 #define GC_ALLOC_CONTAINS_REF 0x2
911 #define GC_ALLOC_ALIGN8_BIAS 0x4
912 #define GC_ALLOC_ALIGN8 0x8
913
914 #if defined(USE_CHECKED_OBJECTREFS) && !defined(_NOVM)
915 #define OBJECTREF_TO_UNCHECKED_OBJECTREF(objref)    (*((_UNCHECKED_OBJECTREF*)&(objref)))
916 #define UNCHECKED_OBJECTREF_TO_OBJECTREF(obj)       (OBJECTREF(obj))
917 #else
918 #define OBJECTREF_TO_UNCHECKED_OBJECTREF(objref)    (objref)
919 #define UNCHECKED_OBJECTREF_TO_OBJECTREF(obj)       (obj)
920 #endif
921
922 struct ScanContext
923 {
924     Thread* thread_under_crawl;
925     int thread_number;
926     uintptr_t stack_limit; // Lowest point on the thread stack that the scanning logic is permitted to read
927     bool promotion; //TRUE: Promotion, FALSE: Relocation.
928     bool concurrent; //TRUE: concurrent scanning 
929 #if defined (FEATURE_APPDOMAIN_RESOURCE_MONITORING) || defined (DACCESS_COMPILE)
930     AppDomain *pCurrentDomain;
931 #else
932     void* _unused1;
933 #endif //FEATURE_APPDOMAIN_RESOURCE_MONITORING || DACCESS_COMPILE
934     void* pMD;
935 #if defined(GC_PROFILING) || defined(FEATURE_EVENT_TRACE)
936     EtwGCRootKind dwEtwRootKind;
937 #else
938     EtwGCRootKind _unused3;
939 #endif // GC_PROFILING || FEATURE_EVENT_TRACE
940     
941     ScanContext()
942     {
943         LIMITED_METHOD_CONTRACT;
944
945         thread_under_crawl = 0;
946         thread_number = -1;
947         stack_limit = 0;
948         promotion = false;
949         concurrent = false;
950         pMD = NULL;
951 #if defined(GC_PROFILING) || defined(FEATURE_EVENT_TRACE)
952         dwEtwRootKind = kEtwGCRootKindOther;
953 #endif
954     }
955 };
956
957 // These types are used as part of the loader protocol between the EE
958 // and the GC.
959 struct VersionInfo {
960     uint32_t MajorVersion;
961     uint32_t MinorVersion;
962     uint32_t BuildVersion;
963     const char* Name;
964 };
965
966 typedef void (*GC_VersionInfoFunction)(
967     /* Out */ VersionInfo*
968 );
969
970 typedef HRESULT (*GC_InitializeFunction)(
971     /* In  */ IGCToCLR*,
972     /* Out */ IGCHeap**,
973     /* Out */ IGCHandleManager**,
974     /* Out */ GcDacVars*
975 );
976
977 #endif // _GC_INTERFACE_H_