diff --git a/src/coreclr/debug/daccess/daccess.cpp b/src/coreclr/debug/daccess/daccess.cpp index 5deb0937c3acbd..8af160fd73d064 100644 --- a/src/coreclr/debug/daccess/daccess.cpp +++ b/src/coreclr/debug/daccess/daccess.cpp @@ -3245,6 +3245,10 @@ ClrDataAccess::QueryInterface(THIS_ { ifaceRet = static_cast(this); } + else if (IsEqualIID(interfaceId, __uuidof(ISOSDacInterface16))) + { + ifaceRet = static_cast(this); + } else { *iface = NULL; diff --git a/src/coreclr/debug/daccess/dacimpl.h b/src/coreclr/debug/daccess/dacimpl.h index 588777171333db..c8947048ec92ef 100644 --- a/src/coreclr/debug/daccess/dacimpl.h +++ b/src/coreclr/debug/daccess/dacimpl.h @@ -814,7 +814,8 @@ class ClrDataAccess public ISOSDacInterface12, public ISOSDacInterface13, public ISOSDacInterface14, - public ISOSDacInterface15 + public ISOSDacInterface15, + public ISOSDacInterface16 { public: ClrDataAccess(ICorDebugDataTarget * pTarget, ICLRDataTarget * pLegacyTarget=0); @@ -1222,6 +1223,9 @@ class ClrDataAccess // ISOSDacInterface15 virtual HRESULT STDMETHODCALLTYPE GetMethodTableSlotEnumerator(CLRDATA_ADDRESS mt, ISOSMethodEnum **enumerator); + // ISOSDacInterface16 + virtual HRESULT STDMETHODCALLTYPE GetGCDynamicAdaptationMode(int* pDynamicAdaptationMode); + // // ClrDataAccess. // diff --git a/src/coreclr/debug/daccess/request.cpp b/src/coreclr/debug/daccess/request.cpp index 7a07a8c0f6c3c1..9c6669b0810f76 100644 --- a/src/coreclr/debug/daccess/request.cpp +++ b/src/coreclr/debug/daccess/request.cpp @@ -2908,6 +2908,24 @@ ClrDataAccess::GetGCHeapStaticData(struct DacpGcHeapDetails *detailsData) return hr; } +HRESULT +ClrDataAccess::GetGCDynamicAdaptationMode(int* pDynamicAdaptationMode) +{ + SOSDacEnter(); + if (IsDatasEnabled()) + { + *pDynamicAdaptationMode = *g_gcDacGlobals->dynamic_adaptation_mode; + hr = S_OK; + } + else + { + *pDynamicAdaptationMode = -1; + hr = S_FALSE; + } + SOSDacLeave(); + return hr; +} + HRESULT ClrDataAccess::GetHeapSegmentData(CLRDATA_ADDRESS seg, struct DacpHeapSegmentData *heapSegment) { diff --git a/src/coreclr/debug/daccess/request_common.h b/src/coreclr/debug/daccess/request_common.h index 623761ba250687..e2f4531e267b97 100644 --- a/src/coreclr/debug/daccess/request_common.h +++ b/src/coreclr/debug/daccess/request_common.h @@ -103,14 +103,47 @@ HeapTableIndex(DPTR(unused_gc_heap**) heaps, size_t index) DacEnumMemoryRegion(p_##field_name.GetAddr(), sizeof(field_type) * array_length); \ } +inline bool UseBuildVariant() +{ + int major = g_gcDacGlobals->major_version_number; + int minor = g_gcDacGlobals->minor_version_number; + return (major > 2) || (major == 2 && minor >= 4); +} + inline bool IsRegionGCEnabled() { - return (g_gcDacGlobals->minor_version_number & 1) != 0; + if (UseBuildVariant()) + { + return (*(g_gcDacGlobals->build_variant) & build_variant_use_region) != 0; + } + else + { + return (g_gcDacGlobals->minor_version_number & 1) != 0; + } } inline bool IsBackgroundGCEnabled() { - return (g_gcDacGlobals->minor_version_number & 2) == 0; + if (UseBuildVariant()) + { + return (*(g_gcDacGlobals->build_variant) & build_variant_background_gc) != 0; + } + else + { + return (g_gcDacGlobals->minor_version_number & 2) == 0; + } +} + +inline bool IsDatasEnabled() +{ + if (UseBuildVariant()) + { + return (*(g_gcDacGlobals->build_variant) & build_variant_dynamic_heap_count) != 0; + } + else + { + return false; + } } // Load an instance of dac_gc_heap for the heap pointed by heap. diff --git a/src/coreclr/gc/dac_gcheap_fields.h b/src/coreclr/gc/dac_gcheap_fields.h index 39b2dca81008ac..862ef04fac4cb9 100644 --- a/src/coreclr/gc/dac_gcheap_fields.h +++ b/src/coreclr/gc/dac_gcheap_fields.h @@ -53,4 +53,4 @@ DEFINE_MISSING_FIELD(freeable_uoh_segment) DEFINE_ARRAY_FIELD (free_regions, dac_region_free_list, FREE_REGION_KINDS) #else DEFINE_MISSING_FIELD(free_regions) -#endif // ALL_FIELDS +#endif // defined(ALL_FIELDS) || defined(USE_REGIONS) diff --git a/src/coreclr/gc/gc.cpp b/src/coreclr/gc/gc.cpp index 3b717a6e239157..8bc4043b54e7e2 100644 --- a/src/coreclr/gc/gc.cpp +++ b/src/coreclr/gc/gc.cpp @@ -53194,6 +53194,7 @@ bool GCHeap::IsConcurrentGCEnabled() void PopulateDacVars(GcDacVars *gcDacVars) { bool v2 = gcDacVars->minor_version_number >= 2; + bool v4 = gcDacVars->minor_version_number >= 4; #define DEFINE_FIELD(field_name, field_type) offsetof(CLASS_NAME, field_name), #define DEFINE_DPTR_FIELD(field_name, field_type) offsetof(CLASS_NAME, field_name), @@ -53225,15 +53226,16 @@ void PopulateDacVars(GcDacVars *gcDacVars) // work differently than .Net SOS. When making breaking changes here you may need to // find NativeAOT's equivalent of SOS_BREAKING_CHANGE_VERSION and increment it. gcDacVars->major_version_number = 2; - gcDacVars->minor_version_number = 0; + gcDacVars->minor_version_number = 4; if (v2) { gcDacVars->total_bookkeeping_elements = total_bookkeeping_elements; gcDacVars->card_table_info_size = sizeof(card_table_info); } + g_build_variant = 0; #ifdef USE_REGIONS - gcDacVars->minor_version_number |= 1; + g_build_variant |= build_variant_use_region; if (v2) { gcDacVars->count_free_region_kinds = count_free_region_kinds; @@ -53242,8 +53244,11 @@ void PopulateDacVars(GcDacVars *gcDacVars) } #endif //USE_REGIONS #ifndef BACKGROUND_GC - gcDacVars->minor_version_number |= 2; + g_build_variant |= build_variant_background_gc; #endif //!BACKGROUND_GC +#ifdef DYNAMIC_HEAP_COUNT + g_build_variant |= build_variant_dynamic_heap_count; +#endif //DYNAMIC_HEAP_COUNT gcDacVars->built_with_svr = &g_built_with_svr_gc; gcDacVars->build_variant = &g_build_variant; gcDacVars->gc_structures_invalid_cnt = const_cast(&GCScan::m_GcStructuresInvalidCnt); @@ -53319,6 +53324,14 @@ void PopulateDacVars(GcDacVars *gcDacVars) { gcDacVars->bookkeeping_start = &gc_heap::bookkeeping_start; } + if (v4) + { +#ifdef DYNAMIC_HEAP_COUNT + gcDacVars->dynamic_adaptation_mode = &gc_heap::dynamic_adaptation_mode; +#else + gcDacVars->dynamic_adaptation_mode = nullptr; +#endif //DYNAMIC_HEAP_COUNT + } } int GCHeap::RefreshMemoryLimit() diff --git a/src/coreclr/gc/gcinterface.dac.h b/src/coreclr/gc/gcinterface.dac.h index b3be7b09cee60f..fadb890ccc638a 100644 --- a/src/coreclr/gc/gcinterface.dac.h +++ b/src/coreclr/gc/gcinterface.dac.h @@ -206,6 +206,10 @@ struct unused_generation uint8_t unused; }; +#define build_variant_use_region 1 +#define build_variant_background_gc 2 +#define build_variant_dynamic_heap_count 4 + // The DAC links against six symbols that build as part of the VM DACCESS_COMPILE // build. These symbols are considered to be GC-private functions, but the DAC needs // to use them in order to perform some handle-related functions. These six functions diff --git a/src/coreclr/gc/gcinterface.dacvars.def b/src/coreclr/gc/gcinterface.dacvars.def index a78b9d720930c6..fc071e881faef8 100644 --- a/src/coreclr/gc/gcinterface.dacvars.def +++ b/src/coreclr/gc/gcinterface.dacvars.def @@ -88,6 +88,9 @@ GC_DAC_VAL (int, total_bookkeeping_elements) GC_DAC_VAL (int, count_free_region_kinds) GC_DAC_VAL (size_t, card_table_info_size) +// Here is where v5.4 fields starts +GC_DAC_VAR (int, dynamic_adaptation_mode) + #undef GC_DAC_VAR #undef GC_DAC_ARRAY_VAR #undef GC_DAC_PTR_VAR diff --git a/src/coreclr/gc/gcinterface.h b/src/coreclr/gc/gcinterface.h index b41d3005ae6721..bb1e5bc173e1b7 100644 --- a/src/coreclr/gc/gcinterface.h +++ b/src/coreclr/gc/gcinterface.h @@ -11,7 +11,7 @@ // The minor version of the IGCHeap interface. Non-breaking changes are required // to bump the minor version number. GCs and EEs with minor version number // mismatches can still interoperate correctly, with some care. -#define GC_INTERFACE_MINOR_VERSION 3 +#define GC_INTERFACE_MINOR_VERSION 4 // The major version of the IGCToCLR interface. Breaking changes to this interface // require bumps in the major version number. diff --git a/src/coreclr/inc/sospriv.idl b/src/coreclr/inc/sospriv.idl index 141f597dcb4e94..0820d20386b9e0 100644 --- a/src/coreclr/inc/sospriv.idl +++ b/src/coreclr/inc/sospriv.idl @@ -562,3 +562,13 @@ interface ISOSDacInterface15 : IUnknown { HRESULT GetMethodTableSlotEnumerator(CLRDATA_ADDRESS mt, ISOSMethodEnum **enumerator); } + +[ + object, + local, + uuid(4ba12ff8-daac-4e43-ac56-98cf8d5c595d) +] +interface ISOSDacInterface16 : IUnknown +{ + HRESULT GetGCDynamicAdaptationMode(int* pDynamicAdaptationMode); +} diff --git a/src/coreclr/pal/prebuilt/idl/sospriv_i.cpp b/src/coreclr/pal/prebuilt/idl/sospriv_i.cpp index 579be51d356f7f..f3c4867a3a0ace 100644 --- a/src/coreclr/pal/prebuilt/idl/sospriv_i.cpp +++ b/src/coreclr/pal/prebuilt/idl/sospriv_i.cpp @@ -127,6 +127,9 @@ MIDL_DEFINE_GUID(IID, IID_ISOSMethodEnum,0x3c0fe725,0xc324,0x4a4f,0x81,0x00,0xd3 MIDL_DEFINE_GUID(IID, IID_ISOSDacInterface15,0x7ed81261,0x52a9,0x4a23,0xa3,0x58,0xc3,0x31,0x3d,0xea,0x30,0xa8); + +MIDL_DEFINE_GUID(IID, IID_ISOSDacInterface16,0x4ba12ff8,0xdaac,0x4e43,0xac,0x56,0x98,0xcf,0x8d,0x5c,0x59,0x5d); + #undef MIDL_DEFINE_GUID #ifdef __cplusplus diff --git a/src/coreclr/pal/prebuilt/inc/sospriv.h b/src/coreclr/pal/prebuilt/inc/sospriv.h index a3d741f740defa..4ff12d95b74894 100644 --- a/src/coreclr/pal/prebuilt/inc/sospriv.h +++ b/src/coreclr/pal/prebuilt/inc/sospriv.h @@ -3685,6 +3685,86 @@ EXTERN_C const IID IID_ISOSDacInterface15; #endif /* __ISOSDacInterface15_INTERFACE_DEFINED__ */ +#ifndef __ISOSDacInterface16_INTERFACE_DEFINED__ +#define __ISOSDacInterface16_INTERFACE_DEFINED__ + +/* interface ISOSDacInterface16 */ +/* [uuid][local][object] */ + + +EXTERN_C const IID IID_ISOSDacInterface16; + +#if defined(__cplusplus) && !defined(CINTERFACE) + + MIDL_INTERFACE("4ba12ff8-daac-4e43-ac56-98cf8d5c595d") + ISOSDacInterface16 : public IUnknown + { + public: + virtual HRESULT STDMETHODCALLTYPE GetGCDynamicAdaptationMode( + int *pDynamicAdaptationMode) = 0; + + }; + + +#else /* C style interface */ + + typedef struct ISOSDacInterface16Vtbl + { + BEGIN_INTERFACE + + HRESULT ( STDMETHODCALLTYPE *QueryInterface )( + ISOSDacInterface16 * This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + _COM_Outptr_ void **ppvObject); + + ULONG ( STDMETHODCALLTYPE *AddRef )( + ISOSDacInterface16 * This); + + ULONG ( STDMETHODCALLTYPE *Release )( + ISOSDacInterface16 * This); + + HRESULT ( STDMETHODCALLTYPE *GetGCDynamicAdaptationMode )( + ISOSDacInterface16 * This, + int *pDynamicAdaptationMode); + + END_INTERFACE + } ISOSDacInterface16Vtbl; + + interface ISOSDacInterface16 + { + CONST_VTBL struct ISOSDacInterface16Vtbl *lpVtbl; + }; + + + +#ifdef COBJMACROS + + +#define ISOSDacInterface16_QueryInterface(This,riid,ppvObject) \ + ( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) ) + +#define ISOSDacInterface16_AddRef(This) \ + ( (This)->lpVtbl -> AddRef(This) ) + +#define ISOSDacInterface16_Release(This) \ + ( (This)->lpVtbl -> Release(This) ) + + +#define ISOSDacInterface16_GetGCDynamicAdaptationMode(This,pDynamicAdaptationMode) \ + ( (This)->lpVtbl -> GetGCDynamicAdaptationMode(This,pDynamicAdaptationMode) ) + +#endif /* COBJMACROS */ + + +#endif /* C style interface */ + + + + +#endif /* __ISOSDacInterface16_INTERFACE_DEFINED__ */ + + /* Additional Prototypes for ALL interfaces */ /* end of Additional Prototypes */