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

Jitted Code Pitching Feature implemented #10496

Merged
merged 1 commit into from
Jul 20, 2017
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions src/inc/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,10 @@ endforeach(IDL_SOURCE)
add_compile_options(-fPIC)
endif(WIN32)

if(FEATURE_JIT_PITCHING)
add_definitions(-DFEATURE_JIT_PITCHING)
endif(FEATURE_JIT_PITCHING)

# Compile *_i.cpp to lib
_add_library(corguids ${CORGUIDS_SOURCES})

Expand Down
11 changes: 11 additions & 0 deletions src/inc/clrconfigvalues.h
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,17 @@ RETAIL_CONFIG_DWORD_INFO(EXTERNAL_FinalizeOnShutdown, W("FinalizeOnShutdown"), D
//
RETAIL_CONFIG_DWORD_INFO(UNSUPPORTED_ARMEnabled, W("ARMEnabled"), (DWORD)0, "Set it to 1 to enable ARM")

//
// Jit Pitching
//
RETAIL_CONFIG_DWORD_INFO(INTERNAL_JitPitchEnabled, W("JitPitchEnabled"), (DWORD)0, "Set it to 1 to enable Jit Pitching")
RETAIL_CONFIG_DWORD_INFO(INTERNAL_JitPitchMemThreshold, W("JitPitchMemThreshold"), (DWORD)0, "Do Jit Pitching when code heap usage is larger than this (in bytes)")
RETAIL_CONFIG_DWORD_INFO(INTERNAL_JitPitchMethodSizeThreshold, W("JitPitchMethodSizeThreshold"), (DWORD)0, "Do Jit Pitching for methods whose native code size larger than this (in bytes)")
RETAIL_CONFIG_DWORD_INFO(INTERNAL_JitPitchTimeInterval, W("JitPitchTimeInterval"), (DWORD)0, "Time interval between Jit Pitchings in ms")
RETAIL_CONFIG_DWORD_INFO(INTERNAL_JitPitchPrintStat, W("JitPitchPrintStat"), (DWORD)0, "Print statistics about Jit Pitching")
RETAIL_CONFIG_DWORD_INFO(INTERNAL_JitPitchMinVal, W("JitPitchMinVal"), (DWORD)0, "Do Jit Pitching if the value of the inner counter greater than this value (for debugging purpose only)")
RETAIL_CONFIG_DWORD_INFO(INTERNAL_JitPitchMaxVal, W("JitPitchMaxVal"), (DWORD)0xffffffff, "Do Jit Pitching the value of the inner counter less then this value (for debuggin purpose only)")

//
// Assembly Loader
//
Expand Down
10 changes: 10 additions & 0 deletions src/vm/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ if(FEATURE_GDBJIT)
add_definitions(-DFEATURE_GDBJIT)
endif(FEATURE_GDBJIT)

if(FEATURE_JIT_PITCHING)
add_definitions(-DFEATURE_JIT_PITCHING)
endif(FEATURE_JIT_PITCHING)

set(VM_SOURCES_DAC_AND_WKS_COMMON
appdomain.cpp
array.cpp
Expand Down Expand Up @@ -137,6 +141,12 @@ if(FEATURE_READYTORUN)
)
endif(FEATURE_READYTORUN)

if(FEATURE_JIT_PITCHING)
list(APPEND VM_SOURCES_DAC_AND_WKS_COMMON
codepitchingmanager.cpp
)
endif(FEATURE_JIT_PITCHING)

set(VM_SOURCES_DAC
${VM_SOURCES_DAC_AND_WKS_COMMON}
contexts.cpp
Expand Down
32 changes: 19 additions & 13 deletions src/vm/codeman.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2186,7 +2186,7 @@ HeapList* EEJitManager::NewCodeHeap(CodeHeapRequestInfo *pInfo, DomainCodeHeapLi
} CONTRACT_END;

size_t initialRequestSize = pInfo->getRequestSize();
size_t minReserveSize = VIRTUAL_ALLOC_RESERVE_GRANULARITY; // ( 64 KB)
size_t minReserveSize = VIRTUAL_ALLOC_RESERVE_GRANULARITY; // ( 64 KB)

#ifdef _WIN64
if (pInfo->m_hiAddr == 0)
Expand Down Expand Up @@ -2390,12 +2390,12 @@ void* EEJitManager::allocCodeRaw(CodeHeapRequestInfo *pInfo,
{
// Let us create a new heap.

DomainCodeHeapList *pList = GetCodeHeapList(pInfo->m_pMD, pInfo->m_pAllocator);
DomainCodeHeapList *pList = GetCodeHeapList(pInfo, pInfo->m_pAllocator);
if (pList == NULL)
{
// not found so need to create the first one
pList = CreateCodeHeapList(pInfo);
_ASSERTE(pList == GetCodeHeapList(pInfo->m_pMD, pInfo->m_pAllocator));
_ASSERTE(pList == GetCodeHeapList(pInfo, pInfo->m_pAllocator));
}
_ASSERTE(pList);

Expand Down Expand Up @@ -2478,23 +2478,29 @@ CodeHeader* EEJitManager::allocCode(MethodDesc* pMD, size_t blockSize, CorJitAll

SIZE_T totalSize = blockSize;

CodeHeader * pCodeHdr = NULL;

CodeHeapRequestInfo requestInfo(pMD);
#if defined(FEATURE_JIT_PITCHING)
if (pMD && pMD->IsPitchable() && CLRConfig::GetConfigValue(CLRConfig::INTERNAL_JitPitchMethodSizeThreshold) < blockSize)
{
requestInfo.SetDynamicDomain();
}
#endif

#if defined(USE_INDIRECT_CODEHEADER)
SIZE_T realHeaderSize = offsetof(RealCodeHeader, unwindInfos[0]) + (sizeof(T_RUNTIME_FUNCTION) * nUnwindInfos);

// if this is a LCG method then we will be allocating the RealCodeHeader
// following the code so that the code block can be removed easily by
// the LCG code heap.
if (pMD->IsLCGMethod())
if (requestInfo.IsDynamicDomain())
{
totalSize = ALIGN_UP(totalSize, sizeof(void*)) + realHeaderSize;
static_assert_no_msg(CODE_SIZE_ALIGN >= sizeof(void*));
}
#endif // USE_INDIRECT_CODEHEADER

CodeHeader * pCodeHdr = NULL;

CodeHeapRequestInfo requestInfo(pMD);

// Scope the lock
{
CrstHolder ch(&m_CodeHeapCritSec);
Expand All @@ -2521,7 +2527,7 @@ CodeHeader* EEJitManager::allocCode(MethodDesc* pMD, size_t blockSize, CorJitAll
pCodeHdr = ((CodeHeader *)pCode) - 1;

#ifdef USE_INDIRECT_CODEHEADER
if (pMD->IsLCGMethod())
if (requestInfo.IsDynamicDomain())
{
pCodeHdr->SetRealCodeHeader((BYTE*)pCode + ALIGN_UP(blockSize, sizeof(void*)));
}
Expand Down Expand Up @@ -2550,7 +2556,7 @@ CodeHeader* EEJitManager::allocCode(MethodDesc* pMD, size_t blockSize, CorJitAll
RETURN(pCodeHdr);
}

EEJitManager::DomainCodeHeapList *EEJitManager::GetCodeHeapList(MethodDesc *pMD, LoaderAllocator *pAllocator, BOOL fDynamicOnly)
EEJitManager::DomainCodeHeapList *EEJitManager::GetCodeHeapList(CodeHeapRequestInfo *pInfo, LoaderAllocator *pAllocator, BOOL fDynamicOnly)
{
CONTRACTL {
NOTHROW;
Expand All @@ -2564,7 +2570,7 @@ EEJitManager::DomainCodeHeapList *EEJitManager::GetCodeHeapList(MethodDesc *pMD,

// get the appropriate list of heaps
// pMD is NULL for NGen modules during Module::LoadTokenTables
if (fDynamicOnly || (pMD != NULL && pMD->IsLCGMethod()))
if (fDynamicOnly || (pInfo != NULL && pInfo->IsDynamicDomain()))
{
ppList = m_DynamicDomainCodeHeaps.Table();
count = m_DynamicDomainCodeHeaps.Count();
Expand Down Expand Up @@ -2605,7 +2611,7 @@ HeapList* EEJitManager::GetCodeHeap(CodeHeapRequestInfo *pInfo)

// loop through the m_DomainCodeHeaps to find the AppDomain
// if not found, then create it
DomainCodeHeapList *pList = GetCodeHeapList(pInfo->m_pMD, pInfo->m_pAllocator);
DomainCodeHeapList *pList = GetCodeHeapList(pInfo, pInfo->m_pAllocator);
if (pList)
{
// Set pResult to the largest non-full HeapList
Expand Down Expand Up @@ -2726,7 +2732,7 @@ bool EEJitManager::CanUseCodeHeap(CodeHeapRequestInfo *pInfo, HeapList *pCodeHea
}
}

return retVal;
return retVal;
}

EEJitManager::DomainCodeHeapList * EEJitManager::CreateCodeHeapList(CodeHeapRequestInfo *pInfo)
Expand Down
4 changes: 3 additions & 1 deletion src/vm/codeman.h
Original file line number Diff line number Diff line change
Expand Up @@ -369,6 +369,8 @@ struct CodeHeapRequestInfo
bool m_isCollectible;

bool IsDynamicDomain() { return m_isDynamicDomain; }
void SetDynamicDomain() { m_isDynamicDomain = true; }

bool IsCollectible() { return m_isCollectible; }

size_t getRequestSize() { return m_requestSize; }
Expand Down Expand Up @@ -1095,7 +1097,7 @@ private :
size_t header, size_t blockSize, unsigned align,
HeapList ** ppCodeHeap /* Writeback, Can be null */ );

DomainCodeHeapList *GetCodeHeapList(MethodDesc *pMD, LoaderAllocator *pAllocator, BOOL fDynamicOnly = FALSE);
DomainCodeHeapList *GetCodeHeapList(CodeHeapRequestInfo *pInfo, LoaderAllocator *pAllocator, BOOL fDynamicOnly = FALSE);
DomainCodeHeapList *CreateCodeHeapList(CodeHeapRequestInfo *pInfo);
LoaderHeap* GetJitMetaHeap(MethodDesc *pMD);
#endif // !CROSSGEN_COMPILE
Expand Down
Loading