Skip to content

Commit

Permalink
probing R2R code in caller modules
Browse files Browse the repository at this point in the history
  • Loading branch information
y-yamshchikov committed Apr 5, 2021
1 parent ddb88a4 commit 660c697
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 22 deletions.
5 changes: 3 additions & 2 deletions src/coreclr/vm/codeversion.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1637,7 +1637,8 @@ PCODE CodeVersionManager::PublishVersionableCodeIfNecessary(
MethodDesc* pMethodDesc,
CallerGCMode callerGCMode,
bool *doBackpatchRef,
bool *doFullBackpatchRef)
bool *doFullBackpatchRef,
Module* pModule)
{
STANDARD_VM_CONTRACT;
_ASSERTE(!IsLockOwnedByCurrentThread());
Expand Down Expand Up @@ -1698,7 +1699,7 @@ PCODE CodeVersionManager::PublishVersionableCodeIfNecessary(

// Record the caller's GC mode.
config->SetCallerGCMode(callerGCMode);
pCode = pMethodDesc->PrepareCode(config);
pCode = pMethodDesc->PrepareCode(config, pModule);

#ifdef FEATURE_CODE_VERSIONING
if (config->ProfilerMayHaveActivatedNonDefaultCodeVersion())
Expand Down
3 changes: 2 additions & 1 deletion src/coreclr/vm/codeversion.h
Original file line number Diff line number Diff line change
Expand Up @@ -594,7 +594,8 @@ class CodeVersionManager
MethodDesc* pMethodDesc,
CallerGCMode callerGCMode,
bool *doBackpatchRef,
bool *doFullBackpatchRef);
bool *doFullBackpatchRef,
Module* pModule = NULL);
HRESULT PublishNativeCodeVersion(MethodDesc* pMethodDesc, NativeCodeVersion nativeCodeVersion);
HRESULT GetOrCreateMethodDescVersioningState(MethodDesc* pMethod, MethodDescVersioningState** ppMethodDescVersioningState);
HRESULT GetOrCreateILCodeVersioningState(Module* pModule, mdMethodDef methodDef, ILCodeVersioningState** ppILCodeVersioningState);
Expand Down
10 changes: 5 additions & 5 deletions src/coreclr/vm/method.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1792,7 +1792,7 @@ class MethodDesc
//
PCODE DoBackpatch(MethodTable * pMT, MethodTable * pDispatchingMT, BOOL fFullBackPatch);

PCODE DoPrestub(MethodTable *pDispatchingMT, CallerGCMode callerGCMode = CallerGCMode::Unknown);
PCODE DoPrestub(MethodTable *pDispatchingMT, CallerGCMode callerGCMode = CallerGCMode::Unknown, Module* pModule = NULL);

VOID GetMethodInfo(SString &namespaceOrClassName, SString &methodName, SString &methodSignature);
VOID GetMethodInfoWithNewSig(SString &namespaceOrClassName, SString &methodName, SString &methodSignature);
Expand Down Expand Up @@ -2019,13 +2019,13 @@ class MethodDesc
#ifndef DACCESS_COMPILE
public:
PCODE PrepareInitialCode(CallerGCMode callerGCMode = CallerGCMode::Unknown);
PCODE PrepareCode(PrepareCodeConfig* pConfig);
PCODE PrepareCode(PrepareCodeConfig* pConfig, Module* pModule = NULL);

private:
PCODE PrepareILBasedCode(PrepareCodeConfig* pConfig);
PCODE GetPrecompiledCode(PrepareCodeConfig* pConfig, bool shouldTier);
PCODE PrepareILBasedCode(PrepareCodeConfig* pConfig, Module* pModule = NULL);
PCODE GetPrecompiledCode(PrepareCodeConfig* pConfig, bool shouldTier, Module* pModule = NULL);
PCODE GetPrecompiledNgenCode(PrepareCodeConfig* pConfig);
PCODE GetPrecompiledR2RCode(PrepareCodeConfig* pConfig);
PCODE GetPrecompiledR2RCode(PrepareCodeConfig* pConfig, Module* pModule_probe = NULL);
PCODE GetMulticoreJitCode(PrepareCodeConfig* pConfig, bool* pWasTier0Jit);
COR_ILMETHOD_DECODER* GetAndVerifyILHeader(PrepareCodeConfig* pConfig, COR_ILMETHOD_DECODER* pIlDecoderMemory);
COR_ILMETHOD_DECODER* GetAndVerifyMetadataILHeader(PrepareCodeConfig* pConfig, COR_ILMETHOD_DECODER* pIlDecoderMemory);
Expand Down
48 changes: 34 additions & 14 deletions src/coreclr/vm/prestub.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -322,7 +322,7 @@ PCODE MethodDesc::PrepareInitialCode(CallerGCMode callerGCMode)
return PrepareCode(&config);
}

