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
15 changes: 8 additions & 7 deletions src/coreclr/vm/method.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2022,7 +2022,7 @@ class MethodDesc
PCODE GetPrecompiledCode(PrepareCodeConfig* pConfig, bool shouldTier);
PCODE GetPrecompiledNgenCode(PrepareCodeConfig* pConfig);
PCODE GetPrecompiledR2RCode(PrepareCodeConfig* pConfig);
PCODE GetMulticoreJitCode(PrepareCodeConfig* pConfig, bool* pWasTier0Jit);
PCODE GetMulticoreJitCode(PrepareCodeConfig* pConfig, bool* pWasTier0);
COR_ILMETHOD_DECODER* GetAndVerifyILHeader(PrepareCodeConfig* pConfig, COR_ILMETHOD_DECODER* pIlDecoderMemory);
COR_ILMETHOD_DECODER* GetAndVerifyMetadataILHeader(PrepareCodeConfig* pConfig, COR_ILMETHOD_DECODER* pIlDecoderMemory);
COR_ILMETHOD_DECODER* GetAndVerifyNoMetadataILHeader();
Expand Down Expand Up @@ -2207,7 +2207,8 @@ class PrepareCodeConfig
}
}

bool FinalizeOptimizationTierForTier0Jit();
bool FinalizeOptimizationTierForTier0Load();
bool FinalizeOptimizationTierForTier0LoadOrJit();
#endif

public:
Expand Down Expand Up @@ -2299,21 +2300,21 @@ class PrepareCodeConfigBuffer
class MulticoreJitPrepareCodeConfig : public PrepareCodeConfig
{
private:
bool m_wasTier0Jit;
bool m_wasTier0;

public:
MulticoreJitPrepareCodeConfig(MethodDesc* pMethod);

bool WasTier0Jit() const
bool WasTier0() const
{
LIMITED_METHOD_CONTRACT;
return m_wasTier0Jit;
return m_wasTier0;
}

void SetWasTier0Jit()
void SetWasTier0()
{
LIMITED_METHOD_CONTRACT;
m_wasTier0Jit = true;
m_wasTier0 = true;
}

virtual BOOL SetNativeCode(PCODE pCode, PCODE * ppAlternateCodeToUse) override;
Expand Down
30 changes: 24 additions & 6 deletions src/coreclr/vm/multicorejit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -471,6 +471,7 @@ HRESULT MulticoreJitRecorder::WriteOutput(IStream * pStream)
header.shortCounters[ 8] = m_stats.m_nDelayCount;
header.shortCounters[ 9] = m_stats.m_nWalkBack;
header.shortCounters[10] = m_fAppxMode;
header.shortCounters[11] = m_stats.m_nNoJitCount;

_ASSERTE(HEADER_W_COUNTER >= 14);

Expand Down Expand Up @@ -600,14 +601,14 @@ unsigned MulticoreJitRecorder::GetOrAddModuleIndex(Module * pModule)
return slot;
}

void MulticoreJitRecorder::RecordMethodInfo(unsigned moduleIndex, MethodDesc * pMethod, bool application)
void MulticoreJitRecorder::RecordMethodInfo(unsigned moduleIndex, MethodDesc * pMethod, bool application, bool dojit)
{
LIMITED_METHOD_CONTRACT;

if (m_JitInfoArray != nullptr && m_JitInfoCount < (LONG) MAX_METHODS)
{
m_ModuleList[moduleIndex].methodCount++;
m_JitInfoArray[m_JitInfoCount++].PackMethod(moduleIndex, pMethod, application);
m_JitInfoArray[m_JitInfoCount++].PackMethod(moduleIndex, pMethod, application, dojit);
}
}

Expand Down Expand Up @@ -869,7 +870,7 @@ void MulticoreJitRecorder::PreRecordFirstMethod()
}


void MulticoreJitRecorder::RecordMethodJit(MethodDesc * pMethod, bool application)
void MulticoreJitRecorder::RecordMethodJit(MethodDesc * pMethod, bool application, bool dojit)
{
STANDARD_VM_CONTRACT;

Expand All @@ -888,7 +889,7 @@ void MulticoreJitRecorder::RecordMethodJit(MethodDesc * pMethod, bool applicatio
return;
}

RecordMethodInfo(moduleIndex, pMethod, application);
RecordMethodInfo(moduleIndex, pMethod, application, dojit);
}


