Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
585727c
[NativeAOT] Add cDAC data descriptor infrastructure
max-charlamb Apr 16, 2026
1af663b
[NativeAOT] Add managed type sub-descriptor for cDAC
max-charlamb Apr 16, 2026
5c322ca
Address PR review feedback
max-charlamb Apr 16, 2026
56493a5
Enable cdac-build-tool for NativeAOT builds
max-charlamb Apr 17, 2026
1101d7d
Address round 2 review feedback
max-charlamb Apr 17, 2026
0405d35
Move ThreadStore pointer to static member matching CoreCLR
max-charlamb Apr 17, 2026
1706da7
Move datadescriptor after eventpipe in CMake ordering
max-charlamb Apr 17, 2026
3368b21
Use nativeaot_runtime_includes for datadescriptor build
max-charlamb Apr 17, 2026
b6ae1b0
Fix cdacdata.h redirect path
max-charlamb Apr 19, 2026
67615c4
Copy cdacdata.h template into NativeAOT Runtime/inc
max-charlamb Apr 19, 2026
5a93416
Use Utf8JsonWriter for managed descriptor JSON
max-charlamb Apr 19, 2026
465bd7b
Address PR review feedback: attribute naming, cdacdata.h, comment cle…
max-charlamb Apr 20, 2026
3e60d67
Remove unnecessary SUPPORT_JIT guard from ManagedDataDescriptorNode
max-charlamb Apr 20, 2026
b03ad0c
Merge CdacType/CdacField into single DataContractAttribute
max-charlamb Apr 21, 2026
4dcc843
Update doc comments to reference DataContractAttribute
max-charlamb Apr 22, 2026
417592b
Add stresslog data descriptor entries for NativeAOT
max-charlamb Apr 22, 2026
85107c0
Address code review findings
max-charlamb Apr 22, 2026
4897be6
Enable GC sub-descriptor for NativeAOT
max-charlamb Apr 22, 2026
a4db3d7
Fix stressLog guard, WASM export, and comment
max-charlamb Apr 24, 2026
6697021
Guard GC_DESCRIPTOR define for non-WASM builds
max-charlamb Apr 24, 2026
459c33b
Remove CompareToImpl override from ManagedDataDescriptorNode
max-charlamb Apr 24, 2026
0d09c17
Use ILC NameMangler for type names and EmitUInt for uint32_t fields
max-charlamb Apr 27, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/coreclr/gc/datadescriptor/datadescriptor.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,9 +67,11 @@ struct cdac_data<GC_NAMESPACE::gc_heap>
#endif // !USE_REGIONS

/* For use in GCHeapAnalyzeData APIs */
#ifdef HEAP_ANALYZE
GC_HEAP_FIELD(InternalRootArray, internal_root_array)
GC_HEAP_FIELD(InternalRootArrayIndex, internal_root_array_index)
GC_HEAP_FIELD(HeapAnalyzeSuccess, heap_analyze_success)
#endif // HEAP_ANALYZE

