#ifndef DACCESS_COMPILE
NativeImageInliningIterator::NativeImageInliningIterator() :
m_pModule(NULL),
- m_pInlinee(NULL),
m_dynamicBuffer(NULL),
m_dynamicBufferSize(0),
m_dynamicAvailable(0),
}
-HRESULT NativeImageInliningIterator::Reset(Module *pModule, MethodDesc *pInlinee)
+HRESULT NativeImageInliningIterator::Reset(Module *pInlinerModule, MethodInModule inlinee)
{
- _ASSERTE(pModule != NULL);
- _ASSERTE(pInlinee != NULL);
+ _ASSERTE(pInlinerModule != NULL);
+ _ASSERTE(inlinee.m_module != NULL);
- m_pModule = pModule;
- m_pInlinee = pInlinee;
+ m_pModule = pInlinerModule;
+ m_inlinee = inlinee;
HRESULT hr = S_OK;
EX_TRY
{
// Trying to use the existing buffer
BOOL incompleteData;
- Module *inlineeModule = m_pInlinee->GetModule();
- mdMethodDef mdInlinee = m_pInlinee->GetMemberDef();
+ Module *inlineeModule = m_inlinee.m_module;
+ mdMethodDef mdInlinee = m_inlinee.m_methodDef;
COUNT_T methodsAvailable = m_pModule->GetReadyToRunInliners(inlineeModule, mdInlinee, m_dynamicBufferSize, m_dynamicBuffer, &incompleteData);
// If the existing buffer is not large enough, reallocate.
return m_currentPos < m_dynamicAvailable;
}
-MethodDesc *NativeImageInliningIterator::GetMethodDesc()
+MethodInModule NativeImageInliningIterator::GetMethod()
{
// this evaluates true when m_currentPos == s_failurePos or m_currentPos == (COUNT_T)-1
// m_currentPos is an unsigned type
if (m_currentPos >= m_dynamicAvailable)
{
- return NULL;
+ return MethodInModule();
}
- MethodInModule mm = m_dynamicBuffer[m_currentPos];
- Module *pModule = mm.m_module;
- mdMethodDef mdInliner = mm.m_methodDef;
- return pModule->LookupMethodDef(mdInliner);
+ return m_dynamicBuffer[m_currentPos];
}
//---------------------------------------------------------------------------------------
if ((flags & COR_PRF_REJIT_BLOCK_INLINING) == COR_PRF_REJIT_BLOCK_INLINING)
{
- hr = UpdateNativeInlinerActiveILVersions(&mgrToCodeActivationBatch, pMD, fIsRevert, flags);
+ hr = UpdateNativeInlinerActiveILVersions(&mgrToCodeActivationBatch, pModule, rgMethodDefs[i], fIsRevert, flags);
if (FAILED(hr))
{
return hr;
}
- hr = UpdateJitInlinerActiveILVersions(&mgrToCodeActivationBatch, pMD, fIsRevert, flags);
- if (FAILED(hr))
+ if (pMD != NULL)
{
- return hr;
+ // If pMD is not null, then the method may have already been inlined somewhere. Go check.
+ hr = UpdateJitInlinerActiveILVersions(&mgrToCodeActivationBatch, pMD, fIsRevert, flags);
+ if (FAILED(hr))
+ {
+ return hr;
+ }
}
}
} // for (ULONG i = 0; i < cFunctions; i++)
// static
HRESULT ReJitManager::UpdateNativeInlinerActiveILVersions(
SHash<CodeActivationBatchTraits> *pMgrToCodeActivationBatch,
- MethodDesc *pInlinee,
+ Module *pInlineeModule,
+ mdMethodDef inlineeMethodDef,
BOOL fIsRevert,
COR_PRF_REJIT_FLAGS flags)
{
CONTRACTL_END;
_ASSERTE(pMgrToCodeActivationBatch != NULL);
- _ASSERTE(pInlinee != NULL);
+ _ASSERTE(pInlineeModule != NULL);
+ _ASSERTE(RidFromToken(inlineeMethodDef) != 0);
HRESULT hr = S_OK;
Module * pModule = pDomainAssembly->GetModule();
if (pModule->HasReadyToRunInlineTrackingMap())
{
- inlinerIter.Reset(pModule, pInlinee);
+ inlinerIter.Reset(pModule, MethodInModule(pInlineeModule, inlineeMethodDef));
- MethodDesc *pInliner = NULL;
while (inlinerIter.Next())
{
- pInliner = inlinerIter.GetMethodDesc();
+ MethodInModule inliner = inlinerIter.GetMethod();
{
CodeVersionManager *pCodeVersionManager = pModule->GetCodeVersionManager();
CodeVersionManager::LockHolder codeVersioningLockHolder;
- ILCodeVersion ilVersion = pCodeVersionManager->GetActiveILCodeVersion(pInliner);
+ ILCodeVersion ilVersion = pCodeVersionManager->GetActiveILCodeVersion(inliner.m_module, inliner.m_methodDef);
if (!ilVersion.HasDefaultIL())
{
// This method has already been ReJITted, no need to request another ReJIT at this point.
}
}
- hr = UpdateActiveILVersion(pMgrToCodeActivationBatch, pInliner->GetModule(), pInliner->GetMemberDef(), fIsRevert, flags);
+ hr = UpdateActiveILVersion(pMgrToCodeActivationBatch, inliner.m_module, inliner.m_methodDef, fIsRevert, flags);
if (FAILED(hr))
{
- ReportReJITError(pInliner->GetModule(), pInliner->GetMemberDef(), NULL, hr);
+ ReportReJITError(inliner.m_module, inliner.m_methodDef, NULL, hr);
}
}
}
public:
NativeImageInliningIterator();
- HRESULT Reset(Module *pInlineeModule, MethodDesc *pInlinee);
+ HRESULT Reset(Module* pInlinerModule, MethodInModule inlinee);
BOOL Next();
- MethodDesc *GetMethodDesc();
+ MethodInModule GetMethod();
private:
Module *m_pModule;
- MethodDesc *m_pInlinee;
+ MethodInModule m_inlinee;
NewArrayHolder<MethodInModule> m_dynamicBuffer;
COUNT_T m_dynamicBufferSize;
COUNT_T m_dynamicAvailable;
static HRESULT UpdateNativeInlinerActiveILVersions(
SHash<CodeActivationBatchTraits> *pMgrToCodeActivationBatch,
- MethodDesc *pInlinee,
+ Module *pInlineeModule,
+ mdMethodDef inlineeMethodDef,
BOOL fIsRevert,
COR_PRF_REJIT_FLAGS flags);
COR_PRF_METHOD method;
while (pEnum->Next(1, &method, NULL) == S_OK)
{
- FunctionID inlinerFuncId = GetFunctionIDFromToken(method.moduleId, method.methodId);
+ FunctionID inlinerFuncId = GetFunctionIDFromToken(method.moduleId, method.methodId, true);
- // GetFunctionIDFromToken doesn't handle generics, will return NULL
+ // GetFunctionIDFromToken doesn't handle generics or not yet loaded methods, will return NULL
if (inlinerFuncId != mdTokenNil)
{
AddInlining(inlinerFuncId, functionId);
}
+ else
+ {
+ String calleeName = GetFunctionIDName(functionId);
+ String moduleName = GetModuleIDName(GetModuleIDForFunction(functionId));
+ String inlinerModuleId = GetModuleIDName(method.moduleId);
+ INFO(L"Inlining occurred, but name could not be resolved! Inliner=ModuleId=" << inlinerModuleId << L" Token=" << std::hex << method.methodId << L", Inlinee=" << calleeName << L" Inlinee module name=" << moduleName);
+ }
}
}
{
SHUTDOWNGUARD();
- INFO(L"Starting to build IL for method " << GetFunctionIDName(GetFunctionIDFromToken(moduleId, methodId)));
+ INFO(L"Starting to build IL for method " << GetFunctionIDName(GetFunctionIDFromToken(moduleId, methodId, false)));
COMPtrHolder<IUnknown> pUnk;
HRESULT hr = _profInfo10->GetModuleMetaData(moduleId, ofWrite, IID_IMetaDataEmit2, &pUnk);
if (FAILED(hr))
INFO(L"Inlining occurred! Inliner=" << GetFunctionIDName(inliner) << L" Inlinee=" << calleeName << L" Inlinee module name=" << moduleName);
}
-FunctionID ReJITProfiler::GetFunctionIDFromToken(ModuleID module, mdMethodDef token)
+FunctionID ReJITProfiler::GetFunctionIDFromToken(ModuleID module, mdMethodDef token, bool invalidArgNotFailure)
{
HRESULT hr = S_OK;
FunctionID functionId;
- if (FAILED(hr = pCorProfilerInfo->GetFunctionFromToken(module,
- token,
- &functionId)))
+ hr = pCorProfilerInfo->GetFunctionFromToken(module,
+ token,
+ &functionId);
+
+ if (invalidArgNotFailure && hr == E_INVALIDARG)
+ {
+ printf("Call to GetFunctionFromToken failed with E_INVALIDARG, this may be caused by the method not yet being loaded\n");
+ return mdTokenNil;
+ }
+
+ if (FAILED(hr))
{
printf("Call to GetFunctionFromToken failed with hr=0x%x\n", hr);
_failures++;
}
[MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
- private static void InlineeTarget()
+ public static void InlineeTarget()
{
Console.WriteLine("Inline.InlineeTarget");
}
profileeOptions: ProfileeOptions.OptimizationSensitive);
}
}
+
+ public class SeparateClassNeverLoaded
+ {
+ [MethodImplAttribute(MethodImplOptions.NoInlining)]
+ private static void TriggerInliningChain()
+ {
+ Console.WriteLine("TriggerInlining");
+ // Test Inlining through another method
+ InlineeChain1();
+ }
+
+ [MethodImplAttribute(MethodImplOptions.NoInlining)]
+ private static void TriggerDirectInlining()
+ {
+ Console.WriteLine("TriggerDirectInlining");
+ RejitWithInlining.InlineeTarget();
+ }
+
+ [MethodImplAttribute(MethodImplOptions.AggressiveInlining)]
+ private static void InlineeChain1()
+ {
+ Console.WriteLine("Inline.InlineeChain1");
+ RejitWithInlining.InlineeTarget();
+ }
+ }
}