Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

partial fix 44948 #47269

Closed
wants to merge 1 commit into from
Closed
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
@@ -1637,7 +1637,8 @@ PCODE CodeVersionManager::PublishVersionableCodeIfNecessary(
MethodDesc* pMethodDesc,
CallerGCMode callerGCMode,
bool *doBackpatchRef,
bool *doFullBackpatchRef)
bool *doFullBackpatchRef,
Module* pModule)
{
STANDARD_VM_CONTRACT;
_ASSERTE(!IsLockOwnedByCurrentThread());
@@ -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())
3 changes: 2 additions & 1 deletion src/coreclr/vm/codeversion.h
Original file line number Diff line number Diff line change
@@ -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);
10 changes: 5 additions & 5 deletions src/coreclr/vm/method.hpp
Original file line number Diff line number Diff line change
@@ -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);
@@ -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);
48 changes: 34 additions & 14 deletions src/coreclr/vm/prestub.cpp
Original file line number Diff line number Diff line change
@@ -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;

@@ -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);
@@ -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;
@@ -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);
@@ -421,7 +421,7 @@ PCODE MethodDesc::PrepareILBasedCode(PrepareCodeConfig* pConfig)

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

#ifdef FEATURE_PERFMAP
@@ -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;
@@ -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);
@@ -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;

@@ -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;
@@ -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());

@@ -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;
@@ -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;
@@ -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
{
@@ -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;
@@ -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)
{
@@ -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)
{