Expand Down Expand Up @@ -1103,7 +1104,7 @@ MulticoreJitCodeInfo MulticoreJitRecorder::RequestMethodCode(MethodDesc * pMetho

if (!codeInfo.IsNull() && pManager->IsRecorderActive()) // recorder may be off when player is on (e.g. for Appx)
{
RecordMethodJit(pMethod, false); // JITTed by background thread, returned to application
RecordMethodJit(pMethod, false, true); // JITTed by background thread, returned to application
}

return codeInfo;
Expand Down Expand Up @@ -1434,7 +1435,24 @@ void MulticoreJitManager::RecordMethodJit(MethodDesc * pMethod)

if (m_pMulticoreJitRecorder != NULL)
{
m_pMulticoreJitRecorder->RecordMethodJit(pMethod, true);
m_pMulticoreJitRecorder->RecordMethodJit(pMethod, true, true);

if (m_pMulticoreJitRecorder->IsAtFullCapacity())
{
m_fRecorderActive = false;
}
}
}

void MulticoreJitManager::RecordMethodLoad(MethodDesc * pMethod)
{
STANDARD_VM_CONTRACT;

CrstHolder hold(& m_playerLock);

if (m_pMulticoreJitRecorder != NULL)
{
m_pMulticoreJitRecorder->RecordMethodJit(pMethod, true, false);

if (m_pMulticoreJitRecorder->IsAtFullCapacity())
{
Expand Down
10 changes: 6 additions & 4 deletions src/coreclr/vm/multicorejit.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ struct MulticoreJitPlayerStat
unsigned short m_nTotalDelay;
unsigned short m_nDelayCount;
unsigned short m_nWalkBack;
unsigned short m_nNoJitCount;

HRESULT m_hr;

Expand All @@ -84,9 +85,9 @@ class MulticoreJitCodeInfo
enum class TierInfo : TADDR
{
None = 0,
WasTier0Jit = 1 << 0,
WasTier0 = 1 << 0,
JitSwitchedToOptimized = 1 << 1,
Mask = None | WasTier0Jit | JitSwitchedToOptimized
Mask = None | WasTier0 | JitSwitchedToOptimized
};

TADDR m_entryPointAndTierInfo;
Expand Down Expand Up @@ -118,12 +119,12 @@ class MulticoreJitCodeInfo
return IsNull() ? NULL : PINSTRToPCODE(m_entryPointAndTierInfo & ~(TADDR)TierInfo::Mask);
}

bool WasTier0Jit() const
bool WasTier0() const
{
WRAPPER_NO_CONTRACT;
VerifyIsNotNull();

return (m_entryPointAndTierInfo & (TADDR)TierInfo::WasTier0Jit) != 0;
return (m_entryPointAndTierInfo & (TADDR)TierInfo::WasTier0) != 0;
}

bool JitSwitchedToOptimized() const
Expand Down Expand Up @@ -282,6 +283,7 @@ class MulticoreJitManager
MulticoreJitCodeInfo RequestMethodCode(MethodDesc * pMethod);

void RecordMethodJit(MethodDesc * pMethod);
void RecordMethodLoad(MethodDesc * pMethod);

MulticoreJitPlayerStat & GetStats()
{
Expand Down
20 changes: 13 additions & 7 deletions src/coreclr/vm/multicorejitimpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@
// Bits 0xff0000 are reserved method flags. Currently only first bit is used.
const unsigned METHOD_FLAGS_MASK = 0xff0000;
const unsigned JIT_BY_APP_THREAD_TAG = 0x10000; // tag, that indicates whether method is jitted by application thread(1) or background thread(0)
// Tags 0xfe0000 are currently free
const unsigned NO_JIT_TAG = 0x20000; // tag, that indicates whether method should be jitted or simply loaded (i.e. related types are created, etc.)
// Tags 0xfc0000 are currently free

const unsigned RECORD_TYPE_OFFSET = 24; // offset of type of record

Expand All @@ -45,7 +46,7 @@ const int MAX_WALKBACK = 128;

enum
{
MULTICOREJIT_PROFILE_VERSION = 102,
MULTICOREJIT_PROFILE_VERSION = 103,

MULTICOREJIT_HEADER_RECORD_ID = 1,
MULTICOREJIT_MODULE_RECORD_ID = 2,
Expand Down Expand Up @@ -297,8 +298,8 @@ friend class MulticoreJitRecorder;

HRESULT HandleModuleRecord(const ModuleRecord * pMod);
HRESULT HandleModuleInfoRecord(unsigned moduleTo, unsigned level);
HRESULT HandleNonGenericMethodInfoRecord(unsigned moduleIndex, unsigned token);
HRESULT HandleGenericMethodInfoRecord(unsigned moduleIndex, BYTE * signature, unsigned length);
HRESULT HandleNonGenericMethodInfoRecord(unsigned moduleIndex, unsigned token, bool dojit);
HRESULT HandleGenericMethodInfoRecord(unsigned moduleIndex, BYTE * signature, unsigned length, bool dojit);
void CompileMethodInfoRecord(Module *pModule, MethodDesc *pMethod, bool isGeneric);

bool CompileMethodDesc(Module * pModule, MethodDesc * pMD);
Expand Down Expand Up @@ -559,7 +560,7 @@ struct RecorderInfo
_ASSERTE(IsFullyInitialized());
}

void PackMethod(unsigned moduleIndex, MethodDesc * pMethod, bool application)
void PackMethod(unsigned moduleIndex, MethodDesc * pMethod, bool application, bool dojit)
{
LIMITED_METHOD_CONTRACT;

Expand All @@ -586,6 +587,11 @@ struct RecorderInfo
data1 |= JIT_BY_APP_THREAD_TAG;
}

if (!dojit)
{
data1 |= NO_JIT_TAG;
}

data2 = 0;
// To avoid recording overhead, records only pointer to MethodDesc.
ptr = (BYTE *) pMethod;
Expand Down Expand Up @@ -639,7 +645,7 @@ class MulticoreJitRecorder

HRESULT WriteModuleRecord(IStream * pStream, const RecorderModuleInfo & module);

void RecordMethodInfo(unsigned moduleIndex, MethodDesc * pMethod, bool application);
void RecordMethodInfo(unsigned moduleIndex, MethodDesc * pMethod, bool application, bool dojit);
unsigned RecordModuleInfo(Module * pModule);
void RecordOrUpdateModuleInfo(FileLoadLevel needLevel, unsigned moduleIndex);

Expand Down Expand Up @@ -710,7 +716,7 @@ class MulticoreJitRecorder
(m_ModuleCount >= MAX_MODULES);
}

void RecordMethodJit(MethodDesc * pMethod, bool application);
void RecordMethodJit(MethodDesc * pMethod, bool application, bool dojit);

MulticoreJitCodeInfo RequestMethodCode(MethodDesc * pMethod, MulticoreJitManager * pManager);

Expand Down
44 changes: 31 additions & 13 deletions src/coreclr/vm/multicorejitplayer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ void MulticoreJitCodeStorage::StoreMethodCode(MethodDesc * pMD, MulticoreJitCode
"%p %p %d %d StoredMethodCode",
pMD,
codeInfo.GetEntryPoint(),
(int)codeInfo.WasTier0Jit(),
(int)codeInfo.WasTier0(),
(int)codeInfo.JitSwitchedToOptimized()));
}
#endif
Expand Down Expand Up @@ -131,7 +131,7 @@ MulticoreJitCodeInfo MulticoreJitCodeStorage::QueryAndRemoveMethodCode(MethodDes
"%p %p %d %d QueryAndRemoveMethodCode",
pMethod,
codeInfo.GetEntryPoint(),
(int)codeInfo.WasTier0Jit(),
(int)codeInfo.WasTier0(),
(int)codeInfo.JitSwitchedToOptimized()));
}
#endif
Expand Down Expand Up @@ -521,7 +521,9 @@ HRESULT MulticoreJitProfilePlayer::HandleModuleRecord(const ModuleRecord * pMod)

