[NativeAOT] Add cDAC data descriptor infrastructure#126972
[NativeAOT] Add cDAC data descriptor infrastructure#126972max-charlamb wants to merge 22 commits intomainfrom
Conversation
|
Tagging subscribers to this area: @agocke, @dotnet/ilc-contrib |
There was a problem hiding this comment.
Pull request overview
Adds cDAC contract descriptor generation to the NativeAOT runtime, plus an ILC-emitted managed sub-descriptor so diagnostic tools can inspect NativeAOT runtime/managed state via the shared contract mechanism.
Changes:
- Integrates NativeAOT cDAC contract descriptor (and GC sub-descriptors) into the NativeAOT CMake build and runtime libraries.
- Introduces a managed type layout sub-descriptor emitted by ILC (
DotNetManagedContractDescriptor) and wires it into the NativeAOT descriptor as a sub-descriptor. - Exposes select private NativeAOT runtime offsets/constants to the descriptor via the
cdac_data<T>friend pattern and exports the main contract descriptor symbol for diagnostics.
Reviewed changes
Copilot reviewed 13 out of 13 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| src/coreclr/tools/aot/ILCompiler/Program.cs | Adds the managed descriptor root provider to ILC compilation roots. |
| src/coreclr/tools/aot/ILCompiler.Compiler/ILCompiler.Compiler.csproj | Includes new managed descriptor provider/node sources in the build. |
| src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/ManagedDataDescriptorProvider.cs | Registers managed types to be described and roots the descriptor + JSON blob. |
| src/coreclr/tools/aot/ILCompiler.Compiler/Compiler/DependencyAnalysis/ManagedDataDescriptorNode.cs | Emits a ContractDescriptor-shaped symbol containing JSON type layout data. |
| src/coreclr/nativeaot/Runtime/threadstore.h | Exposes ThreadStore private offsets for descriptor generation via cdac_data<>. |
| src/coreclr/nativeaot/Runtime/inc/MethodTable.h | Exposes MethodTable offsets and flag constants for descriptor consumption via cdac_data<>. |
| src/coreclr/nativeaot/Runtime/datadescriptor/datadescriptor.inc | Defines the NativeAOT data descriptor types/globals/contracts and sub-descriptors. |
| src/coreclr/nativeaot/Runtime/datadescriptor/datadescriptor.h | Provides includes and declares the managed sub-descriptor symbol address for inclusion. |
| src/coreclr/nativeaot/Runtime/datadescriptor/CMakeLists.txt | Adds descriptor generation targets for NativeAOT runtime + GC (wks/svr). |
| src/coreclr/nativeaot/Runtime/RuntimeInstance.h | Exposes RuntimeInstance private offsets via cdac_data<>. |
| src/coreclr/nativeaot/Runtime/Full/CMakeLists.txt | Links the generated descriptor libraries into WorkstationGC/ServerGC runtime libs. |
| src/coreclr/nativeaot/Runtime/CMakeLists.txt | Adds the datadescriptor subdirectory to the NativeAOT runtime build (non-WASM). |
| src/coreclr/nativeaot/BuildIntegration/Microsoft.NETCore.Native.targets | Exports DotNetRuntimeContractDescriptor symbol for diagnostics on all OSes. |
Comments suppressed due to low confidence (1)
src/coreclr/nativeaot/Runtime/datadescriptor/CMakeLists.txt:73
target_compile_definitionsentries should be raw preprocessor symbols (e.g.,SERVER_GC), not compiler flags. Passing-DSERVER_GChere will typically result in an invalid definition being forwarded to the compiler. UseSERVER_GC(orSERVER_GC=1) instead.
9462d5c to
f226bc3
Compare
This comment has been minimized.
This comment has been minimized.
Add StressLog, ThreadStressLog, StressLogChunk, StressMsgHeader, and StressMsg types to the NativeAOT data descriptor. Add StressLog globals (without module table per jkoritzinsky's feedback) and StressLog contract version 2, matching CoreCLR. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
9f5817e to
8f32bcb
Compare
- Use T_UINT32/T_UINT8/T_UINT64 macros for CDAC_GLOBAL types instead of bare uint32/uint8/uint64, matching CoreCLR convention and enabling debug-build type validation - Combine Thread + RuntimeThreadLocals: put EEAllocContext directly on Thread since Thread inherits from RuntimeThreadLocals at offset 0, removing the unnecessary RuntimeThreadLocals intermediate type Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
8f32bcb to
85107c0
Compare
Three fixes to populate the GC sub-descriptor: 1. Guard HEAP_ANALYZE fields in gc/datadescriptor with #ifdef HEAP_ANALYZE (NativeAOT disables HEAP_ANALYZE, causing link errors for the internal_root_array/heap_analyze_success fields) 2. Add -DGC_DESCRIPTOR to NativeAOT Runtime CMake so gc.cpp assigns gcDacVars->gc_descriptor during GC initialization 3. Set GC_INTERFACE version numbers before GC_Initialize (matching CoreCLR pattern) so PopulateDacVars enables the v6+ code path that assigns gc_descriptor 4. Link both WKS and SVR GC descriptors into Runtime.ServerGC since gc.cpp declares extern symbols for both when FEATURE_SVR_GC is defined Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Guard cdac_data<ThreadStressLog> with #if defined(STRESS_LOG) to prevent compile errors when NO_STRESS_LOG is defined (iOS/Android) - Exclude browser/WASM from DotNetRuntimeContractDescriptor export since the descriptor is not built for WASM targets - Fix header layout comment to match actual field names Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
WASM doesn't build the datadescriptor subdirectory, so defining GC_DESCRIPTOR unconditionally would cause undefined symbol errors for GCContractDescriptorWKS/SVR on browser/WASM builds. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Singleton nodes should not override CompareToImpl to return 0. The base class SortableDependencyNode throws NotImplementedException for duplicate instances, which is the correct pattern for singletons (matching ArrayMapNode and other singleton nodes in ILC). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This comment has been minimized.
This comment has been minimized.
- Use factory.NameMangler.GetMangledTypeName() for type name mangling instead of custom GetMangledTypeName method - Use EmitUInt for descriptor_size, pointer_data_count, and pad0 fields to match the uint32_t types in contract-descriptor.h Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
Note This review was generated by Copilot (Claude Opus 4.6) and validated against the codebase. Multi-model review: findings synthesized from Claude Opus 4.6 (primary), Claude Sonnet 4.5, and GPT-5.3-Codex sub-agents. 🤖 Copilot Code Review — PR #126972Holistic AssessmentMotivation: This PR extends the cDAC data descriptor infrastructure to NativeAOT, enabling diagnostic tools (SOS/cDAC) to inspect NativeAOT runtime state. This is clearly needed — NativeAOT currently lacks parity with CoreCLR's diagnostic data contract support. The changes include StressLog descriptors, GC sub-descriptors, managed type layout emission via Approach: The approach is sound — it reuses CoreCLR's established datadescriptor infrastructure and adapts it to NativeAOT's different memory layout (e.g., Thread inherits RuntimeThreadLocals instead of pointing to it). The attribute consolidation ( Summary: Detailed Findings✅ JSON Descriptor Format — CorrectThe new ✅ GC Version Pre-Initialization — CorrectSetting ✅ Server GC Linking Both Descriptors — Correct
✅ CompareToImpl Removal — SafeThe base ✅ WASM/Browser Exclusion — Correct and NecessaryAdding ✅ HEAP_ANALYZE Guards — CorrectAdding ✅ StressLog Hardcoded Enabled — Matches CoreCLR
✅ ThreadStore Static Pointer — Clean RefactorMoving from
|
| // Licensed to the .NET Foundation under one or more agreements. | ||
| // The .NET Foundation licenses this file to you under the MIT license. | ||
|
|
||
| // This is a copy of src/coreclr/gc/env/cdacdata.h for use by NativeAOT headers. |
There was a problem hiding this comment.
We can do #include "../../inc/cdacdata.h" instead
| pThreadStore.SuppressRelease(); | ||
| pRuntimeInstance.SuppressRelease(); | ||
|
|
||
| pRuntimeInstance->m_pThreadStore = pThreadStore; |
There was a problem hiding this comment.
Can we delete pRuntimeInstance->m_pThreadStore - it is redundant now
| /// <summary> | ||
| /// When applied to a type, indicates that ILC should include its field layout in the | ||
| /// managed cDAC data descriptor so diagnostic tools can inspect instances without | ||
| /// runtime metadata. When applied to a field of such a type, indicates ILC should |
There was a problem hiding this comment.
| /// runtime metadata. When applied to a field of such a type, indicates ILC should | |
| /// runtime metadata or symbols. When applied to a field of such a type, indicates ILC should |
|
|
||
| private static void WriteType(Utf8JsonWriter writer, EcmaType type, NameMangler nameMangler) | ||
| { | ||
| writer.WriteStartObject(nameMangler.GetMangledTypeName(type).ToString()); |
There was a problem hiding this comment.
I know this was added in response to the other review comment (before commit 0d09c17), but this name mangling also has properties you probably don't want, like if there is a conflict after we flatten and sanitize the names, we're going add numbers to these:
runtime/src/coreclr/tools/Common/Compiler/NativeAotNameMangler.cs
Lines 360 to 361 in 3ac6e13
Making the S_P_CoreLib prefix part of the contract is also not great. The previous name mangling was better because cDAC infra can be fully in control of what it supports and how it does it.
Note
This PR was created with assistance from GitHub Copilot.
Summary
Adds the cDAC data descriptor infrastructure for NativeAOT, enabling diagnostic tools (cDAC reader, SOS) to inspect NativeAOT runtime state through the same contract-based mechanism used by CoreCLR.
Changes
Native data descriptor (
datadescriptor.inc)cdac_data<>friend patternSTRESS_LOG)ILC managed type descriptor (
ManagedDataDescriptorNode)ContractDescriptor(DotNetManagedContractDescriptor) with JSON-encoded type layouts usingUtf8JsonWriter[DataContract]attribute on types inMetadataManager.GetTypesWithEETypes()System.Threading.Thread->System_Threading_ThreadCDAC_GLOBAL_SUB_DESCRIPTORSystem.Threading.Threadfields (ManagedThreadId,Name)GC sub-descriptor
GC_INTERFACE_*_VERSIONbeforeGC_InitializeGC_DESCRIPTORcompile definition (guarded on non-WASM)Runtime.ServerGC(ServerGC compiles both paths)#ifdef HEAP_ANALYZEguards in shared GC datadescriptor files (NativeAOT disablesHEAP_ANALYZE)Attribute-based type discovery
[DataContract]attribute inSystem.Diagnosticsnamespace (internal, targets Class/Struct/Field)System.Threading.Threadfields inThread.NativeAot.csGetTypesWithEETypes()ensuring only types with MethodTables are includedBuild integration
clrdatadescriptors.cmakeinfrastructurenativeaot_runtime_includesinterface library captures all Runtime include paths for cross-target compilationcdac-build-toolenabled for NativeAOT viaClrNativeAotSubsetinruntime.proj--export-dynamic-symbolinMicrosoft.NETCore.Native.targets(WASM excluded)cdacdata.htemplate inRuntime/inc/(matching GC pattern for self-contained builds)Key design decisions
n1for NativeAOT-specific contracts,c1/c2for contracts shared with CoreCLR (same version)SPTR_DECL/SPTR_IMPLfors_pThreadStorestatic member, matching CoreCLR patternManagedDataDescriptorNodedoes not overrideCompareToImpl— follows the ILC singleton pattern (base class throws on duplicates)slist.hshared between CoreCLR VM and NativeAOT RuntimeValidation
build.cmd clr.aot+libs -rc release— 0 errors, 0 warningsRuntime.WorkstationGC.libvia dumpbin