-
Notifications
You must be signed in to change notification settings - Fork 4.9k
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
[cDAC] Implement GCCover portion of SOSDacImpl::GetMethodDescData #110322
Changes from 18 commits
41767c9
6e6461d
0129e85
8f629fd
f1e9011
8526183
a0194d2
e2ecb75
15ec95e
771949d
635a966
2396d06
61dde80
90584bf
090adca
991b217
cf7a5f1
a6eefcb
c0bd0ea
094b438
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 |
---|---|---|
|
@@ -76,4 +76,5 @@ public enum DataType | |
NonVtableSlot, | ||
MethodImpl, | ||
NativeCodeSlot, | ||
GCCoverageInfo, | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -254,6 +254,24 @@ internal static Target CreateTarget( | |
return target; | ||
} | ||
|
||
internal static Target CreateTarget( | ||
MockTarget.Architecture arch, | ||
MockCodeVersions builder, | ||
Mock<IRuntimeTypeSystem> mockRuntimeTypeSystem) | ||
{ | ||
TestPlaceholderTarget target = new TestPlaceholderTarget( | ||
arch, | ||
builder.Builder.GetReadContext().ReadFromTarget, | ||
builder.Types); | ||
|
||
IContractFactory<ICodeVersions> cvfactory = new CodeVersionsFactory(); | ||
ContractRegistry reg = Mock.Of<ContractRegistry>( | ||
c => c.CodeVersions == cvfactory.CreateContract(target, 1) | ||
&& c.RuntimeTypeSystem == mockRuntimeTypeSystem.Object); | ||
target.SetContracts(reg); | ||
return target; | ||
} | ||
Comment on lines
+257
to
+273
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. Previous CodeVersion tests use custom "mock" classes. Now that we have 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. Not for this change, but might be nice to switch the previous/existing tests to this as well. |
||
|
||
[Theory] | ||
[ClassData(typeof(MockTarget.StdArch))] | ||
public void GetNativeCodeVersion_Null(MockTarget.Architecture arch) | ||
|
@@ -678,4 +696,65 @@ public void IlToNativeToIlCodeVersion_SyntheticAndExplicit(MockTarget.Architectu | |
NativeCodeVersionHandle syntheticNativeCodeVersion = codeVersions.GetActiveNativeCodeVersionForILCodeVersion(methodDescAddress, syntheticILcodeVersion); | ||
Assert.True(syntheticILcodeVersion.Equals(codeVersions.GetILCodeVersion(syntheticNativeCodeVersion))); | ||
} | ||
|
||
private void GetGCStressCodeCopy_Impl(MockTarget.Architecture arch, bool returnsNull) | ||
{ | ||
MockCodeVersions builder = new(arch); | ||
Mock<IRuntimeTypeSystem> mockRTS = new(); | ||
|
||
// Setup synthetic NativeCodeVersion | ||
TargetPointer expectedSyntheticCodeCopyAddr = returnsNull ? TargetPointer.Null : new(0x2345_6789); | ||
TargetPointer syntheticMethodDescAddr = new(0x2345_8000); | ||
NativeCodeVersionHandle syntheticHandle = NativeCodeVersionHandle.CreateSynthetic(syntheticMethodDescAddr); | ||
MethodDescHandle methodDescHandle = new MethodDescHandle(syntheticMethodDescAddr); | ||
mockRTS.Setup(rts => rts.GetMethodDescHandle(syntheticMethodDescAddr)).Returns(methodDescHandle); | ||
mockRTS.Setup(rts => rts.GetGCStressCodeCopy(methodDescHandle)).Returns(expectedSyntheticCodeCopyAddr); | ||
|
||
// Setup explicit NativeCodeVersion | ||
TargetPointer? explicitGCCoverageInfoAddr = returnsNull ? TargetPointer.Null : new(0x1234_5678); | ||
TargetPointer nativeCodeVersionNode = builder.AddNativeCodeVersionNode(); | ||
builder.FillNativeCodeVersionNode( | ||
nativeCodeVersionNode, | ||
methodDesc: TargetPointer.Null, | ||
nativeCode: TargetCodePointer.Null, | ||
next: TargetPointer.Null, | ||
isActive: true, | ||
ilVersionId: new(1), | ||
gcCoverageInfo: explicitGCCoverageInfoAddr); | ||
NativeCodeVersionHandle explicitHandle = NativeCodeVersionHandle.CreateExplicit(nativeCodeVersionNode); | ||
|
||
var target = CreateTarget(arch, builder, mockRTS); | ||
var codeVersions = target.Contracts.CodeVersions; | ||
|
||
// TEST | ||
TargetPointer actualSyntheticCodeCopyAddr = codeVersions.GetGCStressCodeCopy(syntheticHandle); | ||
Assert.Equal(expectedSyntheticCodeCopyAddr, actualSyntheticCodeCopyAddr); | ||
|
||
if(returnsNull) | ||
{ | ||
TargetPointer actualExplicitCodeCopyAddr = codeVersions.GetGCStressCodeCopy(explicitHandle); | ||
Assert.Equal(TargetPointer.Null, actualExplicitCodeCopyAddr); | ||
} | ||
else | ||
{ | ||
Target.TypeInfo gcCoverageInfoType = target.GetTypeInfo(DataType.GCCoverageInfo); | ||
TargetPointer expectedExplicitCodeCopyAddr = explicitGCCoverageInfoAddr.Value + (ulong)gcCoverageInfoType.Fields["SavedCode"].Offset; | ||
TargetPointer actualExplicitCodeCopyAddr = codeVersions.GetGCStressCodeCopy(explicitHandle); | ||
Assert.Equal(expectedExplicitCodeCopyAddr, actualExplicitCodeCopyAddr); | ||
} | ||
} | ||
|
||
[Theory] | ||
[ClassData(typeof(MockTarget.StdArch))] | ||
public void GetGCStressCodeCopy_Null(MockTarget.Architecture arch) | ||
{ | ||
GetGCStressCodeCopy_Impl(arch, returnsNull: true); | ||
} | ||
|
||
[Theory] | ||
[ClassData(typeof(MockTarget.StdArch))] | ||
public void GetGCStressCodeCopy_NotNull(MockTarget.Architecture arch) | ||
{ | ||
GetGCStressCodeCopy_Impl(arch, returnsNull: false); | ||
} | ||
} |
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.
Do we want to refer to it as 'GCCoverage' or 'GCStress'? I kind of think of GC coverage as the more basic feature/info that GC stress uses. I don't feel too strongly either way.
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.
GCCoverageInfo
is a runtime type which holds state about the functions GCCoverage, including a copy of the original code before any GC points were inserted. In the runtime this field issavedCode
.The DAC type
DacpMethodDescData
has a field which should be populated with a pointer to thegcCoverageInfo.savedCode
,GCStressCodeCopy
.My preference is to use
GetGCStressCodeCopy
to mimic the DAC type and because it better describes what is actually being returned.