#ifndef DACCESS_COMPILE
MulticoreJitPrepareCodeConfig::MulticoreJitPrepareCodeConfig(MethodDesc* pMethod) :
PrepareCodeConfig(NativeCodeVersion(pMethod), FALSE, FALSE), m_wasTier0Jit(false)
// Method code that was pregenerated and loaded is recorded in the multi-core JIT profile, so enable multi-core JIT to also
// look up pregenerated code to help parallelize the work
PrepareCodeConfig(NativeCodeVersion(pMethod), FALSE, TRUE), m_wasTier0(false)
{
WRAPPER_NO_CONTRACT;

Expand All @@ -548,9 +550,9 @@ MulticoreJitCodeInfo::MulticoreJitCodeInfo(PCODE entryPoint, const MulticoreJitP
_ASSERTE((m_entryPointAndTierInfo & (TADDR)TierInfo::Mask) == 0);

#ifdef FEATURE_TIERED_COMPILATION
if (pConfig->WasTier0Jit())
if (pConfig->WasTier0())
{
m_entryPointAndTierInfo |= (TADDR)TierInfo::WasTier0Jit;
m_entryPointAndTierInfo |= (TADDR)TierInfo::WasTier0;
}

if (pConfig->JitSwitchedToOptimized())
Expand Down Expand Up @@ -865,7 +867,7 @@ DomainAssembly * MulticoreJitProfilePlayer::LoadAssembly(SString & assemblyName)
FALSE); // Don't throw on FileNotFound.
}

