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

Commit

Permalink
[3.1] Use native code slot for default interface methods (#25770) (#2…
Browse files Browse the repository at this point in the history
…8153)

- 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
  • Loading branch information
kouvel committed Mar 11, 2021
1 parent 3800437 commit 1d4fd4a
Show file tree
Hide file tree
Showing 6 changed files with 24 additions and 12 deletions.
2 changes: 1 addition & 1 deletion src/vm/codeversion.cpp
Expand Up @@ -200,7 +200,7 @@ void NativeCodeVersionNode::SetGCCoverageInfo(PTR_GCCoverageInfo gcCover)
#endif // HAVE_GCCOVER

NativeCodeVersion::NativeCodeVersion() :
m_storageKind(StorageKind::Unknown)
m_storageKind(StorageKind::Unknown), m_pVersionNode(PTR_NULL)
{}

NativeCodeVersion::NativeCodeVersion(const NativeCodeVersion & rhs) :
Expand Down
8 changes: 6 additions & 2 deletions src/vm/gccover.cpp
Expand Up @@ -1315,7 +1315,9 @@ bool IsGcCoverageInterrupt(LPVOID ip)
return false;
}

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

GCCoverageInfo* gcCover = codeInfo.GetNativeCodeVersion().GetGCCoverageInfo();
NativeCodeVersion nativeCodeVersion = codeInfo.GetNativeCodeVersion();
_ASSERTE(!nativeCodeVersion.IsNull());
GCCoverageInfo* gcCover = nativeCodeVersion.GetGCCoverageInfo();
forceStack[3] = &gcCover; // This is so I can see it fastchecked
if (gcCover == 0)
return(FALSE); // we aren't doing code gcCoverage on this function
Expand Down
8 changes: 3 additions & 5 deletions src/vm/method.cpp
Expand Up @@ -1022,6 +1022,7 @@ PCODE MethodDesc::GetNativeCode()
{
WRAPPER_NO_CONTRACT;
SUPPORTS_DAC;
_ASSERTE(!IsDefaultInterfaceMethod() || HasNativeCodeSlot());

g_IBCLogger.LogMethodDescAccess(this);

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

_ASSERTE(!IsDefaultInterfaceMethod() || HasNativeCodeSlot());

if (HasNativeCodeSlot())
{
#ifdef _TARGET_ARM_
Expand All @@ -5060,11 +5063,6 @@ BOOL MethodDesc::SetNativeCodeInterlocked(PCODE addr, PCODE pExpected /*=NULL*/)
(TADDR&)value, (TADDR&)expected) == (TADDR&)expected;
}

if (IsDefaultInterfaceMethod() && HasPrecode())
{
return GetPrecode()->SetTargetInterlocked(addr);
}

_ASSERTE(pExpected == NULL);
return SetStableEntryPointInterlocked(addr);
}
Expand Down
14 changes: 14 additions & 0 deletions src/vm/methodtablebuilder.cpp
Expand Up @@ -6973,6 +6973,20 @@ MethodTableBuilder::NeedsNativeCodeSlot(bmtMDMethod * pMDMethod)
}
#endif

#ifdef FEATURE_DEFAULT_INTERFACES
if (IsInterface())
{
DWORD attrs = pMDMethod->GetDeclAttrs();
if (!IsMdStatic(attrs) && IsMdVirtual(attrs) && !IsMdAbstract(attrs))
{
// Default interface method. Since interface methods currently need to have a precode, the native code slot will be
// used to retrieve the native code entry point, instead of getting it from the precode, which is not reliable with
// debuggers setting breakpoints.
return TRUE;
}
}
#endif

#if defined(FEATURE_JIT_PITCHING)
if ((CLRConfig::GetConfigValue(CLRConfig::INTERNAL_JitPitchEnabled) != 0) &&
(CLRConfig::GetConfigValue(CLRConfig::INTERNAL_JitPitchMemThreshold) != 0))
Expand Down
Expand Up @@ -15,8 +15,6 @@
<OutputType>Exe</OutputType>
<CLRTestKind>BuildAndRun</CLRTestKind>
<CLRTestPriority>0</CLRTestPriority>
<!-- See https://github.com/dotnet/coreclr/issues/25690 -->
<GCStressIncompatible>true</GCStressIncompatible>
</PropertyGroup>

<ItemGroup>
Expand Down
Expand Up @@ -15,8 +15,6 @@
<OutputType>Exe</OutputType>
<CLRTestKind>BuildAndRun</CLRTestKind>
<CLRTestPriority>0</CLRTestPriority>
<!-- See https://github.com/dotnet/coreclr/issues/25690 -->
<GCStressIncompatible>true</GCStressIncompatible>
</PropertyGroup>

<ItemGroup>
Expand Down

0 comments on commit 1d4fd4a

Please sign in to comment.