-
Notifications
You must be signed in to change notification settings - Fork 5.4k
[cDAC] Changing loader heaps from string-keyed to enum-keyed dict #127474
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -44,6 +44,20 @@ public enum ClrModifiableAssemblies : uint | |
| Debug = 2, | ||
| } | ||
|
|
||
| public enum LoaderAllocatorHeapType : uint | ||
| { | ||
| LowFrequency = 0, | ||
| HighFrequency = 1, | ||
| Statics = 2, | ||
| Stub = 3, | ||
| Executable = 4, | ||
| FixupPrecode = 5, | ||
| NewStubPrecode = 6, | ||
| DynamicHelpers = 7, | ||
| Indcell = 8, | ||
| CacheEntry = 9, | ||
| } | ||
|
Comment on lines
+47
to
+59
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Any reason to explicitly define the size of this enum and values? The flags above do, but given this is a true managed enum, I don't think we need to. |
||
|
|
||
| [Flags] | ||
| public enum AssemblyIterationFlags | ||
| { | ||
|
|
@@ -130,7 +144,7 @@ public interface ILoader : IContract | |
| TargetPointer GetFirstLoaderHeapBlock(TargetPointer loaderHeap) => throw new NotImplementedException(); | ||
| // Returns the data for the given loader heap block (address, size, and next block pointer). | ||
| LoaderHeapBlockData GetLoaderHeapBlockData(TargetPointer block) => throw new NotImplementedException(); | ||
| IReadOnlyDictionary<string, TargetPointer> GetLoaderAllocatorHeaps(TargetPointer loaderAllocatorPointer) => throw new NotImplementedException(); | ||
| IReadOnlyDictionary<LoaderAllocatorHeapType, TargetPointer> GetLoaderAllocatorHeaps(TargetPointer loaderAllocatorPointer) => throw new NotImplementedException(); | ||
|
|
||
| DebuggerAssemblyControlFlags GetDebuggerInfoBits(ModuleHandle handle) => throw new NotImplementedException(); | ||
| void SetDebuggerInfoBits(ModuleHandle handle, DebuggerAssemblyControlFlags newBits) => throw new NotImplementedException(); | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -6378,10 +6378,8 @@ int ISOSDacInterface13.GetLoaderAllocatorHeaps(ClrDataAddress loaderAllocator, i | |
| try | ||
| { | ||
| Contracts.ILoader contract = _target.Contracts.Loader; | ||
| IReadOnlyDictionary<string, TargetPointer> heaps = contract.GetLoaderAllocatorHeaps(loaderAllocator.ToTargetPointer(_target)); | ||
|
|
||
| var filteredEntries = GetFilteredHeapNameEntries(); | ||
| int loaderHeapCount = filteredEntries.Length; | ||
| IReadOnlyDictionary<LoaderAllocatorHeapType, TargetPointer> heaps = contract.GetLoaderAllocatorHeaps(loaderAllocator.ToTargetPointer(_target)); | ||
| int loaderHeapCount = heaps.Count; | ||
|
|
||
| if (pNeeded != null) | ||
| *pNeeded = loaderHeapCount; | ||
|
|
@@ -6394,12 +6392,15 @@ int ISOSDacInterface13.GetLoaderAllocatorHeaps(ClrDataAddress loaderAllocator, i | |
| } | ||
| else | ||
| { | ||
| for (int i = 0; i < loaderHeapCount; i++) | ||
| int i = 0; | ||
| foreach (LoaderAllocatorHeapType heapType in Enum.GetValues<LoaderAllocatorHeapType>()) | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So we'd have something like |
||
| { | ||
| pLoaderHeaps[i] = heaps.TryGetValue(filteredEntries[i].Name, out TargetPointer heapAddr) | ||
| ? heapAddr.ToClrDataAddress(_target) | ||
| : 0; | ||
| pKinds[i] = 0; // LoaderHeapKindNormal | ||
| if (heaps.TryGetValue(heapType, out TargetPointer heapAddr)) | ||
| { | ||
| pLoaderHeaps[i] = heapAddr.ToClrDataAddress(_target); | ||
| pKinds[i] = 0; // LoaderHeapKindNormal | ||
| i++; | ||
| } | ||
| } | ||
| } | ||
| } | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -154,17 +154,17 @@ | |
| Assert.Throws<DecoderFallbackException>(() => contract.TryGetSimpleName(handle, out _)); | ||
| } | ||
|
|
||
| private static readonly Dictionary<string, TargetPointer> MockHeapDictionary = new() | ||
| { | ||
| ["LowFrequencyHeap"] = new(0x1000), | ||
| ["HighFrequencyHeap"] = new(0x2000), | ||
| ["StaticsHeap"] = new(0x3000), | ||
| ["StubHeap"] = new(0x4000), | ||
| ["ExecutableHeap"] = new(0x5000), | ||
| ["FixupPrecodeHeap"] = new(0x6000), | ||
| ["NewStubPrecodeHeap"] = new(0x7000), | ||
| ["IndcellHeap"] = new(0x8000), | ||
| ["CacheEntryHeap"] = new(0x9000), | ||
| private static readonly Dictionary<LoaderAllocatorHeapType, TargetPointer> MockHeapDictionary = new() | ||
| { | ||
| [LoaderAllocatorHeapType.LowFrequency] = new(0x1000), | ||
| [LoaderAllocatorHeapType.HighFrequency] = new(0x2000), | ||
| [LoaderAllocatorHeapType.Statics] = new(0x3000), | ||
| [LoaderAllocatorHeapType.Stub] = new(0x4000), | ||
| [LoaderAllocatorHeapType.Executable] = new(0x5000), | ||
| [LoaderAllocatorHeapType.FixupPrecode] = new(0x6000), | ||
| [LoaderAllocatorHeapType.NewStubPrecode] = new(0x7000), | ||
| [LoaderAllocatorHeapType.Indcell] = new(0x8000), | ||
| [LoaderAllocatorHeapType.CacheEntry] = new(0x9000), | ||
| }; | ||
|
|
||
| private static ISOSDacInterface13 CreateSOSDacInterface13ForHeapTests(MockTarget.Architecture arch) | ||
|
|
@@ -201,7 +201,7 @@ | |
| var target = targetBuilder | ||
| .AddTypes(types) | ||
| .AddMockContract<ILoader>(Mock.Of<ILoader>( | ||
| l => l.GetLoaderAllocatorHeaps(It.IsAny<TargetPointer>()) == (IReadOnlyDictionary<string, TargetPointer>)MockHeapDictionary | ||
| l => l.GetLoaderAllocatorHeaps(It.IsAny<TargetPointer>()) == (IReadOnlyDictionary<LoaderAllocatorHeapType, TargetPointer>)MockHeapDictionary | ||
| && l.GetGlobalLoaderAllocator() == new TargetPointer(0x100))) | ||
| .Build(); | ||
| return new SOSDacImpl(target, null); | ||
|
|
@@ -235,7 +235,7 @@ | |
|
|
||
| Assert.Equal(HResults.S_OK, hr); | ||
| Assert.Equal(MockHeapDictionary.Count, needed); | ||
| HashSet<string> expectedNames = new(MockHeapDictionary.Keys); | ||
|
Check failure on line 238 in src/native/managed/cdac/tests/LoaderTests.cs
|
||
| for (int i = 0; i < needed; i++) | ||
| { | ||
| string actual = Marshal.PtrToStringAnsi((nint)names[i])!; | ||
|
|
@@ -255,7 +255,7 @@ | |
|
|
||
| Assert.Equal(HResults.S_FALSE, hr); | ||
| Assert.Equal(MockHeapDictionary.Count, needed); | ||
| HashSet<string> expectedNames = new(MockHeapDictionary.Keys); | ||
|
Check failure on line 258 in src/native/managed/cdac/tests/LoaderTests.cs
|
||
| for (int i = 0; i < 2; i++) | ||
| { | ||
| string actual = Marshal.PtrToStringAnsi((nint)names[i])!; | ||
|
|
@@ -293,22 +293,21 @@ | |
| ISOSDacInterface13 impl = CreateSOSDacInterface13ForHeapTests(arch); | ||
|
|
||
| int needed; | ||
| impl.GetLoaderAllocatorHeapNames(0, null, &needed); | ||
|
|
||
| char** names = stackalloc char*[needed]; | ||
| impl.GetLoaderAllocatorHeapNames(needed, names, &needed); | ||
|
|
||
| ClrDataAddress* heaps = stackalloc ClrDataAddress[needed]; | ||
| int* kinds = stackalloc int[needed]; | ||
| int hr = impl.GetLoaderAllocatorHeaps(new ClrDataAddress(0x100), needed, heaps, kinds, &needed); | ||
| ClrDataAddress* heaps = stackalloc ClrDataAddress[MockHeapDictionary.Count]; | ||
| int* kinds = stackalloc int[MockHeapDictionary.Count]; | ||
| int hr = impl.GetLoaderAllocatorHeaps(new ClrDataAddress(0x100), MockHeapDictionary.Count, heaps, kinds, &needed); | ||
|
|
||
| Assert.Equal(HResults.S_OK, hr); | ||
| Assert.Equal(MockHeapDictionary.Count, needed); | ||
| for (int i = 0; i < needed; i++) | ||
| int i = 0; | ||
| foreach (LoaderAllocatorHeapType heapType in Enum.GetValues<LoaderAllocatorHeapType>()) | ||
| { | ||
| string name = Marshal.PtrToStringAnsi((nint)names[i])!; | ||
| Assert.Equal((ulong)MockHeapDictionary[name], (ulong)heaps[i]); | ||
| Assert.Equal(0, kinds[i]); // LoaderHeapKindNormal | ||
| if (MockHeapDictionary.TryGetValue(heapType, out TargetPointer expected)) | ||
| { | ||
| Assert.Equal((ulong)expected, (ulong)heaps[i]); | ||
| Assert.Equal(0, kinds[i]); // LoaderHeapKindNormal | ||
| i++; | ||
| } | ||
|
Comment on lines
+296
to
+310
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please revert this unit test. We should verify that it matches the heap names, not the enum. |
||
| } | ||
| } | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe reserve 0 for an Unknown type in case there is something added in the future?