HRESULT MulticoreJitProfilePlayer::HandleNonGenericMethodInfoRecord(unsigned moduleIndex, unsigned token)
HRESULT MulticoreJitProfilePlayer::HandleNonGenericMethodInfoRecord(unsigned moduleIndex, unsigned token, bool dojit)
{
STANDARD_VM_CONTRACT;

Expand All @@ -891,7 +893,14 @@ HRESULT MulticoreJitProfilePlayer::HandleNonGenericMethodInfoRecord(unsigned mod
// except it calls GetMethodDescFromMemberDefOrRefOrSpec with strictMetadataChecks=FALSE to allow generic instantiation
MethodDesc * pMethod = MemberLoader::GetMethodDescFromMemberDefOrRefOrSpec(pModule, token, NULL, FALSE, FALSE);

CompileMethodInfoRecord(pModule, pMethod, false);
if (dojit)
{
CompileMethodInfoRecord(pModule, pMethod, false);
}
else
{
m_stats.m_nNoJitCount++;
}
}
else
{
Expand All @@ -911,7 +920,7 @@ HRESULT MulticoreJitProfilePlayer::HandleNonGenericMethodInfoRecord(unsigned mod
return hr;
}

HRESULT MulticoreJitProfilePlayer::HandleGenericMethodInfoRecord(unsigned moduleIndex, BYTE * signature, unsigned length)
HRESULT MulticoreJitProfilePlayer::HandleGenericMethodInfoRecord(unsigned moduleIndex, BYTE * signature, unsigned length, bool dojit)
{
STANDARD_VM_CONTRACT;

Expand Down Expand Up @@ -945,7 +954,14 @@ HRESULT MulticoreJitProfilePlayer::HandleGenericMethodInfoRecord(unsigned module
}
EX_END_CATCH(SwallowAllExceptions);

CompileMethodInfoRecord(pModule, pMethod, true);
if (dojit)
{
CompileMethodInfoRecord(pModule, pMethod, true);
}
else
{
m_stats.m_nNoJitCount++;
}
}
else
{
Expand Down Expand Up @@ -1017,16 +1033,17 @@ void MulticoreJitProfilePlayer::TraceSummary()

unsigned compiled = curStorage.GetStored();

MulticoreJitTrace(("PlayerSummary: %d total: %d no mod, %d filtered out, %d had code, %d other, %d tried, %d compiled, %d returned, %d%% efficiency, %d mod loaded, %d ms delay(%d)",
MulticoreJitTrace(("PlayerSummary: %d total, %d no jit: %d no mod, %d filtered out, %d had code, %d other, %d tried, %d compiled, %d returned, %d%% efficiency, %d mod loaded, %d ms delay(%d)",
m_stats.m_nTotalMethod,
m_stats.m_nNoJitCount,
m_stats.m_nMissingModuleSkip,
m_stats.m_nFilteredMethods,
m_stats.m_nHasNativeCode,
m_stats.m_nTotalMethod - m_stats.m_nMissingModuleSkip - m_stats.m_nFilteredMethods - m_stats.m_nHasNativeCode - m_stats.m_nTryCompiling,
m_stats.m_nTryCompiling,
compiled,
returned,
(m_stats.m_nTotalMethod == 0) ? 100 : returned * 100 / m_stats.m_nTotalMethod,
(m_stats.m_nTotalMethod == 0) ? 100 : returned * 100 / (m_stats.m_nTotalMethod - m_stats.m_nNoJitCount),
m_nLoadedModuleCount,
m_stats.m_nTotalDelay,
m_stats.m_nDelayCount
Expand Down Expand Up @@ -1293,20 +1310,21 @@ HRESULT MulticoreJitProfilePlayer::PlayProfile()
unsigned currcdTyp = curdata1 >> RECORD_TYPE_OFFSET;
unsigned curmoduleIndex = curdata1 & MODULE_MASK;
unsigned curflags = curdata1 & METHOD_FLAGS_MASK;
bool dojit = (curflags & NO_JIT_TAG) == 0;

if (currcdTyp == MULTICOREJIT_METHOD_RECORD_ID)
{
unsigned token = * (((const unsigned *) pCurBuf) + 1);

hr = HandleNonGenericMethodInfoRecord(curmoduleIndex, token);
hr = HandleNonGenericMethodInfoRecord(curmoduleIndex, token, dojit);
}
else
{
_ASSERTE(currcdTyp == MULTICOREJIT_GENERICMETHOD_RECORD_ID);

unsigned cursignatureLength = * (const unsigned short *) (((const unsigned *) pCurBuf) + 1);

hr = HandleGenericMethodInfoRecord(curmoduleIndex, (BYTE *) (pCurBuf + sizeof(unsigned) + sizeof(unsigned short)), cursignatureLength);
hr = HandleGenericMethodInfoRecord(curmoduleIndex, (BYTE *) (pCurBuf + sizeof(unsigned) + sizeof(unsigned short)), cursignatureLength, dojit);
}

if (SUCCEEDED(hr) && ShouldAbort(false))
Expand Down
Loading