Make custom IData initializers lazy - #131763
Merged
max-charlamb merged 1 commit intoAug 3, 2026
Merged
Conversation
Replace eager OnInit hooks with named per-property initializers and teach CdacUsageGraph to combine declared initializer dependencies with inferred body usage. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: ac4f2b2a-736b-4295-b586-50887eabfc60
|
Azure Pipelines: Successfully started running 5 pipeline(s). 11 pipeline(s) were filtered out due to trigger conditions. There may be pipelines that require an authorized user to comment /azp run to run. |
Contributor
|
Tagging subscribers to this area: @steveisok, @tommcdon, @dotnet/dotnet-diag |
Contributor
There was a problem hiding this comment.
Pull request overview
Refactors cDAC IData custom initialization from a single eager OnInit hook to named, per-property lazy initializer methods (via a new [CustomInit] attribute), and updates the usage-analysis tooling/tests/docs accordingly.
Changes:
- Introduces
[CustomInit(nameof(Method))]and generator support to emit lazy, memoized getters that call an author-provided initializer method. - Updates CdacUsageGraph to treat initializer methods as dependency-bearing while still walking their bodies for inferred globals/helper/property reads.
- Converts many existing
IDataimplementations (Contracts/Data) and updates design docs + generator/usage tests for the new model.
Reviewed changes
Copilot reviewed 48 out of 48 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| src/native/managed/cdac/tools/CdacUsageGraph/tests/CdacUsageGraph.Tests/UsageWalkerIntegrationTests.cs | Updates integration test to read deps from init methods |
| src/native/managed/cdac/tools/CdacUsageGraph/tests/CdacUsageGraph.Tests/DataTypeIndexTests.cs | Updates/extends usage-index tests for custom init behavior |
| src/native/managed/cdac/tools/CdacUsageGraph/src/CdacUsageGraph/Semantic/CdacAttributeMatcher.cs | Adds CustomInit symbol + custom-initializer detection |
| src/native/managed/cdac/tools/CdacUsageGraph/src/CdacUsageGraph/CdacSymbols.cs | Adds metadata name constant for CustomInitAttribute |
| src/native/managed/cdac/tools/CdacUsageGraph/src/CdacUsageGraph/Analysis/UsageWalker.cs | Avoids short-circuiting body analysis for custom init methods |
| src/native/managed/cdac/tests/DataGenerator/TestTypes.cs | Adds test type covering [CustomInit] generator behavior |
| src/native/managed/cdac/tests/DataGenerator/DataGeneratorTests.cs | Adds tests for laziness/memoization and dependency behavior |
| src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/UnwindInfo.cs | Converts OnInit to per-property custom initializers |
| src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/TypeDesc.cs | Converts OnInit to custom initializer returning base-derived value |
| src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/Thread.cs | Splits eager init into per-property custom initializers |
| src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/TableSegment.cs | Makes byte-buffer reads lazy via custom initializers |
| src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/TableRW.cs | Adds descriptor-only type to surface generated GetSize |
| src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/SyncTableEntry.cs | Converts pointer-following init logic to lazy initializers |
| src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/SyncBlock.cs | Splits OnInit reads into per-property lazy initializers |
| src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/ReadyToRunInfo.cs | Converts multiple pointer computations to lazy initializers |
| src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/ReadyToRunCoreHeader.cs | Converts section list materialization to lazy initializer |
| src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/RCW.cs | Converts interface-entry list read to lazy initializer |
| src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/RangeSectionFragment.cs | Converts tag-bit stripping logic to custom initializer |
| src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/PrecodeMachineDescriptor.cs | Reworks optional fields/buffers into per-property lazy initializers |
| src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/ObjectHandle.cs | Splits handle/object computation into per-property initializers |
| src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/InterpreterRealCodeHeader.cs | Converts pointer-following init logic to lazy initializer |
| src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/InstMethodHashTable.cs | Converts entry enumeration to lazy initializer |
| src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/HandleTableMap.cs | Converts bucket-pointer list read to lazy initializer |
| src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/Frames/HijackArgs.cs | Converts register map materialization to lazy initializer |
| src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/Frames/Frame.cs | Converts identifier read to lazy initializer |
| src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/Frames/CalleeSavedRegisters.cs | Converts register map materialization to lazy initializer |
| src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/Frames/ArgumentRegisters.cs | Converts register map materialization to lazy initializer |
| src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/EETypeHashTable.cs | Converts entry enumeration to lazy initializer |
| src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/DynamicStaticsInfo.cs | Splits masked-pointer reads into lazy initializers |
| src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/ComWrappersVtablePtrs.cs | Converts pointer list materialization to lazy initializer |
| src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/ComInterfaceEntry.cs | Converts GUID materialization to lazy initializer |
| src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/ComCallWrapper.cs | Converts interface pointer array read to lazy initializer |
| src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/CMiniMdRW.cs | Uses TableRW.GetSize(target) via new descriptor-only type |
| src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/Bucket.cs | Splits key/value array materialization into separate lazy initializers |
| src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/ArrayListBase.cs | Splits blocks vs element flattening into separate lazy initializers |
| src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Abstractions/CdacAttributes.cs | Adds new public [CustomInit] attribute definition |
| src/native/managed/cdac/IData.md | Updates spec to describe [CustomInit] replacing OnInit |
| src/native/managed/cdac/gen/Parser.cs | Parses [CustomInit]; refactors writable-field tracking |
| src/native/managed/cdac/gen/Model.cs | Adds CustomInit member kind; extends member model |
| src/native/managed/cdac/gen/Emitter.cs | Emits lazy getters that call named initializer methods |
| docs/design/datacontracts/WindowsErrorReporting.md | Regenerates “data descriptors used” (removals/updates) |
| docs/design/datacontracts/SyncBlock.md | Regenerates “data descriptors used” (removals/updates) |
| docs/design/datacontracts/StackWalk.md | Regenerates “data descriptors used” (removals/updates) |
| docs/design/datacontracts/RuntimeMutableTypeSystem.md | Regenerates “data descriptors used” (removals/updates) |
| docs/design/datacontracts/Object.md | Regenerates “data descriptors used” (removals/updates) |
| docs/design/datacontracts/ExecutionManager.md | Regenerates “data descriptors used” (additions/updates) |
| docs/design/datacontracts/EcmaMetadata.md | Updates docs to include TableRW type-size usage |
| docs/design/datacontracts/data-descriptor-meanings.json | Adds meaning entry for TableRW.Size |
rcj1
approved these changes
Aug 3, 2026
rcj1
left a comment
Contributor
There was a problem hiding this comment.
lgtm, good cleanup of generated dependencies.
max-charlamb
marked this pull request as ready for review
August 3, 2026 19:41
|
Azure Pipelines: Successfully started running 5 pipeline(s). 11 pipeline(s) were filtered out due to trigger conditions. There may be pipelines that require an authorized user to comment /azp run to run. |
max-charlamb
enabled auto-merge (squash)
August 3, 2026 20:21
Member
Author
|
/ba-g osx timeouts |
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.
Summary
This changes custom IData initialization from one eager
OnInithook to named, per-property lazy initializer methods.IData generation
[CustomInit(nameof(Method))]for properties requiring custom read logic.[Field(Writable = true)]properties.TableRWIData type so its generatedGetSizemethod is used when indexing metadata tables.Usage analysis
DataDescriptorDependencyandUsesDataDescriptorTypeSizeannotations on custom initializer methods.EnsureAllFieldsReadas a complete dependency summary for types with custom initializers.IData implementations
OnInitimplementations to named per-property initializer methods.Documentation and tests
Testing
docs --checkNote
This pull request description was generated with GitHub Copilot.