/* For use in GCInterestingInfo APIs */
GC_HEAP_FIELD(InterestingData, interesting_data_per_heap)
Expand Down
4 changes: 4 additions & 0 deletions src/coreclr/gc/datadescriptor/datadescriptor.inc
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,11 @@ CDAC_TYPE_FIELD(GCHeap, T_POINTER, SavedSweepEphemeralSeg, cdac_data<GC_NAMESPAC
CDAC_TYPE_FIELD(GCHeap, T_POINTER, SavedSweepEphemeralStart, cdac_data<GC_NAMESPACE::gc_heap>::SavedSweepEphemeralStart)
#endif // !USE_REGIONS
CDAC_TYPE_FIELD(GCHeap, TYPE(OomHistory), OomData, cdac_data<GC_NAMESPACE::gc_heap>::OomData)
#ifdef HEAP_ANALYZE
CDAC_TYPE_FIELD(GCHeap, T_POINTER, InternalRootArray, cdac_data<GC_NAMESPACE::gc_heap>::InternalRootArray)
CDAC_TYPE_FIELD(GCHeap, T_NUINT, InternalRootArrayIndex, cdac_data<GC_NAMESPACE::gc_heap>::InternalRootArrayIndex)
CDAC_TYPE_FIELD(GCHeap, T_INT32, HeapAnalyzeSuccess, cdac_data<GC_NAMESPACE::gc_heap>::HeapAnalyzeSuccess)
#endif // HEAP_ANALYZE
CDAC_TYPE_FIELD(GCHeap, T_POINTER, InterestingData, cdac_data<GC_NAMESPACE::gc_heap>::InterestingData)
CDAC_TYPE_FIELD(GCHeap, T_POINTER, CompactReasons, cdac_data<GC_NAMESPACE::gc_heap>::CompactReasons)
CDAC_TYPE_FIELD(GCHeap, T_POINTER, ExpandMechanisms, cdac_data<GC_NAMESPACE::gc_heap>::ExpandMechanisms)
Expand Down Expand Up @@ -166,9 +168,11 @@ CDAC_GLOBAL_POINTER(GCHeapSavedSweepEphemeralSeg, cdac_data<GC_NAMESPACE::gc_hea
CDAC_GLOBAL_POINTER(GCHeapSavedSweepEphemeralStart, cdac_data<GC_NAMESPACE::gc_heap>::SavedSweepEphemeralStart)
#endif // !USE_REGIONS
CDAC_GLOBAL_POINTER(GCHeapOomData, cdac_data<GC_NAMESPACE::gc_heap>::OomData)
#ifdef HEAP_ANALYZE
CDAC_GLOBAL_POINTER(GCHeapInternalRootArray, cdac_data<GC_NAMESPACE::gc_heap>::InternalRootArray)
CDAC_GLOBAL_POINTER(GCHeapInternalRootArrayIndex, cdac_data<GC_NAMESPACE::gc_heap>::InternalRootArrayIndex)
CDAC_GLOBAL_POINTER(GCHeapHeapAnalyzeSuccess, cdac_data<GC_NAMESPACE::gc_heap>::HeapAnalyzeSuccess)
#endif // HEAP_ANALYZE
CDAC_GLOBAL_POINTER(GCHeapInterestingData, cdac_data<GC_NAMESPACE::gc_heap>::InterestingData)
CDAC_GLOBAL_POINTER(GCHeapCompactReasons, cdac_data<GC_NAMESPACE::gc_heap>::CompactReasons)
CDAC_GLOBAL_POINTER(GCHeapExpandMechanisms, cdac_data<GC_NAMESPACE::gc_heap>::ExpandMechanisms)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,8 @@ The .NET Foundation licenses this file to you under the MIT license.
<IlcArg Condition="'$(ExportsFile)' != ''" Include="--exportsfile:$(ExportsFile)" />
<IlcArg Condition="'$(_targetOS)' == 'win' and '$(DebuggerSupport)' != 'false'" Include="--export-dynamic-symbol:DotNetRuntimeDebugHeader,DATA" />
<IlcArg Condition="'$(_targetOS)' != 'win' and '$(DebuggerSupport)' != 'false'" Include="--export-dynamic-symbol:DotNetRuntimeDebugHeader" />
<IlcArg Condition="'$(_targetOS)' == 'win' and '$(DebuggerSupport)' != 'false'" Include="--export-dynamic-symbol:DotNetRuntimeContractDescriptor,DATA" />
<IlcArg Condition="'$(_targetOS)' != 'win' and '$(_targetOS)' != 'browser' and '$(DebuggerSupport)' != 'false'" Include="--export-dynamic-symbol:DotNetRuntimeContractDescriptor" />
<IlcArg Condition="'$(_targetOS)' == 'freebsd' and '$(IsNativeExecutable)' == 'true'" Include="--export-dynamic-symbol:__progname;--export-dynamic-symbol:environ" />
<IlcArg Condition="'$(IlcExportUnmanagedEntrypoints)' == 'true'" Include="--export-unmanaged-entrypoints" />
<IlcArg Include="@(AutoInitializedAssemblies->'--initassembly:%(Identity)')" />
Expand Down
13 changes: 13 additions & 0 deletions src/coreclr/nativeaot/Runtime/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,9 @@ if(CLR_CMAKE_TARGET_ARCH_I386 OR CLR_CMAKE_TARGET_ARCH_ARM)
add_definitions(-DINTERFACE_DISPATCH_CACHE_HAS_CELL_BACKPOINTER)
endif()
add_definitions(-D_LIB)
if(NOT CLR_CMAKE_TARGET_ARCH_WASM)
add_definitions(-DGC_DESCRIPTOR)
endif()

# there is a problem with undefined symbols when this is set
# add_definitions(-DSTRESS_HEAP)
Expand Down Expand Up @@ -346,3 +349,13 @@ endif()
if(FEATURE_PERFTRACING)
add_subdirectory(eventpipe)
endif()

if(NOT CLR_CMAKE_TARGET_ARCH_WASM)
# Create an interface library that captures the Runtime's include directories
# for use by the datadescriptor intermediary compilation.
add_library(nativeaot_runtime_includes INTERFACE)
get_property(_runtime_includes DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY INCLUDE_DIRECTORIES)
target_include_directories(nativeaot_runtime_includes INTERFACE ${_runtime_includes})

add_subdirectory(datadescriptor)
endif()
4 changes: 2 additions & 2 deletions src/coreclr/nativeaot/Runtime/Full/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,11 @@ endif (CLR_CMAKE_TARGET_WIN32)

add_library(Runtime.WorkstationGC STATIC ${COMMON_RUNTIME_SOURCES} ${FULL_RUNTIME_SOURCES} ${RUNTIME_ARCH_ASM_OBJECTS})
add_dependencies(Runtime.WorkstationGC aot_eventing_headers)
target_link_libraries(Runtime.WorkstationGC PRIVATE aotminipal)
target_link_libraries(Runtime.WorkstationGC PRIVATE aotminipal nativeaot_cdac_contract_descriptor nativeaot_gc_wks_descriptor)

add_library(Runtime.ServerGC STATIC ${COMMON_RUNTIME_SOURCES} ${FULL_RUNTIME_SOURCES} ${SERVER_GC_SOURCES} ${RUNTIME_ARCH_ASM_OBJECTS})
add_dependencies(Runtime.ServerGC aot_eventing_headers)
target_link_libraries(Runtime.ServerGC PRIVATE aotminipal)
target_link_libraries(Runtime.ServerGC PRIVATE aotminipal nativeaot_cdac_contract_descriptor nativeaot_gc_wks_descriptor nativeaot_gc_svr_descriptor)

add_library(standalonegc-disabled STATIC ${STANDALONEGC_DISABLED_SOURCES})
add_dependencies(standalonegc-disabled aot_eventing_headers)
Expand Down
1 change: 1 addition & 0 deletions src/coreclr/nativeaot/Runtime/RuntimeInstance.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -319,6 +319,7 @@ bool RuntimeInstance::Initialize(HANDLE hPalInstance)

ASSERT_MSG(g_pTheRuntimeInstance == NULL, "multi-instances are not supported");
g_pTheRuntimeInstance = pRuntimeInstance;
ThreadStore::s_pThreadStore = pThreadStore;

return true;
}
Expand Down
49 changes: 49 additions & 0 deletions src/coreclr/nativeaot/Runtime/datadescriptor/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
set(CMAKE_INCLUDE_CURRENT_DIR OFF)

# cDAC contract descriptor for NativeAOT
#
# This uses the shared datadescriptor infrastructure from
# src/coreclr/debug/datadescriptor-shared/ to generate a
# DotNetRuntimeContractDescriptor symbol in the NativeAOT runtime.
#
# The nativeaot_runtime_includes interface library (created in the parent
# Runtime/CMakeLists.txt) provides the same include directories used by
# the regular NativeAOT Runtime build.

include(${CLR_DIR}/clrdatadescriptors.cmake)

add_library(nativeaot_descriptor_interface INTERFACE)
target_include_directories(nativeaot_descriptor_interface INTERFACE
${CMAKE_CURRENT_SOURCE_DIR})
target_link_libraries(nativeaot_descriptor_interface INTERFACE nativeaot_runtime_includes)
add_dependencies(nativeaot_descriptor_interface aot_eventing_headers)
generate_data_descriptors(
LIBRARY_NAME nativeaot_cdac_contract_descriptor
CONTRACT_NAME "DotNetRuntimeContractDescriptor"
INTERFACE_TARGET nativeaot_descriptor_interface
EXPORT_VISIBLE)

# GC contract descriptors (workstation + server).
# The GC has its own data descriptor exposed as a sub-descriptor via gc_descriptor in GcDacVars.
set(GC_DESCRIPTOR_DIR "${CLR_DIR}/gc/datadescriptor")

add_library(nativeaot_gc_wks_descriptor_interface INTERFACE)
target_include_directories(nativeaot_gc_wks_descriptor_interface INTERFACE
${GC_DESCRIPTOR_DIR})
target_link_libraries(nativeaot_gc_wks_descriptor_interface INTERFACE nativeaot_runtime_includes)
add_dependencies(nativeaot_gc_wks_descriptor_interface aot_eventing_headers)
generate_data_descriptors(
Comment thread
max-charlamb marked this conversation as resolved.
LIBRARY_NAME nativeaot_gc_wks_descriptor
CONTRACT_NAME "GCContractDescriptorWKS"
INTERFACE_TARGET nativeaot_gc_wks_descriptor_interface)

add_library(nativeaot_gc_svr_descriptor_interface INTERFACE)
target_include_directories(nativeaot_gc_svr_descriptor_interface INTERFACE
${GC_DESCRIPTOR_DIR})
target_link_libraries(nativeaot_gc_svr_descriptor_interface INTERFACE nativeaot_runtime_includes)
add_dependencies(nativeaot_gc_svr_descriptor_interface aot_eventing_headers)
target_compile_definitions(nativeaot_gc_svr_descriptor_interface INTERFACE -DSERVER_GC)
generate_data_descriptors(
LIBRARY_NAME nativeaot_gc_svr_descriptor
CONTRACT_NAME "GCContractDescriptorSVR"
INTERFACE_TARGET nativeaot_gc_svr_descriptor_interface)
37 changes: 37 additions & 0 deletions src/coreclr/nativeaot/Runtime/datadescriptor/datadescriptor.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

// This header provides the includes needed for datadescriptor.inc to use
// offsetof() on NativeAOT runtime data structures.
//
// Note: Some NativeAOT types have private members that offsetof() cannot access
// from this compilation unit. For those types, we use known offset constants
// validated at build time by AsmOffsetsVerify.cpp and DebugHeader.cpp static_asserts.

#include "common.h"
#include "gcenv.h"
#include "gcheaputilities.h"
#include "gcinterface.dac.h"
#include "rhassert.h"
#include "TargetPtrs.h"
#include "PalLimitedContext.h"
#include "Pal.h"
#include "holder.h"
#include "RuntimeInstance.h"
#include "regdisplay.h"
#include "StackFrameIterator.h"
#include "thread.h"
#include "threadstore.h"

#include <stdint.h>
#include <stddef.h>

GPTR_DECL(MethodTable, g_pFreeObjectEEType);
GPTR_DECL(StressLog, g_pStressLog);

// ILC emits a ContractDescriptor named "DotNetManagedContractDescriptor" with
// managed type layouts. We take its address so datadescriptor.inc can reference
// it as a sub-descriptor via CDAC_GLOBAL_SUB_DESCRIPTOR.
struct ContractDescriptor;
extern "C" ContractDescriptor DotNetManagedContractDescriptor;
static const void* g_pManagedContractDescriptor = &DotNetManagedContractDescriptor;
188 changes: 188 additions & 0 deletions src/coreclr/nativeaot/Runtime/datadescriptor/datadescriptor.inc
Original file line number Diff line number Diff line change
@@ -0,0 +1,188 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
//
// No include guards. This file is included multiple times.
//
// NativeAOT data descriptor declarations for the cDAC contract system.
// This file defines the types, fields, and globals that diagnostic tools
// need to inspect NativeAOT runtime state.
//
// When modifying this file (adding/removing types, fields, or globals), you must also:
// 1. Update the corresponding contract doc in docs/design/datacontracts/<contract>.md
// 2. Update the managed data class in src/native/managed/cdac/.../Data/<Type>.cs
// 3. Update the contract implementation in src/native/managed/cdac/.../Contracts/<Contract>.cs
// 4. Update the mock descriptors and tests in src/native/managed/cdac/tests/.

CDAC_BASELINE("empty")
CDAC_TYPES_BEGIN()

// ========================
// Thread and ThreadStore
// ========================

CDAC_TYPE_BEGIN(Thread)
CDAC_TYPE_INDETERMINATE(Thread)
CDAC_TYPE_FIELD(Thread, T_UINT64, OSId, offsetof(RuntimeThreadLocals, m_threadId))
CDAC_TYPE_FIELD(Thread, T_UINT32, State, offsetof(RuntimeThreadLocals, m_ThreadStateFlags))
CDAC_TYPE_FIELD(Thread, T_POINTER, LinkNext, offsetof(RuntimeThreadLocals, m_pNext))
CDAC_TYPE_FIELD(Thread, T_POINTER, ExceptionTracker, offsetof(RuntimeThreadLocals, m_pExInfoStackHead))
CDAC_TYPE_FIELD(Thread, T_POINTER, CachedStackBase, offsetof(RuntimeThreadLocals, m_pStackHigh))
CDAC_TYPE_FIELD(Thread, T_POINTER, CachedStackLimit, offsetof(RuntimeThreadLocals, m_pStackLow))
// Thread inherits from RuntimeThreadLocals at offset 0, so EEAllocContext is directly on Thread
CDAC_TYPE_FIELD(Thread, TYPE(EEAllocContext), AllocContext, offsetof(RuntimeThreadLocals, m_eeAllocContext))
CDAC_TYPE_FIELD(Thread, T_POINTER, TransitionFrame, offsetof(RuntimeThreadLocals, m_pTransitionFrame))
CDAC_TYPE_END(Thread)

CDAC_TYPE_BEGIN(ThreadStore)
CDAC_TYPE_INDETERMINATE(ThreadStore)
CDAC_TYPE_FIELD(ThreadStore, T_POINTER, FirstThreadLink, cdac_data<ThreadStore>::FirstThreadLink)
Comment thread
max-charlamb marked this conversation as resolved.
CDAC_TYPE_END(ThreadStore)

// ========================
// Allocation Context
// ========================

CDAC_TYPE_BEGIN(EEAllocContext)
CDAC_TYPE_INDETERMINATE(EEAllocContext)
CDAC_TYPE_FIELD(EEAllocContext, TYPE(GCAllocContext), GCAllocationContext, offsetof(ee_alloc_context, m_rgbAllocContextBuffer))
CDAC_TYPE_END(EEAllocContext)

CDAC_TYPE_BEGIN(GCAllocContext)
CDAC_TYPE_INDETERMINATE(GCAllocContext)
CDAC_TYPE_FIELD(GCAllocContext, T_POINTER, Pointer, offsetof(gc_alloc_context, alloc_ptr))
CDAC_TYPE_FIELD(GCAllocContext, T_POINTER, Limit, offsetof(gc_alloc_context, alloc_limit))
CDAC_TYPE_FIELD(GCAllocContext, T_INT64, AllocBytes, offsetof(gc_alloc_context, alloc_bytes))
CDAC_TYPE_FIELD(GCAllocContext, T_INT64, AllocBytesLoh, offsetof(gc_alloc_context, alloc_bytes_uoh))
CDAC_TYPE_END(GCAllocContext)

// ========================
// MethodTable (EEType)
// ========================

CDAC_TYPE_BEGIN(MethodTable)
CDAC_TYPE_INDETERMINATE(MethodTable)
CDAC_TYPE_FIELD(MethodTable, T_UINT32, Flags, cdac_data<MethodTable>::Flags)
CDAC_TYPE_FIELD(MethodTable, T_UINT32, BaseSize, cdac_data<MethodTable>::BaseSize)
CDAC_TYPE_FIELD(MethodTable, T_POINTER, RelatedType, cdac_data<MethodTable>::RelatedType)
CDAC_TYPE_FIELD(MethodTable, T_UINT16, NumVtableSlots, cdac_data<MethodTable>::NumVtableSlots)
CDAC_TYPE_FIELD(MethodTable, T_UINT16, NumInterfaces, cdac_data<MethodTable>::NumInterfaces)
CDAC_TYPE_FIELD(MethodTable, T_UINT32, HashCode, cdac_data<MethodTable>::HashCode)
CDAC_TYPE_FIELD(MethodTable, T_POINTER, VTable, cdac_data<MethodTable>::VTable)
CDAC_TYPE_END(MethodTable)

// ========================
// Exception Info
// ========================

CDAC_TYPE_BEGIN(ExInfo)
CDAC_TYPE_INDETERMINATE(ExInfo)
CDAC_TYPE_FIELD(ExInfo, T_POINTER, PreviousNestedInfo, offsetof(ExInfo, m_pPrevExInfo))
CDAC_TYPE_FIELD(ExInfo, T_POINTER, ThrownObject, offsetof(ExInfo, m_exception))
CDAC_TYPE_END(ExInfo)

// ========================
// StressLog
// ========================

CDAC_TYPE_BEGIN(StressLog)
CDAC_TYPE_SIZE(sizeof(StressLog))
CDAC_TYPE_FIELD(StressLog, T_UINT32, LoggedFacilities, offsetof(StressLog, facilitiesToLog))
CDAC_TYPE_FIELD(StressLog, T_UINT32, Level, offsetof(StressLog, levelToLog))
CDAC_TYPE_FIELD(StressLog, T_UINT32, MaxSizePerThread, offsetof(StressLog, MaxSizePerThread))
CDAC_TYPE_FIELD(StressLog, T_UINT32, MaxSizeTotal, offsetof(StressLog, MaxSizeTotal))
CDAC_TYPE_FIELD(StressLog, T_INT32, TotalChunks, offsetof(StressLog, totalChunk))
CDAC_TYPE_FIELD(StressLog, T_POINTER, Logs, offsetof(StressLog, logs))
CDAC_TYPE_FIELD(StressLog, T_UINT64, TickFrequency, offsetof(StressLog, tickFrequency))
CDAC_TYPE_FIELD(StressLog, T_UINT64, StartTimestamp, offsetof(StressLog, startTimeStamp))
CDAC_TYPE_END(StressLog)

CDAC_TYPE_BEGIN(ThreadStressLog)
CDAC_TYPE_INDETERMINATE(ThreadStressLog)
CDAC_TYPE_FIELD(ThreadStressLog, T_POINTER, Next, cdac_data<ThreadStressLog>::Next)
CDAC_TYPE_FIELD(ThreadStressLog, T_UINT64, ThreadId, cdac_data<ThreadStressLog>::ThreadId)
CDAC_TYPE_FIELD(ThreadStressLog, T_UINT8, WriteHasWrapped, cdac_data<ThreadStressLog>::WriteHasWrapped)
CDAC_TYPE_FIELD(ThreadStressLog, T_POINTER, CurrentPtr, cdac_data<ThreadStressLog>::CurrentPtr)
CDAC_TYPE_FIELD(ThreadStressLog, T_POINTER, ChunkListHead, cdac_data<ThreadStressLog>::ChunkListHead)
CDAC_TYPE_FIELD(ThreadStressLog, T_POINTER, ChunkListTail, cdac_data<ThreadStressLog>::ChunkListTail)
CDAC_TYPE_FIELD(ThreadStressLog, T_POINTER, CurrentWriteChunk, cdac_data<ThreadStressLog>::CurrentWriteChunk)
CDAC_TYPE_END(ThreadStressLog)

CDAC_TYPE_BEGIN(StressLogChunk)
CDAC_TYPE_SIZE(sizeof(StressLogChunk))
CDAC_TYPE_FIELD(StressLogChunk, T_POINTER, Prev, offsetof(StressLogChunk, prev))
CDAC_TYPE_FIELD(StressLogChunk, T_POINTER, Next, offsetof(StressLogChunk, next))
CDAC_TYPE_FIELD(StressLogChunk, T_ARRAY(T_UINT8), Buf, offsetof(StressLogChunk, buf))
CDAC_TYPE_FIELD(StressLogChunk, T_UINT32, Sig1, offsetof(StressLogChunk, dwSig1))
CDAC_TYPE_FIELD(StressLogChunk, T_UINT32, Sig2, offsetof(StressLogChunk, dwSig2))
CDAC_TYPE_END(StressLogChunk)

CDAC_TYPE_BEGIN(StressMsgHeader)
CDAC_TYPE_SIZE(sizeof(StressMsg))
CDAC_TYPE_END(StressMsgHeader)

CDAC_TYPE_BEGIN(StressMsg)
CDAC_TYPE_INDETERMINATE(StressMsg)
CDAC_TYPE_FIELD(StressMsg, TYPE(StressMsgHeader), Header, 0)
CDAC_TYPE_FIELD(StressMsg, T_POINTER, Args, offsetof(StressMsg, args))
CDAC_TYPE_END(StressMsg)

CDAC_TYPES_END()

// ========================
// Globals
// ========================

CDAC_GLOBALS_BEGIN()

CDAC_GLOBAL_POINTER(ThreadStore, &ThreadStore::s_pThreadStore)

CDAC_GLOBAL_POINTER(FreeObjectMethodTable, &g_pFreeObjectEEType)

CDAC_GLOBAL_POINTER(GCLowestAddress, &g_lowest_address)
CDAC_GLOBAL_POINTER(GCHighestAddress, &g_highest_address)

// NativeAOT MethodTable flag constants (accessed via cdac_data friend)
CDAC_GLOBAL(MethodTableEETypeKindMask, T_UINT32, cdac_data<MethodTable>::EETypeKindMask)
CDAC_GLOBAL(MethodTableHasComponentSizeFlag, T_UINT32, cdac_data<MethodTable>::HasComponentSizeFlag)
CDAC_GLOBAL(MethodTableHasFinalizerFlag, T_UINT32, cdac_data<MethodTable>::HasFinalizerFlag)
CDAC_GLOBAL(MethodTableHasPointersFlag, T_UINT32, cdac_data<MethodTable>::HasPointersFlag)
CDAC_GLOBAL(MethodTableIsGenericFlag, T_UINT32, cdac_data<MethodTable>::IsGenericFlag)
CDAC_GLOBAL(MethodTableElementTypeMask, T_UINT32, cdac_data<MethodTable>::ElementTypeMask)
CDAC_GLOBAL(MethodTableElementTypeShift, T_UINT32, cdac_data<MethodTable>::ElementTypeShift)

// Thread state flag constants
CDAC_GLOBAL(ThreadStateFlagAttached, T_UINT32, 0x00000001)
CDAC_GLOBAL(ThreadStateFlagDetached, T_UINT32, 0x00000002)

// Object contract globals
#ifdef TARGET_64BIT
CDAC_GLOBAL(ObjectToMethodTableUnmask, T_UINT8, 7)
#else
CDAC_GLOBAL(ObjectToMethodTableUnmask, T_UINT8, 3)
#endif

// StressLog globals (no module table in NativeAOT)
CDAC_GLOBAL(StressLogEnabled, T_UINT8, 1)
CDAC_GLOBAL_POINTER(StressLog, &g_pStressLog)
CDAC_GLOBAL(StressLogHasModuleTable, T_UINT8, 0)
CDAC_GLOBAL(StressLogChunkSize, T_UINT32, STRESSLOG_CHUNK_SIZE)
CDAC_GLOBAL(StressLogValidChunkSig, T_UINT32, 0xCFCFCFCF)
CDAC_GLOBAL(StressLogMaxMessageSize, T_UINT64, (uint64_t)StressMsg::maxMsgSize)

// Contracts: declare which contracts this runtime supports
Comment thread
max-charlamb marked this conversation as resolved.
CDAC_GLOBAL_CONTRACT(Thread, n1)
CDAC_GLOBAL_CONTRACT(Exception, c1)
CDAC_GLOBAL_CONTRACT(RuntimeTypeSystem, n1)
CDAC_GLOBAL_CONTRACT(StressLog, c2)
Comment thread
max-charlamb marked this conversation as resolved.

// Managed type sub-descriptor: ILC emits a ContractDescriptor with managed type layouts
// that the cDAC reader merges as a sub-descriptor. This provides field offsets for managed
// types (e.g., ConditionalWeakTable internals, IdDispenser) that are not exposed through
// native C++ data descriptors.
CDAC_GLOBAL_SUB_DESCRIPTOR(ManagedTypes, &g_pManagedContractDescriptor)

Comment thread
max-charlamb marked this conversation as resolved.
// GC sub-descriptor: the GC populates gc_descriptor during GC_Initialize.
// It is important for subdescriptor pointers to be the last pointers.
CDAC_GLOBAL_SUB_DESCRIPTOR(GC, &(g_gc_dac_vars.gc_descriptor))

CDAC_GLOBALS_END()
3 changes: 3 additions & 0 deletions src/coreclr/nativeaot/Runtime/gcheaputilities.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include "gchandleutilities.h"

#include "gceventstatus.h"
#include "gcinterface.h"

// This is the global GC heap, maintained by the VM.
GPTR_IMPL(IGCHeap, g_pGCHeap);
Expand Down Expand Up @@ -71,6 +72,8 @@ HRESULT GCHeapUtilities::InitializeDefaultGC()

IGCHeap* heap;
IGCHandleManager* manager;
g_gc_dac_vars.major_version_number = GC_INTERFACE_MAJOR_VERSION;
g_gc_dac_vars.minor_version_number = GC_INTERFACE_MINOR_VERSION;
HRESULT initResult = GC_Initialize(nullptr, &heap, &manager, &g_gc_dac_vars);
if (initResult == S_OK)
{
Expand Down
Loading
Loading