[cDAC] Add EnC metadata and caching#129935
Open
rcj1 wants to merge 7 commits into
Open
Conversation
Contributor
There was a problem hiding this comment.
Pull request overview
This PR expands the cDAC EcmaMetadata contract to support Edit-and-Continue (EnC) and read-write (RW) metadata scenarios by adding new VM data descriptors, walking RW metadata structures (MDInternalRW → CLiteWeightStgdbRW → CMiniMdRW), and caching metadata readers based on generation/edit counters.
Changes:
- Add new CoreCLR data descriptors and managed contract data models for RW metadata structures and EnC module state.
- Implement RW metadata reconstruction/serialization into a contiguous ECMA-335 metadata image, including heap/table coalescing.
- Adjust caching/flush behavior and update design documentation to reflect the new metadata sources and invalidation signals.
Show a summary per file
| File | Description |
|---|---|
| src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/EcmaMetadataUtils.cs | Adds helper to read metadata version string from a metadata root. |
| src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/DataType.cs | Adds new public DataType enum entries for RW metadata and EnC module types. |
| src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/StgPoolSeg.cs | New contract data model for StgPoolSeg. |
| src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/StgPool.cs | New contract data model for StgPool. |
| src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/PEAssembly.cs | Extends PEAssembly contract data to expose RW importer state/pointer. |
| src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/Module.cs | Adds MetadataGeneration for dynamic module saved-metadata invalidation. |
| src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/MDInternalRW.cs | New contract data model for MDInternalRW (RW metadata entrypoint). |
| src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/EditAndContinueModule.cs | New contract data model for EnC edit counter (ApplyChangesCount). |
| src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/CMiniMdSchema.cs | New contract data model for CMiniMd schema fields (heaps/sorted/row counts). |
| src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/CMiniMdRW.cs | New contract data model for CMiniMdRW fields plus computed table segment addresses. |
| src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/CLiteWeightStgdbRW.cs | New contract data model for RW stgdb pointers and metadata image address. |
| src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/EcmaMetadata_1.cs | Implements RW metadata reading/serialization and generation-based caching. |
| src/coreclr/vm/peassembly.h | Exposes MDImport RW flag and MDImport pointer offsets to cDAC. |
| src/coreclr/vm/encee.h | Adds cDAC data exposure for EditAndContinueModule::m_applyChangesCount. |
| src/coreclr/vm/datadescriptor/datadescriptor.inc | Registers new cDAC types/fields for RW metadata and EnC module. |
| src/coreclr/vm/datadescriptor/datadescriptor.h | Adds metadata header includes needed for RW metadata descriptors. |
| src/coreclr/vm/datadescriptor/CMakeLists.txt | Adds compile definition enabling internal metadata API exposure for descriptor build. |
| src/coreclr/vm/ceeload.h | Adds Module::m_dwMetadataGeneration and exposes it via cDAC. |
| src/coreclr/vm/ceeload.cpp | Initializes/increments dynamic metadata generation counter. |
| src/coreclr/md/inc/stgpool.h | Adds cdac_data mappings for StgPool/StgPoolSeg fields. |
| src/coreclr/md/inc/metamodelrw.h | Adds m_fAll4ByteColumns and exposes RW heap/table offsets for cDAC. |
| src/coreclr/md/inc/metamodel.h | Adds cdac_data mapping for CMiniMdBase schema/tablecount fields. |
| src/coreclr/md/inc/liteweightstgdb.h | Adds cdac_data mapping for RW stgdb miniMd and metadata address. |
| src/coreclr/md/enc/metamodelrw.cpp | Initializes/sets m_fAll4ByteColumns under growth/expansion paths. |
| src/coreclr/md/enc/liteweightstgdbrw.cpp | Marks minimal-delta load as “all 4-byte columns” for RW model. |
| docs/design/datacontracts/EcmaMetadata.md | Updates the contract documentation and descriptor listing for RW metadata support. |
Copilot's findings
Comments suppressed due to low confidence (1)
src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/EcmaMetadata_1.cs:381
GetReadWriteSavedMetadataAddressusesProcessedData.GetOrAddforModuleandDynamicMetadata. Those structures can change when a dynamic module re-serializes its metadata; ifGetMetadatais called again without an interveningTarget.Flush, the cached descriptors can cause the updated metadata generation to be detected but the old address/size to still be used. Consider reading these descriptor types uncached for this mutable path.
private TargetSpan GetReadWriteSavedMetadataAddress(ModuleHandle handle)
{
Data.Module module = target.ProcessedData.GetOrAdd<Data.Module>(handle.Address);
Data.DynamicMetadata dynamicMetadata = target.ProcessedData.GetOrAdd<Data.DynamicMetadata>(module.DynamicMetadata);
return new TargetSpan(dynamicMetadata.Data, dynamicMetadata.Size);
- Files reviewed: 26/26 changed files
- Comments generated: 8
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Contributor
There was a problem hiding this comment.
Copilot's findings
Comments suppressed due to low confidence (1)
src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/EcmaMetadata_1.cs:380
- GetReadWriteSavedMetadataAddress uses ProcessedData.GetOrAdd for Module/DynamicMetadata. Dynamic modules can re-serialize and replace the DynamicMetadata buffer while the debuggee is paused (no Target.Flush), so cached IData snapshots can become stale even though GetMetadataGeneration detects a new generation. Use uncached IData reads here so the updated DynamicMetadata pointer/size is observed.
Data.Module module = target.ProcessedData.GetOrAdd<Data.Module>(handle.Address);
Data.DynamicMetadata dynamicMetadata = target.ProcessedData.GetOrAdd<Data.DynamicMetadata>(module.DynamicMetadata);
- Files reviewed: 26/26 changed files
- Comments generated: 6
This was referenced Jun 28, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #129557