From fb9d3ce81699beea55326be60d605c64dd3619e7 Mon Sep 17 00:00:00 2001 From: Barbara Rosiak Date: Wed, 27 May 2026 16:02:20 -0700 Subject: [PATCH 1/4] Implement AreOptimizationsDisabled for cDAC --- docs/design/datacontracts/ReJIT.md | 18 ++++ src/coreclr/vm/codeversion.h | 1 + .../vm/datadescriptor/datadescriptor.inc | 1 + .../Contracts/IReJIT.cs | 2 + .../Contracts/ReJIT_1.cs | 10 ++ .../Data/ILCodeVersionNode.cs | 2 + .../Dbi/DacDbiImpl.cs | 48 ++++++++- .../managed/cdac/tests/DacDbiImplTests.cs | 99 +++++++++++++++++++ .../MockDescriptors.CodeVersions.cs | 11 ++- .../MockDescriptors/MockDescriptors.ReJIT.cs | 4 +- src/native/managed/cdac/tests/ReJITTests.cs | 33 +++++++ 11 files changed, 225 insertions(+), 4 deletions(-) diff --git a/docs/design/datacontracts/ReJIT.md b/docs/design/datacontracts/ReJIT.md index e9fa276808abb1..e8668fdab27f3c 100644 --- a/docs/design/datacontracts/ReJIT.md +++ b/docs/design/datacontracts/ReJIT.md @@ -17,6 +17,8 @@ bool IsEnabled(); RejitState GetRejitState(ILCodeVersionHandle codeVersionHandle); +bool IsDeoptimized(ILCodeVersionHandle codeVersionHandle); + TargetNUInt GetRejitId(ILCodeVersionHandle codeVersionHandle); IEnumerable GetRejitIds(TargetPointer methodDesc) @@ -33,6 +35,7 @@ Data descriptors used: | ProfControlBlock | NotificationProfilerCount | number of notification-only profilers currently attached | | ILCodeVersionNode | VersionId | `ILCodeVersion` ReJIT ID | ILCodeVersionNode | RejitState | a `RejitFlags` value | +| ILCodeVersionNode | Deoptimized | whether this IL code version has been deoptimized | Global variables used: | Global Name | Type | Purpose | @@ -93,6 +96,21 @@ RejitState GetRejitState(ILCodeVersionHandle codeVersion) } } +bool IsDeoptimized(ILCodeVersionHandle codeVersion) +{ + // ILCodeVersion::IsDeoptimized + if (codeVersion is not explicit) + { + return false; + } + else + { + // ILCodeVersionNode::IsDeoptimized + ILCodeVersionNode codeVersionNode = AsNode(codeVersion); + return codeVersionNode.Deoptimized; + } +} + TargetNUInt GetRejitId(ILCodeVersionHandle codeVersion) { // ILCodeVersion::GetVersionId diff --git a/src/coreclr/vm/codeversion.h b/src/coreclr/vm/codeversion.h index 50c4b82e28fd2d..57a00a399cf605 100644 --- a/src/coreclr/vm/codeversion.h +++ b/src/coreclr/vm/codeversion.h @@ -435,6 +435,7 @@ struct cdac_data static constexpr size_t Next = offsetof(ILCodeVersionNode, m_pNextILVersionNode); static constexpr size_t RejitState = offsetof(ILCodeVersionNode, m_rejitState); static constexpr size_t ILAddress = offsetof(ILCodeVersionNode, m_pIL); + static constexpr size_t Deoptimized = offsetof(ILCodeVersionNode, m_deoptimized); }; class ILCodeVersionCollection diff --git a/src/coreclr/vm/datadescriptor/datadescriptor.inc b/src/coreclr/vm/datadescriptor/datadescriptor.inc index d8b0ae58896a83..987896d88ff65a 100644 --- a/src/coreclr/vm/datadescriptor/datadescriptor.inc +++ b/src/coreclr/vm/datadescriptor/datadescriptor.inc @@ -986,6 +986,7 @@ CDAC_TYPE_FIELD(ILCodeVersionNode, T_NUINT, VersionId, cdac_data::Next) CDAC_TYPE_FIELD(ILCodeVersionNode, T_UINT32, RejitState, cdac_data::RejitState) CDAC_TYPE_FIELD(ILCodeVersionNode, T_POINTER, ILAddress, cdac_data::ILAddress) +CDAC_TYPE_FIELD(ILCodeVersionNode, T_BOOL, Deoptimized, cdac_data::Deoptimized) CDAC_TYPE_END(ILCodeVersionNode) #endif // FEATURE_CODE_VERSIONING diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Abstractions/Contracts/IReJIT.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Abstractions/Contracts/IReJIT.cs index e01fca40002b73..6db4cb08392236 100644 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Abstractions/Contracts/IReJIT.cs +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Abstractions/Contracts/IReJIT.cs @@ -20,6 +20,8 @@ public interface IReJIT : IContract RejitState GetRejitState(ILCodeVersionHandle codeVersionHandle) => throw new NotImplementedException(); + bool IsDeoptimized(ILCodeVersionHandle codeVersionHandle) => throw new NotImplementedException(); + TargetNUInt GetRejitId(ILCodeVersionHandle codeVersionHandle) => throw new NotImplementedException(); } diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/ReJIT_1.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/ReJIT_1.cs index 3e4e79d89a245e..3e0d217c10550c 100644 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/ReJIT_1.cs +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/ReJIT_1.cs @@ -59,6 +59,16 @@ RejitState IReJIT.GetRejitState(ILCodeVersionHandle ilCodeVersionHandle) }; } + bool IReJIT.IsDeoptimized(ILCodeVersionHandle ilCodeVersionHandle) + { + if (!ilCodeVersionHandle.IsExplicit) + { + return false; + } + ILCodeVersionNode ilCodeVersionNode = AsNode(ilCodeVersionHandle); + return ilCodeVersionNode.Deoptimized; + } + TargetNUInt IReJIT.GetRejitId(ILCodeVersionHandle ilCodeVersionHandle) { if (ilCodeVersionHandle.ILCodeVersionNode == TargetPointer.Null) diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/ILCodeVersionNode.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/ILCodeVersionNode.cs index cf0bb305211a5f..984bcacd9b65a6 100644 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/ILCodeVersionNode.cs +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/ILCodeVersionNode.cs @@ -16,10 +16,12 @@ public ILCodeVersionNode(Target target, TargetPointer address) Next = target.ReadPointerField(address, type, nameof(Next)); RejitState = target.ReadField(address, type, nameof(RejitState)); ILAddress = target.ReadPointerField(address, type, nameof(ILAddress)); + Deoptimized = target.ReadField(address, type, nameof(Deoptimized)) != 0; } public TargetNUInt VersionId { get; init; } public TargetPointer Next { get; init; } public uint RejitState { get; init; } public TargetPointer ILAddress { get; init; } + public bool Deoptimized { get; init; } } diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Legacy/Dbi/DacDbiImpl.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Legacy/Dbi/DacDbiImpl.cs index 7f012cbed98b31..2d9d0051e3e048 100644 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Legacy/Dbi/DacDbiImpl.cs +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Legacy/Dbi/DacDbiImpl.cs @@ -2911,7 +2911,53 @@ public int GetPEFileMDInternalRW(ulong vmPEAssembly, ulong* pAddrMDInternalRW) => LegacyFallbackHelper.CanFallback() && _legacy is not null ? _legacy.GetPEFileMDInternalRW(vmPEAssembly, pAddrMDInternalRW) : HResults.E_NOTIMPL; public int AreOptimizationsDisabled(ulong vmModule, uint methodTk, Interop.BOOL* pOptimizationsDisabled) - => LegacyFallbackHelper.CanFallback() && _legacy is not null ? _legacy.AreOptimizationsDisabled(vmModule, methodTk, pOptimizationsDisabled) : HResults.E_NOTIMPL; + { + int hr = HResults.S_OK; + try + { + if (pOptimizationsDisabled is null) + throw new ArgumentException("Output pointer cannot be null.", nameof(pOptimizationsDisabled)); + + if ((EcmaMetadataUtils.TokenType)(methodTk & EcmaMetadataUtils.TokenTypeMask) != EcmaMetadataUtils.TokenType.mdtMethodDef) + throw new ArgumentException("methodTk must be a MethodDef token.", nameof(methodTk)); + + *pOptimizationsDisabled = Interop.BOOL.FALSE; + if (_target.Contracts.TryGetContract(out IReJIT rejit)) + { + ILoader loader = _target.Contracts.Loader; + Contracts.ModuleHandle module = loader.GetModuleHandleFromModulePtr(new TargetPointer(vmModule)); + ModuleLookupTables lookupTables = loader.GetLookupTables(module); + TargetPointer methodDesc = loader.GetModuleLookupMapElement(lookupTables.MethodDefToDesc, methodTk, out _); + + if (methodDesc != TargetPointer.Null) + { + ICodeVersions codeVersions = _target.Contracts.CodeVersions; + ILCodeVersionHandle ilCodeVersion = codeVersions.GetActiveILCodeVersion(methodDesc); + if (rejit.IsDeoptimized(ilCodeVersion)) + { + *pOptimizationsDisabled = Interop.BOOL.TRUE; + } + } + } + } + catch (System.Exception ex) + { + hr = ex.HResult; + } + +#if DEBUG + if (_legacy is not null) + { + Interop.BOOL localPOptimizationsDisabled; + int hrLocal = _legacy.AreOptimizationsDisabled(vmModule, methodTk, &localPOptimizationsDisabled); + Debug.ValidateHResult(hr, hrLocal); + if (hr == HResults.S_OK) + Debug.Assert(*pOptimizationsDisabled == localPOptimizationsDisabled); + } +#endif + + return hr; + } public int GetDefinesBitField(uint* pDefines) { diff --git a/src/native/managed/cdac/tests/DacDbiImplTests.cs b/src/native/managed/cdac/tests/DacDbiImplTests.cs index 9ce032a272c0af..81c8895cece65e 100644 --- a/src/native/managed/cdac/tests/DacDbiImplTests.cs +++ b/src/native/managed/cdac/tests/DacDbiImplTests.cs @@ -635,4 +635,103 @@ private static (DacDbiImpl DacDbi, Target Target) CreateCheckContextDacDbi(MockT } private delegate void GetStackLimitDataCallback(TargetPointer threadPointer, out TargetPointer stackBase, out TargetPointer stackLimit, out TargetPointer frameAddress); + + private const uint MdtMethodDef = 0x06000000; + + private static DacDbiImpl CreateDacDbiWithMockContracts( + MockTarget.Architecture arch, + Mock mockLoader, + Mock mockCodeVersions, + Mock mockReJIT) + { + var target = new TestPlaceholderTarget.Builder(arch) + .UseReader((_, _) => -1) + .AddMockContract(mockLoader) + .AddMockContract(mockCodeVersions) + .AddMockContract(mockReJIT) + .Build(); + return new DacDbiImpl(target, legacyObj: null); + } + + private static Mock SetupMockLoader(TargetPointer modulePtr, uint methodTk, TargetPointer methodDesc) + { + var mockLoader = new Mock(); + var moduleHandle = new Contracts.ModuleHandle(modulePtr); + var lookupTables = new ModuleLookupTables { MethodDefToDesc = new TargetPointer(0x4000) }; + mockLoader.Setup(l => l.GetModuleHandleFromModulePtr(modulePtr)).Returns(moduleHandle); + mockLoader.Setup(l => l.GetLookupTables(moduleHandle)).Returns(lookupTables); + mockLoader.Setup(l => l.GetModuleLookupMapElement(lookupTables.MethodDefToDesc, methodTk, out It.Ref.IsAny)) + .Returns(methodDesc); + return mockLoader; + } + + [Theory] + [ClassData(typeof(MockTarget.StdArch))] + public void AreOptimizationsDisabled_NullOutput_ReturnsError(MockTarget.Architecture arch) + { + var dacDbi = CreateDacDbiWithMockContracts( + arch, new Mock(), new Mock(), new Mock()); + int hr = dacDbi.AreOptimizationsDisabled(0x1000, MdtMethodDef | 1, null); + Assert.NotEqual(System.HResults.S_OK, hr); + } + + [Theory] + [ClassData(typeof(MockTarget.StdArch))] + public void AreOptimizationsDisabled_InvalidToken_ReturnsError(MockTarget.Architecture arch) + { + var dacDbi = CreateDacDbiWithMockContracts( + arch, new Mock(), new Mock(), new Mock()); + Interop.BOOL result; + int hr = dacDbi.AreOptimizationsDisabled(0x1000, 0x01000001, &result); + Assert.NotEqual(System.HResults.S_OK, hr); + } + + public static IEnumerable ArchWithDeoptimized() + { + foreach (object[] stdArch in new MockTarget.StdArch()) + { + yield return [stdArch[0], true]; + yield return [stdArch[0], false]; + } + } + + [Theory] + [MemberData(nameof(ArchWithDeoptimized))] + public void AreOptimizationsDisabled_WithMethodDesc(MockTarget.Architecture arch, bool deoptimized) + { + TargetPointer modulePtr = new(0x1000); + uint methodTk = MdtMethodDef | 1; + TargetPointer methodDesc = new(0x2000); + var ilCodeVersion = ILCodeVersionHandle.CreateExplicit(new TargetPointer(0x3000)); + + Mock mockLoader = SetupMockLoader(modulePtr, methodTk, methodDesc); + + var mockCodeVersions = new Mock(); + mockCodeVersions.Setup(cv => cv.GetActiveILCodeVersion(methodDesc)).Returns(ilCodeVersion); + + var mockReJIT = new Mock(); + mockReJIT.Setup(r => r.IsDeoptimized(ilCodeVersion)).Returns(deoptimized); + + var dacDbi = CreateDacDbiWithMockContracts(arch, mockLoader, mockCodeVersions, mockReJIT); + Interop.BOOL result; + int hr = dacDbi.AreOptimizationsDisabled(modulePtr.Value, methodTk, &result); + Assert.Equal(System.HResults.S_OK, hr); + Assert.Equal(deoptimized ? Interop.BOOL.TRUE : Interop.BOOL.FALSE, result); + } + + [Theory] + [ClassData(typeof(MockTarget.StdArch))] + public void AreOptimizationsDisabled_NullMethodDesc_ReturnsFalse(MockTarget.Architecture arch) + { + TargetPointer modulePtr = new(0x1000); + uint methodTk = MdtMethodDef | 1; + + Mock mockLoader = SetupMockLoader(modulePtr, methodTk, TargetPointer.Null); + + var dacDbi = CreateDacDbiWithMockContracts(arch, mockLoader, new Mock(), new Mock()); + Interop.BOOL result; + int hr = dacDbi.AreOptimizationsDisabled(modulePtr.Value, methodTk, &result); + Assert.Equal(System.HResults.S_OK, hr); + Assert.Equal(Interop.BOOL.FALSE, result); + } } diff --git a/src/native/managed/cdac/tests/MockDescriptors/MockDescriptors.CodeVersions.cs b/src/native/managed/cdac/tests/MockDescriptors/MockDescriptors.CodeVersions.cs index cd31668f7c2861..5ec6375ed8e990 100644 --- a/src/native/managed/cdac/tests/MockDescriptors/MockDescriptors.CodeVersions.cs +++ b/src/native/managed/cdac/tests/MockDescriptors/MockDescriptors.CodeVersions.cs @@ -151,6 +151,7 @@ internal sealed class MockILCodeVersionNode : TypedView private const string NextFieldName = "Next"; private const string RejitStateFieldName = "RejitState"; private const string ILAddressFieldName = "ILAddress"; + private const string DeoptimizedFieldName = "Deoptimized"; public static Layout CreateLayout(MockTarget.Architecture architecture) => new SequentialLayoutBuilder("ILCodeVersionNode", architecture) @@ -158,6 +159,7 @@ public static Layout CreateLayout(MockTarget.Architecture .AddPointerField(NextFieldName) .AddUInt32Field(RejitStateFieldName) .AddPointerField(ILAddressFieldName) + .AddUInt32Field(DeoptimizedFieldName) .Build(); public ulong VersionId @@ -177,6 +179,12 @@ public uint RejitState get => ReadUInt32Field(RejitStateFieldName); set => WriteUInt32Field(RejitStateFieldName, value); } + + public uint Deoptimized + { + get => ReadUInt32Field(DeoptimizedFieldName); + set => WriteUInt32Field(DeoptimizedFieldName, value); + } } internal sealed class MockGCCoverageInfo : TypedView @@ -305,12 +313,13 @@ public MockILCodeVersioningState AddILCodeVersioningState() => ILCodeVersioningStateLayout.Create( _codeVersionsAllocator.Allocate((ulong)ILCodeVersioningStateLayout.Size, "ILCodeVersioningState")); - public MockILCodeVersionNode AddILCodeVersionNode(ulong versionId, uint rejitFlags) + public MockILCodeVersionNode AddILCodeVersionNode(ulong versionId, uint rejitFlags, bool deoptimized = false) { MockILCodeVersionNode node = ILCodeVersionNodeLayout.Create( _codeVersionsAllocator.Allocate((ulong)ILCodeVersionNodeLayout.Size, "ILCodeVersionNode")); node.VersionId = versionId; node.RejitState = rejitFlags; + node.Deoptimized = deoptimized ? 1u : 0u; node.Next = 0; return node; diff --git a/src/native/managed/cdac/tests/MockDescriptors/MockDescriptors.ReJIT.cs b/src/native/managed/cdac/tests/MockDescriptors/MockDescriptors.ReJIT.cs index d38ee5a6fe325c..82058359f9e83f 100644 --- a/src/native/managed/cdac/tests/MockDescriptors/MockDescriptors.ReJIT.cs +++ b/src/native/managed/cdac/tests/MockDescriptors/MockDescriptors.ReJIT.cs @@ -93,8 +93,8 @@ public MockReJITBuilder(MockMemorySpace.Builder builder, (ulong Start, ulong End internal Layout ILCodeVersionNodeLayout => _codeVersions.ILCodeVersionNodeLayout; internal Layout GCCoverageInfoLayout => _codeVersions.GCCoverageInfoLayout; - public MockILCodeVersionNode AddExplicitILCodeVersionNode(ulong rejitId, RejitFlags rejitFlags) - => _codeVersions.AddILCodeVersionNode(rejitId, (uint)rejitFlags); + public MockILCodeVersionNode AddExplicitILCodeVersionNode(ulong rejitId, RejitFlags rejitFlags, bool deoptimized = false) + => _codeVersions.AddILCodeVersionNode(rejitId, (uint)rejitFlags, deoptimized); private ulong AddProfControlBlock(bool rejitOnAttachEnabled) { diff --git a/src/native/managed/cdac/tests/ReJITTests.cs b/src/native/managed/cdac/tests/ReJITTests.cs index ab5aa50a317999..8dd980f84d4500 100644 --- a/src/native/managed/cdac/tests/ReJITTests.cs +++ b/src/native/managed/cdac/tests/ReJITTests.cs @@ -154,4 +154,37 @@ public void GetRejitIds_SyntheticAndExplicit_Success(MockTarget.Architecture arc Assert.Equal(expectedRejitIds, rejitIds); } + + [Theory] + [ClassData(typeof(MockTarget.StdArch))] + public void IsDeoptimized_Synthetic(MockTarget.Architecture arch) + { + ReJITContractContext context = CreateReJITContract(arch, _ => { }); + ILCodeVersionHandle synthetic = ILCodeVersionHandle.CreateSynthetic(new TargetPointer(0x100), 100); + Assert.False(context.ReJIT.IsDeoptimized(synthetic)); + } + + public static IEnumerable ArchWithDeoptimized() + { + foreach (object[] stdArch in new MockTarget.StdArch()) + { + yield return [stdArch[0], true]; + yield return [stdArch[0], false]; + } + } + + [Theory] + [MemberData(nameof(ArchWithDeoptimized))] + public void IsDeoptimized_Explicit(MockTarget.Architecture arch, bool deoptimized) + { + ILCodeVersionHandle explicitHandle = ILCodeVersionHandle.Invalid; + ReJITContractContext context = CreateReJITContract( + arch, + rejitBuilder => + { + var node = rejitBuilder.AddExplicitILCodeVersionNode(1, MockReJITBuilder.RejitFlags.kStateActive, deoptimized: deoptimized); + explicitHandle = ILCodeVersionHandle.CreateExplicit(node.Address); + }); + Assert.Equal(deoptimized, context.ReJIT.IsDeoptimized(explicitHandle)); + } } From a88df5a0c5434883886837feda62994aa655c3bd Mon Sep 17 00:00:00 2001 From: Barbara Rosiak <76071368+barosiak@users.noreply.github.com> Date: Thu, 28 May 2026 12:41:53 -0700 Subject: [PATCH 2/4] Fix mismatched types Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- src/coreclr/vm/datadescriptor/datadescriptor.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreclr/vm/datadescriptor/datadescriptor.inc b/src/coreclr/vm/datadescriptor/datadescriptor.inc index 987896d88ff65a..444f1632018e05 100644 --- a/src/coreclr/vm/datadescriptor/datadescriptor.inc +++ b/src/coreclr/vm/datadescriptor/datadescriptor.inc @@ -986,7 +986,7 @@ CDAC_TYPE_FIELD(ILCodeVersionNode, T_NUINT, VersionId, cdac_data::Next) CDAC_TYPE_FIELD(ILCodeVersionNode, T_UINT32, RejitState, cdac_data::RejitState) CDAC_TYPE_FIELD(ILCodeVersionNode, T_POINTER, ILAddress, cdac_data::ILAddress) -CDAC_TYPE_FIELD(ILCodeVersionNode, T_BOOL, Deoptimized, cdac_data::Deoptimized) +CDAC_TYPE_FIELD(ILCodeVersionNode, T_UINT32, Deoptimized, cdac_data::Deoptimized) CDAC_TYPE_END(ILCodeVersionNode) #endif // FEATURE_CODE_VERSIONING From fefb12ba71cc59b8bf30c8b32114f55079662d3f Mon Sep 17 00:00:00 2001 From: Barbara Rosiak Date: Thu, 28 May 2026 13:01:35 -0700 Subject: [PATCH 3/4] Fix type mismatch, add missing exception throw --- .../Contracts/ReJIT_1.cs | 2 +- .../Data/ILCodeVersionNode.cs | 2 +- .../Dbi/DacDbiImpl.cs | 3 +++ 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/ReJIT_1.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/ReJIT_1.cs index 3e0d217c10550c..71b29a5eb8c844 100644 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/ReJIT_1.cs +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/ReJIT_1.cs @@ -66,7 +66,7 @@ bool IReJIT.IsDeoptimized(ILCodeVersionHandle ilCodeVersionHandle) return false; } ILCodeVersionNode ilCodeVersionNode = AsNode(ilCodeVersionHandle); - return ilCodeVersionNode.Deoptimized; + return ilCodeVersionNode.Deoptimized != 0; } TargetNUInt IReJIT.GetRejitId(ILCodeVersionHandle ilCodeVersionHandle) diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/ILCodeVersionNode.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/ILCodeVersionNode.cs index b9f6ea6341264c..511c93e23f89b5 100644 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/ILCodeVersionNode.cs +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/ILCodeVersionNode.cs @@ -10,5 +10,5 @@ internal sealed partial class ILCodeVersionNode : IData [Field] public TargetPointer Next { get; } [Field] public uint RejitState { get; } [Field] public TargetPointer ILAddress { get; } - [Field] public bool Deoptimized { get; } + [Field] public uint Deoptimized { get; } } diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Legacy/Dbi/DacDbiImpl.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Legacy/Dbi/DacDbiImpl.cs index ce46505687d2b7..ba95a7da541046 100644 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Legacy/Dbi/DacDbiImpl.cs +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Legacy/Dbi/DacDbiImpl.cs @@ -2979,6 +2979,9 @@ public int AreOptimizationsDisabled(ulong vmModule, uint methodTk, Interop.BOOL* int hr = HResults.S_OK; try { + if (vmModule == 0) + throw new ArgumentException("Module pointer cannot be null.", nameof(vmModule)); + if (pOptimizationsDisabled is null) throw new ArgumentException("Output pointer cannot be null.", nameof(pOptimizationsDisabled)); From ccec11558353623b564a3093f4a7cc331d450801 Mon Sep 17 00:00:00 2001 From: Barbara Rosiak <76071368+barosiak@users.noreply.github.com> Date: Thu, 28 May 2026 14:26:52 -0700 Subject: [PATCH 4/4] Delete double space Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- .../Data/ILCodeVersionNode.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/ILCodeVersionNode.cs b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/ILCodeVersionNode.cs index 511c93e23f89b5..f35f4a0398796d 100644 --- a/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/ILCodeVersionNode.cs +++ b/src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/ILCodeVersionNode.cs @@ -10,5 +10,5 @@ internal sealed partial class ILCodeVersionNode : IData [Field] public TargetPointer Next { get; } [Field] public uint RejitState { get; } [Field] public TargetPointer ILAddress { get; } - [Field] public uint Deoptimized { get; } + [Field] public uint Deoptimized { get; } }