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.
5 #ifndef _GC_INTERFACE_H_
6 #define _GC_INTERFACE_H_
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
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
18 struct gc_alloc_context;
21 // Callback passed to GcScanRoots.
22 typedef void promote_func(PTR_PTR_Object, ScanContext*, uint32_t);
24 // Callback passed to GcEnumAllocContexts.
25 typedef void enum_alloc_context_func(gc_alloc_context*, void*);
27 // Callback passed to CreateBackgroundThread.
28 typedef uint32_t (__stdcall *GCBackgroundThreadFunction)(void* param);
30 // Struct often used as a parameter to callbacks.
38 // SUSPEND_REASON is the reason why the GC wishes to suspend the EE,
39 // used as an argument to IGCToCLR::SuspendEE.
43 SUSPEND_FOR_GC_PREP = 6
53 // Different operations that can be done by GCToEEInterface::StompWriteBarrier
54 enum class WriteBarrierOp
63 // Arguments to GCToEEInterface::StompWriteBarrier
64 struct WriteBarrierParameters
66 // The operation that StompWriteBarrier will perform.
67 WriteBarrierOp operation;
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;
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;
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.
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;
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;
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;
101 // The new start of the ephemeral generation.
102 // Used for WriteBarrierOp::StompEphemeral.
103 uint8_t* ephemeral_low;
105 // The new end of the ephemeral generation.
106 // Used for WriteBarrierOp::StompEphemeral.
107 uint8_t* ephemeral_high;
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;
114 // Opaque type for tracking object pointers
115 #ifndef DACCESS_COMPILE
116 struct OBJECTHANDLE__
120 typedef struct OBJECTHANDLE__* OBJECTHANDLE;
122 typedef uintptr_t OBJECTHANDLE;
128 typedef void (CALLBACK *HANDLESCANPROC)(PTR_UNCHECKED_OBJECTREF pref, uintptr_t *pExtraInfo, uintptr_t param1, uintptr_t param2);
130 #include "gcinterface.ee.h"
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
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.
149 LIMITED_METHOD_CONTRACT;
161 #include "gcinterface.dac.h"
163 // stub type to abstract a heap segment
164 struct gc_heap_segment_stub;
165 typedef gc_heap_segment_stub *segment_handle;
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)
176 #ifdef PROFILING_SUPPORTED
177 #define GC_PROFILING //Turn on profiling
178 #endif // PROFILING_SUPPORTED
180 #define LARGE_OBJECT_SIZE ((size_t)(85000))
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)))
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
192 class IGCHandleManager;
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;
203 * GCEventProvider represents one of the two providers that the GC can
204 * fire events from: the default and private providers.
208 GCEventProvider_Default = 0,
209 GCEventProvider_Private = 1
212 // Event levels corresponding to events that can be fired by the GC.
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
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!
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
255 // !!!!!!!!!!!!!!!!!!!!!!!
256 // make sure you change the def in bcl\system\gc.cs
257 // if you change this!
260 collection_non_blocking = 0x00000001,
261 collection_blocking = 0x00000002,
262 collection_optimized = 0x00000004,
263 collection_compacting = 0x00000008
265 , collection_gcstress = 0x80000000
266 #endif // STRESS_HEAP
269 // !!!!!!!!!!!!!!!!!!!!!!!
270 // make sure you change the def in bcl\system\gc.cs
271 // if you change this!
272 enum wait_full_gc_status
274 wait_full_gc_success = 0,
275 wait_full_gc_failed = 1,
276 wait_full_gc_cancelled = 2,
277 wait_full_gc_timeout = 3,
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
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
292 enum end_no_gc_region_status
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
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.
311 * SHORT-LIVED WEAK HANDLES
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.
320 HNDTYPE_WEAK_SHORT = 0,
323 * LONG-LIVED WEAK HANDLES
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.
331 HNDTYPE_WEAK_LONG = 1,
332 HNDTYPE_WEAK_DEFAULT = 1,
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.
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
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!
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.
368 HNDTYPE_VARIABLE = 4,
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.
376 * N.B. These are currently NOT general purpose.
377 * The implementation is tied to COM Interop.
380 HNDTYPE_REFCOUNTED = 5,
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
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.
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.
397 HNDTYPE_DEPENDENT = 6,
400 * PINNED HANDLES for asynchronous operation
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
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!
411 HNDTYPE_ASYNCPINNED = 7,
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
422 HNDTYPE_SIZEDREF = 8,
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
436 HNDTYPE_WEAK_WINRT = 9
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);
456 class IGCHandleStore {
459 virtual void Uproot() = 0;
461 virtual bool ContainsHandle(OBJECTHANDLE handle) = 0;
463 virtual OBJECTHANDLE CreateHandleOfType(Object* object, HandleType type) = 0;
465 virtual OBJECTHANDLE CreateHandleOfType(Object* object, HandleType type, int heapToAffinitizeTo) = 0;
467 virtual OBJECTHANDLE CreateHandleWithExtraInfo(Object* object, HandleType type, void* pExtraInfo) = 0;
469 virtual OBJECTHANDLE CreateDependentHandle(Object* primary, Object* secondary) = 0;
471 // Relocates async pinned handles from a condemned handle store to the default domain's handle store.
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;
480 virtual bool EnumerateAsyncPinnedHandles(async_pin_enum_fn callback, void* context) = 0;
482 virtual ~IGCHandleStore() {};
485 class IGCHandleManager {
488 virtual bool Initialize() = 0;
490 virtual void Shutdown() = 0;
492 virtual void* GetHandleContext(OBJECTHANDLE handle) = 0;
494 virtual IGCHandleStore* GetGlobalHandleStore() = 0;
496 virtual IGCHandleStore* CreateHandleStore(void* context) = 0;
498 virtual void DestroyHandleStore(IGCHandleStore* store) = 0;
500 virtual OBJECTHANDLE CreateGlobalHandleOfType(Object* object, HandleType type) = 0;
502 virtual OBJECTHANDLE CreateDuplicateHandle(OBJECTHANDLE handle) = 0;
504 virtual void DestroyHandleOfType(OBJECTHANDLE handle, HandleType type) = 0;
506 virtual void DestroyHandleOfUnknownType(OBJECTHANDLE handle) = 0;
508 virtual void SetExtraInfoForHandle(OBJECTHANDLE handle, HandleType type, void* pExtraInfo) = 0;
510 virtual void* GetExtraInfoFromHandle(OBJECTHANDLE handle) = 0;
512 virtual void StoreObjectInHandle(OBJECTHANDLE handle, Object* object) = 0;
514 virtual bool StoreObjectInHandleIfNull(OBJECTHANDLE handle, Object* object) = 0;
516 virtual void SetDependentHandleSecondary(OBJECTHANDLE handle, Object* object) = 0;
518 virtual Object* GetDependentHandleSecondary(OBJECTHANDLE handle) = 0;
520 virtual Object* InterlockedCompareExchangeObjectInHandle(OBJECTHANDLE handle, Object* object, Object* comparandObject) = 0;
522 virtual HandleType HandleFetchType(OBJECTHANDLE handle) = 0;
524 virtual void TraceRefCountedHandles(HANDLESCANPROC callback, uintptr_t param1, uintptr_t param2) = 0;
527 // IGCHeap is the interface that the VM will use when interacting with the GC.
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 ===========================================================================
539 // Returns whether or not the given size is a valid segment size.
540 virtual bool IsValidSegmentSize(size_t size) = 0;
542 // Returns whether or not the given size is a valid gen 0 max size.
543 virtual bool IsValidGen0MaxSize(size_t size) = 0;
545 // Gets a valid segment size.
546 virtual size_t GetValidSegmentSize(bool large_seg = false) = 0;
548 // Sets the limit for reserved virtual memory.
549 virtual void SetReservedVMLimit(size_t vmlimit) = 0;
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.
557 Concrete examples of this are moving async pinned handles across appdomains
558 and profiling/ETW scenarios.
559 ===========================================================================
562 // Blocks until any running concurrent GCs complete.
563 virtual void WaitUntilConcurrentGCComplete() = 0;
565 // Returns true if a concurrent GC is in progress, false otherwise.
566 virtual bool IsConcurrentGCInProgress() = 0;
568 // Temporarily enables concurrent GC, used during profiling.
569 virtual void TemporaryEnableConcurrentGC() = 0;
571 // Temporarily disables concurrent GC, used during profiling.
572 virtual void TemporaryDisableConcurrentGC() = 0;
574 // Returns whether or not Concurrent GC is enabled.
575 virtual bool IsConcurrentGCEnabled() = 0;
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
582 ===========================================================================
583 Finalization routines. These are used by the finalizer thread to communicate
585 ===========================================================================
588 // Finalizes an app domain by finalizing objects within that app domain.
589 virtual bool FinalizeAppDomain(void* pDomain, bool fRunFinalizers) = 0;
591 // Finalizes all registered objects for shutdown, even if they are still reachable.
592 virtual void SetFinalizeQueueForShutdown(bool fHasLock) = 0;
594 // Gets the number of finalizable objects.
595 virtual size_t GetNumberOfFinalizable() = 0;
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;
601 // Gets the next finalizable object.
602 virtual Object* GetNextFinalizable() = 0;
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;
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 ===========================================================================
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;
630 // Gets the current GC latency mode.
631 virtual int GetGcLatencyMode() = 0;
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;
637 // Gets the current LOH compaction mode.
638 virtual int GetLOHCompactionMode() = 0;
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;
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;
648 // Cancels a full GC notification that was requested by `RegisterForFullGCNotification`.
649 virtual bool CancelFullGCNotification() = 0;
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;
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;
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;
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;
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;
672 // Exits a no-GC region.
673 virtual int EndNoGCRegion() = 0;
675 // Gets the total number of bytes in use.
676 virtual size_t GetTotalBytesInUse() = 0;
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;
682 // Gets the largest GC generation. Also used extensively throughout the VM.
683 virtual unsigned GetMaxGeneration() = 0;
685 // Indicates that an object's finalizer should not be run upon the object's collection.
686 virtual void SetFinalizationRun(Object* obj) = 0;
688 // Indicates that an object's finalizer should be run upon the object's collection.
689 virtual bool RegisterForFinalization(int gen, Object* obj) = 0;
692 ===========================================================================
693 Miscellaneous routines used by the VM.
694 ===========================================================================
697 // Initializes the GC heap, returning whether or not the initialization
699 virtual HRESULT Initialize() = 0;
701 // Returns whether nor this GC was promoted by the last GC.
702 virtual bool IsPromoted(Object* object) = 0;
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;
707 // Return the generation that has been condemned by the current GC.
708 virtual unsigned GetCondemnedGeneration() = 0;
710 // Returns whether or not a GC is in progress.
711 virtual bool IsGCInProgressHelper(bool bConsiderGCStart = false) = 0;
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;
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;
721 // Returns whether or not this object resides in an ephemeral generation.
722 virtual bool IsEphemeral(Object* object) = 0;
724 // Blocks until a GC is complete, returning a code indicating the wait was successful.
725 virtual uint32_t WaitUntilGCComplete(bool bConsiderGCStart = false) = 0;
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;
731 // Gets the total survived size plus the total allocated bytes on the heap.
732 virtual size_t GetCurrentObjSize() = 0;
734 // Sets whether or not a GC is in progress.
735 virtual void SetGCInProgress(bool fInProgress) = 0;
737 // Gets whether or not the GC runtime structures are in a valid state for heap traversal.
738 virtual bool RuntimeStructuresValid() = 0;
740 // Tells the GC when the VM is suspending threads.
741 virtual void SetSuspensionPending(bool fSuspensionPending) = 0;
743 // Tells the GC how many YieldProcessor calls are equal to one scaled yield processor call.
744 virtual void SetYieldProcessorScalingFactor(float yieldProcessorScalingFactor) = 0;
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 ============================================================================
754 // Get the timestamp corresponding to the last GC that occured for the
756 virtual size_t GetLastGCStartTime(int generation) = 0;
758 // Gets the duration of the last GC that occured for the given generation.
759 virtual size_t GetLastGCDuration(int generation) = 0;
761 // Gets a timestamp for the current moment in time.
762 virtual size_t GetNow() = 0;
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 ===========================================================================
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;
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;
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;
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;
794 // Signals the WaitForGCEvent event, indicating that a GC has completed.
795 virtual void SetWaitForGCEvent() = 0;
797 // Resets the state of the WaitForGCEvent back to an unsignalled state.
798 virtual void ResetWaitForGCEvent() = 0;
801 ===========================================================================
802 Heap verification routines. These are used during heap verification only.
803 ===========================================================================
805 // Returns whether or not this object is in the fixed heap.
806 virtual bool IsObjectInFixedHeap(Object* pObj) = 0;
808 // Walks an object and validates its members.
809 virtual void ValidateObjectMember(Object* obj) = 0;
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;
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;
823 ===========================================================================
824 Profiling routines. Used for event tracing and profiling to broadcast
825 information regarding the heap.
826 ===========================================================================
829 // Walks an object, invoking a callback on each member.
830 virtual void DiagWalkObject(Object* obj, walk_fn fn, void* context) = 0;
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;
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;
838 // Walks the finalization queue.
839 virtual void DiagWalkFinalizeQueue(void* gc_context, fq_walk_fn fn) = 0;
841 // Scan roots on finalizer queue. This is a generic function.
842 virtual void DiagScanFinalizeQueue(fq_scan_fn fn, ScanContext* context) = 0;
844 // Scan handles for profiling or ETW.
845 virtual void DiagScanHandles(handle_scan_fn fn, int gen_number, ScanContext* context) = 0;
847 // Scan dependent handles for profiling or ETW.
848 virtual void DiagScanDependentHandles(handle_scan_fn fn, int gen_number, ScanContext* context) = 0;
850 // Describes all generations to the profiler, invoking a callback on each generation.
851 virtual void DiagDescrGenerations(gen_walk_fn fn, void* context) = 0;
853 // Traces all GC segments and fires ETW events with information on them.
854 virtual void DiagTraceGCSegments() = 0;
857 ===========================================================================
858 GC Stress routines. Used only when running under GC Stress.
859 ===========================================================================
862 // Returns TRUE if GC actually happens, otherwise FALSE. The passed alloc context
864 virtual bool StressHeap(gc_alloc_context* acontext) = 0;
867 ===========================================================================
868 Routines to register read only segments for frozen objects.
869 Only valid if FEATURE_BASICFREEZE is defined.
870 ===========================================================================
873 // Registers a frozen segment with the GC.
874 virtual segment_handle RegisterFrozenSegment(segment_info *pseginfo) = 0;
876 // Unregisters a frozen segment.
877 virtual void UnregisterFrozenSegment(segment_handle seg) = 0;
879 // Indicates whether an object is in a frozen segment.
880 virtual bool IsInFrozenSegment(Object *object) = 0;
883 ===========================================================================
884 Routines for informing the GC about which events are enabled.
885 ===========================================================================
888 // Enables or disables the given keyword or level on the default event provider.
889 virtual void ControlEvents(GCEventKeyword keyword, GCEventLevel level) = 0;
891 // Enables or disables the given keyword or level on the private event provider.
892 virtual void ControlPrivateEvents(GCEventKeyword keyword, GCEventLevel level) = 0;
895 virtual ~IGCHeap() {}
898 #ifdef WRITE_BARRIER_CHECK
899 void updateGCShadow(Object** ptr, Object* val);
902 //constants for the flags parameter to the gc call back
904 #define GC_CALL_INTERIOR 0x1
905 #define GC_CALL_PINNED 0x2
906 #define GC_CALL_CHECK_APP_DOMAIN 0x4
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
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))
918 #define OBJECTREF_TO_UNCHECKED_OBJECTREF(objref) (objref)
919 #define UNCHECKED_OBJECTREF_TO_OBJECTREF(obj) (obj)
924 Thread* thread_under_crawl;
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;
933 #endif //FEATURE_APPDOMAIN_RESOURCE_MONITORING || DACCESS_COMPILE
935 #if defined(GC_PROFILING) || defined(FEATURE_EVENT_TRACE)
936 EtwGCRootKind dwEtwRootKind;
938 EtwGCRootKind _unused3;
939 #endif // GC_PROFILING || FEATURE_EVENT_TRACE
943 LIMITED_METHOD_CONTRACT;
945 thread_under_crawl = 0;
951 #if defined(GC_PROFILING) || defined(FEATURE_EVENT_TRACE)
952 dwEtwRootKind = kEtwGCRootKindOther;
957 // These types are used as part of the loader protocol between the EE
960 uint32_t MajorVersion;
961 uint32_t MinorVersion;
962 uint32_t BuildVersion;
966 typedef void (*GC_VersionInfoFunction)(
967 /* Out */ VersionInfo*
970 typedef HRESULT (*GC_InitializeFunction)(
973 /* Out */ IGCHandleManager**,
977 #endif // _GC_INTERFACE_H_