Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is again a linear search through all loaded assemblies before JITing every method.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it be a suitable approach to improve FindReadyToRunModule to do O(log(N)) or even O(1) search on some structured cache?


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