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

Use native code slot for default interface methods #25770

Merged
merged 1 commit into from Aug 19, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
19 changes: 13 additions & 6 deletions src/debug/ee/functioninfo.cpp
Expand Up @@ -1603,13 +1603,20 @@ DebuggerJitInfo *DebuggerMethodInfo::FindOrCreateInitAndAddJitInfo(MethodDesc* f
// The DJI may already be populated in the cache, if so CreateInitAndAddJitInfo is a no-op and that is fine.
// CreateInitAndAddJitInfo takes a lock and checks the list again, which makes this thread-safe.

CodeVersionManager::TableLockHolder lockHolder(fd->GetCodeVersionManager());
CodeVersionManager *pCodeVersionManager = fd->GetCodeVersionManager();
NativeCodeVersion nativeCodeVersion = pCodeVersionManager->GetNativeCodeVersion(fd, startAddr);

// Some day we'll get EnC to use code versioning properly, but until then we'll get the right behavior treating all EnC versions as the default native code version.
if (nativeCodeVersion.IsNull())
NativeCodeVersion nativeCodeVersion;
if (fd->IsVersionable())
{
CodeVersionManager::TableLockHolder lockHolder(fd->GetCodeVersionManager());
CodeVersionManager *pCodeVersionManager = fd->GetCodeVersionManager();
nativeCodeVersion = pCodeVersionManager->GetNativeCodeVersion(fd, startAddr);
if (nativeCodeVersion.IsNull())
{
return NULL;
}
}
else
{
// Some day we'll get EnC to use code versioning properly, but until then we'll get the right behavior treating all EnC versions as the default native code version.
nativeCodeVersion = NativeCodeVersion(fd);
}

Expand Down
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
2 changes: 1 addition & 1 deletion src/vm/eventtrace.cpp
Expand Up @@ -6901,7 +6901,7 @@ VOID ETW::MethodLog::SendEventsForJitMethodsHelper(LoaderAllocator *pLoaderAlloc
ReJITID ilCodeId = 0;
NativeCodeVersion nativeCodeVersion;
#ifdef FEATURE_CODE_VERSIONING
if (fGetCodeIds)
if (fGetCodeIds && pMD->IsVersionable())
{
CodeVersionManager *pCodeVersionManager = pMD->GetCodeVersionManager();
_ASSERTE(pCodeVersionManager->LockOwnedByCurrentThread());
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
12 changes: 7 additions & 5 deletions src/vm/jitinterface.cpp
Expand Up @@ -14283,12 +14283,14 @@ NativeCodeVersion EECodeInfo::GetNativeCodeVersion()
}

#ifdef FEATURE_CODE_VERSIONING
CodeVersionManager *pCodeVersionManager = pMD->GetCodeVersionManager();
CodeVersionManager::TableLockHolder lockHolder(pCodeVersionManager);
return pCodeVersionManager->GetNativeCodeVersion(pMD, PINSTRToPCODE(GetStartAddress()));
#else
return NativeCodeVersion(pMD);
if (pMD->IsVersionable())
{
CodeVersionManager *pCodeVersionManager = pMD->GetCodeVersionManager();
CodeVersionManager::TableLockHolder lockHolder(pCodeVersionManager);
return pCodeVersionManager->GetNativeCodeVersion(pMD, PINSTRToPCODE(GetStartAddress()));
}
#endif
return NativeCodeVersion(pMD);
}

#if defined(WIN64EXCEPTIONS)
Expand Down
10 changes: 4 additions & 6 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 @@ -2528,7 +2529,7 @@ BOOL MethodDesc::MayHaveNativeCode()

_ASSERTE(IsIL());

if ((IsInterface() && !IsStatic() && IsVirtual() && IsAbstract()) || IsWrapperStub() || ContainsGenericVariables() || IsAbstract())
if (IsWrapperStub() || ContainsGenericVariables() || IsAbstract())
{
return FALSE;
}
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