Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.

Commit 1d4fd4a

Browse files
authored
[3.1] Use native code slot for default interface methods (#25770) (#28153)
- Partial port of #25770 to 3.1 (only the main change, excludes unrelated cleanup) - Use native code slot for default interface methods so that `MethodDesc::GetNativeCode()` can retrieve the current native code entry point (instead of returning null as before), and code versioning can find a matching code version from the code start address - Interface methods currently require having a precode, so the "method entry point" can't be used to directly store the native code entry point - Reenabled a couple of default interface method tests under GCStress Fixes https://github.com/dotnet/coreclr/issues/25690
1 parent 3800437 commit 1d4fd4a

File tree

6 files changed

+24
-12
lines changed

6 files changed

+24
-12
lines changed

src/vm/codeversion.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,7 @@ void NativeCodeVersionNode::SetGCCoverageInfo(PTR_GCCoverageInfo gcCover)
200200
#endif // HAVE_GCCOVER
201201

202202
NativeCodeVersion::NativeCodeVersion() :
203-
m_storageKind(StorageKind::Unknown)
203+
m_storageKind(StorageKind::Unknown), m_pVersionNode(PTR_NULL)
204204
{}
205205

206206
NativeCodeVersion::NativeCodeVersion(const NativeCodeVersion & rhs) :

src/vm/gccover.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1315,7 +1315,9 @@ bool IsGcCoverageInterrupt(LPVOID ip)
13151315
return false;
13161316
}
13171317

1318-
GCCoverageInfo *gcCover = codeInfo.GetNativeCodeVersion().GetGCCoverageInfo();
1318+
NativeCodeVersion nativeCodeVersion = codeInfo.GetNativeCodeVersion();
1319+
_ASSERTE(!nativeCodeVersion.IsNull());
1320+
GCCoverageInfo *gcCover = nativeCodeVersion.GetGCCoverageInfo();
13191321
if (gcCover == nullptr)
13201322
{
13211323
return false;
@@ -1377,7 +1379,9 @@ BOOL OnGcCoverageInterrupt(PCONTEXT regs)
13771379
forceStack[1] = &pMD; // This is so I can see it fastchecked
13781380
forceStack[2] = &offset; // This is so I can see it fastchecked
13791381

1380-
GCCoverageInfo* gcCover = codeInfo.GetNativeCodeVersion().GetGCCoverageInfo();
1382+
NativeCodeVersion nativeCodeVersion = codeInfo.GetNativeCodeVersion();
1383+
_ASSERTE(!nativeCodeVersion.IsNull());
1384+
GCCoverageInfo* gcCover = nativeCodeVersion.GetGCCoverageInfo();
13811385
forceStack[3] = &gcCover; // This is so I can see it fastchecked
13821386
if (gcCover == 0)
13831387
return(FALSE); // we aren't doing code gcCoverage on this function

src/vm/method.cpp

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1022,6 +1022,7 @@ PCODE MethodDesc::GetNativeCode()
10221022
{
10231023
WRAPPER_NO_CONTRACT;
10241024
SUPPORTS_DAC;
1025+
_ASSERTE(!IsDefaultInterfaceMethod() || HasNativeCodeSlot());
10251026

10261027
g_IBCLogger.LogMethodDescAccess(this);
10271028

@@ -5037,6 +5038,8 @@ BOOL MethodDesc::SetNativeCodeInterlocked(PCODE addr, PCODE pExpected /*=NULL*/)
50375038
GC_NOTRIGGER;
50385039
} CONTRACTL_END;
50395040

5041+
_ASSERTE(!IsDefaultInterfaceMethod() || HasNativeCodeSlot());
5042+
50405043
if (HasNativeCodeSlot())
50415044
{
50425045
#ifdef _TARGET_ARM_
@@ -5060,11 +5063,6 @@ BOOL MethodDesc::SetNativeCodeInterlocked(PCODE addr, PCODE pExpected /*=NULL*/)
50605063
(TADDR&)value, (TADDR&)expected) == (TADDR&)expected;
50615064
}
50625065

5063-
if (IsDefaultInterfaceMethod() && HasPrecode())
5064-
{
5065-
return GetPrecode()->SetTargetInterlocked(addr);
5066-
}
5067-
50685066
_ASSERTE(pExpected == NULL);
50695067
return SetStableEntryPointInterlocked(addr);
50705068
}

src/vm/methodtablebuilder.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6973,6 +6973,20 @@ MethodTableBuilder::NeedsNativeCodeSlot(bmtMDMethod * pMDMethod)
69736973
}
69746974
#endif
69756975

6976+
#ifdef FEATURE_DEFAULT_INTERFACES
6977+
if (IsInterface())
6978+
{
6979+
DWORD attrs = pMDMethod->GetDeclAttrs();
6980+
if (!IsMdStatic(attrs) && IsMdVirtual(attrs) && !IsMdAbstract(attrs))
6981+
{
6982+
// Default interface method. Since interface methods currently need to have a precode, the native code slot will be
6983+
// used to retrieve the native code entry point, instead of getting it from the precode, which is not reliable with
6984+
// debuggers setting breakpoints.
6985+
return TRUE;
6986+
}
6987+
}
6988+
#endif
6989+
69766990
#if defined(FEATURE_JIT_PITCHING)
69776991
if ((CLRConfig::GetConfigValue(CLRConfig::INTERNAL_JitPitchEnabled) != 0) &&
69786992
(CLRConfig::GetConfigValue(CLRConfig::INTERNAL_JitPitchMemThreshold) != 0))

tests/src/Loader/classloader/DefaultInterfaceMethods/sharedgenerics/sharedgenerics_d.ilproj

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,6 @@
1515
<OutputType>Exe</OutputType>
1616
<CLRTestKind>BuildAndRun</CLRTestKind>
1717
<CLRTestPriority>0</CLRTestPriority>
18-
<!-- See https://github.com/dotnet/coreclr/issues/25690 -->
19-
<GCStressIncompatible>true</GCStressIncompatible>
2018
</PropertyGroup>
2119

2220
<ItemGroup>

tests/src/Loader/classloader/DefaultInterfaceMethods/sharedgenerics/sharedgenerics_r.ilproj

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,6 @@
1515
<OutputType>Exe</OutputType>
1616
<CLRTestKind>BuildAndRun</CLRTestKind>
1717
<CLRTestPriority>0</CLRTestPriority>
18-
<!-- See https://github.com/dotnet/coreclr/issues/25690 -->
19-
<GCStressIncompatible>true</GCStressIncompatible>
2018
</PropertyGroup>
2119

2220
<ItemGroup>

0 commit comments

Comments
 (0)