PCODE MethodDesc::PrepareCode(PrepareCodeConfig* pConfig)
PCODE MethodDesc::PrepareCode(PrepareCodeConfig* pConfig, Module* pModule)
{
STANDARD_VM_CONTRACT;

Expand All @@ -333,7 +333,7 @@ PCODE MethodDesc::PrepareCode(PrepareCodeConfig* pConfig)
// If other kinds of code need multi-versioning we could add more cases here,
// but for now generation of all other code/stubs occurs in other code paths
_ASSERTE(IsIL() || IsNoMetadata());
PCODE pCode = PrepareILBasedCode(pConfig);
PCODE pCode = PrepareILBasedCode(pConfig, pModule);

#if defined(FEATURE_GDBJIT) && defined(TARGET_UNIX) && !defined(CROSSGEN_COMPILE)
NotifyGdb::MethodPrepared(this);
Expand All @@ -356,7 +356,7 @@ bool MayUsePrecompiledILStub()
return true;
}

PCODE MethodDesc::PrepareILBasedCode(PrepareCodeConfig* pConfig)
PCODE MethodDesc::PrepareILBasedCode(PrepareCodeConfig* pConfig, Module* pModule)
{
STANDARD_VM_CONTRACT;
PCODE pCode = NULL;
Expand Down Expand Up @@ -406,7 +406,7 @@ PCODE MethodDesc::PrepareILBasedCode(PrepareCodeConfig* pConfig)
MethodDesc* pTargetMD = stubMethodDesc->GetILStubResolver()->GetStubTargetMethodDesc();
if (pTargetMD != NULL)
{
pCode = pTargetMD->GetPrecompiledR2RCode(pConfig);
pCode = pTargetMD->GetPrecompiledR2RCode(pConfig, pModule);
if (pCode != NULL)
{
LOG_USING_R2R_CODE(this);
Expand All @@ -421,7 +421,7 @@ PCODE MethodDesc::PrepareILBasedCode(PrepareCodeConfig* pConfig)

if (pCode == NULL)
{
pCode = GetPrecompiledCode(pConfig, shouldTier);
pCode = GetPrecompiledCode(pConfig, shouldTier, pModule);
}

#ifdef FEATURE_PERFMAP
Expand All @@ -447,7 +447,7 @@ PCODE MethodDesc::PrepareILBasedCode(PrepareCodeConfig* pConfig)
return pCode;
}

PCODE MethodDesc::GetPrecompiledCode(PrepareCodeConfig* pConfig, bool shouldTier)
PCODE MethodDesc::GetPrecompiledCode(PrepareCodeConfig* pConfig, bool shouldTier, Module* pModule)
{
STANDARD_VM_CONTRACT;
PCODE pCode = NULL;
Expand All @@ -465,7 +465,7 @@ PCODE MethodDesc::GetPrecompiledCode(PrepareCodeConfig* pConfig, bool shouldTier
#ifdef FEATURE_READYTORUN
else
{
pCode = GetPrecompiledR2RCode(pConfig);
pCode = GetPrecompiledR2RCode(pConfig, pModule);
if (pCode != NULL)
{
LOG_USING_R2R_CODE(this);
Expand Down Expand Up @@ -578,7 +578,7 @@ PCODE MethodDesc::GetPrecompiledNgenCode(PrepareCodeConfig* pConfig)
}


PCODE MethodDesc::GetPrecompiledR2RCode(PrepareCodeConfig* pConfig)
PCODE MethodDesc::GetPrecompiledR2RCode(PrepareCodeConfig* pConfig, Module* pModule_probe)
{
STANDARD_VM_CONTRACT;

Expand All @@ -600,6 +600,20 @@ PCODE MethodDesc::GetPrecompiledR2RCode(PrepareCodeConfig* pConfig)
{
pCode = pModule->GetReadyToRunInfo()->GetEntryPoint(this, pConfig, TRUE /* fFixups */);
}

if (!pCode)
{
if (pModule_probe)
{
if (pModule_probe->IsReadyToRun())
{
if (pModule_probe->IsInSameVersionBubble(GetModule()))
{
pCode = pModule_probe->GetReadyToRunInfo()->GetEntryPoint(this, pConfig, TRUE /* fFixups */);
}
}
}
}
}
#endif
return pCode;
Expand Down Expand Up @@ -1852,7 +1866,8 @@ extern "C" MethodDesc * STDCALL PreStubGetMethodDescForCompactEntryPoint (PCODE
static PCODE PreStubWorker_Preemptive(
_In_ TransitionBlock* pTransitionBlock,
_In_ MethodDesc* pMD,
_In_opt_ Thread* currentThread)
_In_opt_ Thread* currentThread,
Module* pModule = NULL)
{
_ASSERTE(pMD->HasUnmanagedCallersOnlyAttribute());

Expand Down Expand Up @@ -1885,7 +1900,7 @@ static PCODE PreStubWorker_Preemptive(
pMD->CheckRestore();
CONSISTENCY_CHECK(GetAppDomain()->CheckCanExecuteManagedCode(pMD));

pbRetVal = pMD->DoPrestub(NULL, CallerGCMode::Preemptive);
pbRetVal = pMD->DoPrestub(NULL, CallerGCMode::Preemptive, pModule);

UNINSTALL_UNWIND_AND_CONTINUE_HANDLER;
UNINSTALL_MANAGED_EXCEPTION_DISPATCHER;
Expand All @@ -1910,6 +1925,11 @@ extern "C" PCODE STDCALL PreStubWorker(TransitionBlock* pTransitionBlock, Method
{
PCODE pbRetVal = NULL;

Module* pModule = NULL;
FrameWithCookie<ExternalMethodFrame> frame(pTransitionBlock);
ExternalMethodFrame * pEMFrame = &frame;
pModule = ExecutionManager::FindReadyToRunModule((TADDR)(((BYTE*)pEMFrame->GetReturnAddress())-1));

BEGIN_PRESERVE_LAST_ERROR;

STATIC_CONTRACT_THROWS;
Expand All @@ -1927,7 +1947,7 @@ extern "C" PCODE STDCALL PreStubWorker(TransitionBlock* pTransitionBlock, Method
if (CURRENT_THREAD == NULL
|| !CURRENT_THREAD->PreemptiveGCDisabled())
{
pbRetVal = PreStubWorker_Preemptive(pTransitionBlock, pMD, CURRENT_THREAD);
pbRetVal = PreStubWorker_Preemptive(pTransitionBlock, pMD, CURRENT_THREAD, pModule);
}
else
{
Expand Down Expand Up @@ -1995,7 +2015,7 @@ extern "C" PCODE STDCALL PreStubWorker(TransitionBlock* pTransitionBlock, Method
auto jitWriteEnableHolder = PAL_JITWriteEnable(true);
#endif // defined(HOST_OSX) && defined(HOST_ARM64)

pbRetVal = pMD->DoPrestub(pDispatchingMT, CallerGCMode::Coop);
pbRetVal = pMD->DoPrestub(pDispatchingMT, CallerGCMode::Coop, pModule);
}

UNINSTALL_UNWIND_AND_CONTINUE_HANDLER;
Expand Down Expand Up @@ -2064,7 +2084,7 @@ static void TestSEHGuardPageRestore()
// the case of methods that require stubs to be executed first (e.g., remoted methods
// that require remoting stubs to be executed first), this stable entrypoint would be a
// pointer to the stub, and not a pointer directly to the JITted code.
PCODE MethodDesc::DoPrestub(MethodTable *pDispatchingMT, CallerGCMode callerGCMode)
PCODE MethodDesc::DoPrestub(MethodTable *pDispatchingMT, CallerGCMode callerGCMode, Module* pModule)
{
CONTRACT(PCODE)
{
Expand Down Expand Up @@ -2169,7 +2189,7 @@ PCODE MethodDesc::DoPrestub(MethodTable *pDispatchingMT, CallerGCMode callerGCMo
{
bool doBackpatch = true;
bool doFullBackpatch = false;
pCode = GetCodeVersionManager()->PublishVersionableCodeIfNecessary(this, callerGCMode, &doBackpatch, &doFullBackpatch);
pCode = GetCodeVersionManager()->PublishVersionableCodeIfNecessary(this, callerGCMode, &doBackpatch, &doFullBackpatch, pModule);

if (doBackpatch)
{
Expand Down

0 comments on commit 660c697

Please sign in to comment.