mirror of
https://github.com/VSadov/Satori.git
synced 2025-06-09 09:34:49 +09:00
Events for IL methods without IL headers (#90826)
* Events for IL methods without IL headers Dynamically generated methods like UnsafeAccessor functions are marked as IL, but don't contain an IL header. The lack of header is an indication the IL must be generated at runtime. Co-authored-by: Tlakaelel Axayakatl Ceja <tlakaelel.ceja@microsoft.com>
This commit is contained in:
parent
2efa42bc18
commit
a429b0ca4f
9 changed files with 90 additions and 79 deletions
|
@ -1253,14 +1253,19 @@ ClrDataFrame::GetLocalSig(MetaSig** sig,
|
|||
{
|
||||
// It turns out we cannot really get rid of this check. Dynamic methods
|
||||
// (including IL stubs) do not have their local sig's available after JIT time.
|
||||
if (!m_methodDesc->IsIL())
|
||||
// IL methods with dynamically generated IL (for example, UnsafeAccessors) may
|
||||
// not have an IL header.
|
||||
COR_ILMETHOD* ilHeader = m_methodDesc->IsIL()
|
||||
? m_methodDesc->GetILHeader()
|
||||
: NULL;
|
||||
if (ilHeader == NULL)
|
||||
{
|
||||
*sig = NULL;
|
||||
*count = 0;
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
COR_ILMETHOD_DECODER methodDecoder(m_methodDesc->GetILHeader());
|
||||
COR_ILMETHOD_DECODER methodDecoder(ilHeader);
|
||||
mdSignature localSig = methodDecoder.GetLocalVarSigTok() ?
|
||||
methodDecoder.GetLocalVarSigTok() : mdSignatureNil;
|
||||
if (localSig == mdSignatureNil)
|
||||
|
|
|
@ -905,7 +905,7 @@ namespace ETW
|
|||
BOOL fSendRichDebugInfoEvent,
|
||||
BOOL fGetCodeIds);
|
||||
static VOID SendEventsForNgenMethods(Module *pModule, DWORD dwEventOptions);
|
||||
static VOID SendMethodJitStartEvent(MethodDesc *pMethodDesc, SString *namespaceOrClassName=NULL, SString *methodName=NULL, SString *methodSignature=NULL);
|
||||
static VOID SendMethodJitStartEvent(MethodDesc *pMethodDesc, COR_ILMETHOD_DECODER* methodDecoder, SString *namespaceOrClassName=NULL, SString *methodName=NULL, SString *methodSignature=NULL);
|
||||
static VOID SendMethodILToNativeMapEvent(MethodDesc * pMethodDesc, DWORD dwEventOptions, PCODE pNativeCodeStartAddress, DWORD nativeCodeId, ReJITID ilCodeId);
|
||||
static VOID SendMethodRichDebugInfo(MethodDesc * pMethodDesc, PCODE pNativeCodeStartAddress, DWORD nativeCodeId, ReJITID ilCodeId, MethodDescSet* sentMethodDetailsSet);
|
||||
static VOID SendMethodEvent(MethodDesc *pMethodDesc, DWORD dwEventOptions, BOOL bIsJit, SString *namespaceOrClassName=NULL, SString *methodName=NULL, SString *methodSignature=NULL, PCODE pNativeCodeStartAddress = 0, PrepareCodeConfig *pConfig = NULL, MethodDescSet* sentMethodDetailsSet = NULL);
|
||||
|
@ -938,7 +938,7 @@ namespace ETW
|
|||
|
||||
static VOID GetR2RGetEntryPointStart(MethodDesc *pMethodDesc);
|
||||
static VOID GetR2RGetEntryPoint(MethodDesc *pMethodDesc, PCODE pEntryPoint);
|
||||
static VOID MethodJitting(MethodDesc *pMethodDesc, SString *namespaceOrClassName, SString *methodName, SString *methodSignature);
|
||||
static VOID MethodJitting(MethodDesc *pMethodDesc, COR_ILMETHOD_DECODER* methodDecoder, SString *namespaceOrClassName, SString *methodName, SString *methodSignature);
|
||||
static VOID MethodJitted(MethodDesc *pMethodDesc, SString *namespaceOrClassName, SString *methodName, SString *methodSignature, PCODE pNativeCodeStartAddress, PrepareCodeConfig *pConfig);
|
||||
static VOID SendMethodDetailsEvent(MethodDesc *pMethodDesc);
|
||||
static VOID SendNonDuplicateMethodDetailsEvent(MethodDesc* pMethodDesc, MethodDescSet* set);
|
||||
|
@ -952,7 +952,7 @@ namespace ETW
|
|||
public:
|
||||
static VOID GetR2RGetEntryPointStart(MethodDesc *pMethodDesc) {};
|
||||
static VOID GetR2RGetEntryPoint(MethodDesc *pMethodDesc, PCODE pEntryPoint) {};
|
||||
static VOID MethodJitting(MethodDesc *pMethodDesc, SString *namespaceOrClassName, SString *methodName, SString *methodSignature);
|
||||
static VOID MethodJitting(MethodDesc *pMethodDesc, COR_ILMETHOD_DECODER* methodDecoder, SString *namespaceOrClassName, SString *methodName, SString *methodSignature);
|
||||
static VOID MethodJitted(MethodDesc *pMethodDesc, SString *namespaceOrClassName, SString *methodName, SString *methodSignature, PCODE pNativeCodeStartAddress, PrepareCodeConfig *pConfig);
|
||||
static VOID StubInitialized(ULONGLONG ullHelperStartAddress, LPCWSTR pHelperName) {};
|
||||
static VOID StubsInitialized(PVOID *pHelperStartAddress, PVOID *pHelperNames, LONG ulNoOfHelpers) {};
|
||||
|
|
|
@ -12,9 +12,9 @@
|
|||
#include "switches.h"
|
||||
#include "stresslog.h"
|
||||
#include "clrhost.h"
|
||||
#include "ex.h"
|
||||
#define DONOT_DEFINE_ETW_CALLBACK
|
||||
#include "eventtracebase.h"
|
||||
#include "ex.h"
|
||||
|
||||
#if !defined(STRESS_LOG_READONLY)
|
||||
#ifdef HOST_WINDOWS
|
||||
|
|
|
@ -3555,7 +3555,7 @@ VOID ETW::MethodLog::MethodJitted(MethodDesc *pMethodDesc, SString *namespaceOrC
|
|||
/*************************************************/
|
||||
/* This is called by the runtime when method jitting started */
|
||||
/*************************************************/
|
||||
VOID ETW::MethodLog::MethodJitting(MethodDesc *pMethodDesc, SString *namespaceOrClassName, SString *methodName, SString *methodSignature)
|
||||
VOID ETW::MethodLog::MethodJitting(MethodDesc *pMethodDesc, COR_ILMETHOD_DECODER* methodDecoder, SString *namespaceOrClassName, SString *methodName, SString *methodSignature)
|
||||
{
|
||||
CONTRACTL {
|
||||
NOTHROW;
|
||||
|
@ -3570,7 +3570,7 @@ VOID ETW::MethodLog::MethodJitting(MethodDesc *pMethodDesc, SString *namespaceOr
|
|||
CLR_JIT_KEYWORD))
|
||||
{
|
||||
pMethodDesc->GetMethodInfo(*namespaceOrClassName, *methodName, *methodSignature);
|
||||
ETW::MethodLog::SendMethodJitStartEvent(pMethodDesc, namespaceOrClassName, methodName, methodSignature);
|
||||
ETW::MethodLog::SendMethodJitStartEvent(pMethodDesc, methodDecoder, namespaceOrClassName, methodName, methodSignature);
|
||||
}
|
||||
} EX_CATCH { } EX_END_CATCH(SwallowAllExceptions);
|
||||
}
|
||||
|
@ -4528,7 +4528,12 @@ VOID ETW::MethodLog::SendNonDuplicateMethodDetailsEvent(MethodDesc* pMethodDesc,
|
|||
/*****************************************************************/
|
||||
/* This routine is used to send an ETW event just before a method starts jitting*/
|
||||
/*****************************************************************/
|
||||
VOID ETW::MethodLog::SendMethodJitStartEvent(MethodDesc *pMethodDesc, SString *namespaceOrClassName, SString *methodName, SString *methodSignature)
|
||||
VOID ETW::MethodLog::SendMethodJitStartEvent(
|
||||
MethodDesc *pMethodDesc,
|
||||
COR_ILMETHOD_DECODER* methodDecoder,
|
||||
SString *namespaceOrClassName,
|
||||
SString *methodName,
|
||||
SString *methodSignature)
|
||||
{
|
||||
CONTRACTL {
|
||||
THROWS;
|
||||
|
@ -4566,15 +4571,13 @@ VOID ETW::MethodLog::SendMethodJitStartEvent(MethodDesc *pMethodDesc, SString *n
|
|||
ulMethodToken = (ULONG)0;
|
||||
}
|
||||
else
|
||||
ulMethodToken = (ULONG)pMethodDesc->GetMemberDef();
|
||||
|
||||
if(pMethodDesc->IsIL())
|
||||
{
|
||||
COR_ILMETHOD_DECODER::DecoderStatus decoderstatus = COR_ILMETHOD_DECODER::FORMAT_ERROR;
|
||||
COR_ILMETHOD_DECODER ILHeader(pMethodDesc->GetILHeader(), pMethodDesc->GetMDImport(), &decoderstatus);
|
||||
ulMethodILSize = (ULONG)ILHeader.GetCodeSize();
|
||||
ulMethodToken = (ULONG)pMethodDesc->GetMemberDef();
|
||||
}
|
||||
|
||||
if (methodDecoder != NULL)
|
||||
ulMethodILSize = methodDecoder->GetCodeSize();
|
||||
|
||||
SString tNamespace, tMethodName, tMethodSignature;
|
||||
if(!namespaceOrClassName|| !methodName|| !methodSignature || (methodName->IsEmpty() && namespaceOrClassName->IsEmpty() && methodSignature->IsEmpty()))
|
||||
{
|
||||
|
|
|
@ -12327,7 +12327,7 @@ static CorJitResult CompileMethodWithEtwWrapper(EEJitManager *jitMgr,
|
|||
|
||||
SString namespaceOrClassName, methodName, methodSignature;
|
||||
// Fire an ETW event to mark the beginning of JIT'ing
|
||||
ETW::MethodLog::MethodJitting(reinterpret_cast<MethodDesc*>(info->ftn), &namespaceOrClassName, &methodName, &methodSignature);
|
||||
ETW::MethodLog::MethodJitting(reinterpret_cast<MethodDesc*>(info->ftn), NULL, &namespaceOrClassName, &methodName, &methodSignature);
|
||||
|
||||
CorJitResult ret = jitMgr->m_jit->compileMethod(comp, info, flags, nativeEntry, nativeSizeOfCode);
|
||||
|
||||
|
|
|
@ -1819,7 +1819,7 @@ private:
|
|||
PCODE GetMulticoreJitCode(PrepareCodeConfig* pConfig, bool* pWasTier0);
|
||||
PCODE JitCompileCode(PrepareCodeConfig* pConfig);
|
||||
PCODE JitCompileCodeLockedEventWrapper(PrepareCodeConfig* pConfig, JitListLockEntry* pEntry);
|
||||
PCODE JitCompileCodeLocked(PrepareCodeConfig* pConfig, JitListLockEntry* pLockEntry, ULONG* pSizeOfCode);
|
||||
PCODE JitCompileCodeLocked(PrepareCodeConfig* pConfig, COR_ILMETHOD_DECODER* pilHeader, JitListLockEntry* pLockEntry, ULONG* pSizeOfCode);
|
||||
|
||||
public:
|
||||
bool TryGenerateUnsafeAccessor(DynamicResolver** resolver, COR_ILMETHOD_DECODER** methodILDecoder);
|
||||
|
|
|
@ -709,6 +709,53 @@ PCODE MethodDesc::JitCompileCode(PrepareCodeConfig* pConfig)
|
|||
}
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
COR_ILMETHOD_DECODER* GetAndVerifyMetadataILHeader(MethodDesc* pMD, PrepareCodeConfig* pConfig, COR_ILMETHOD_DECODER* pDecoderMemory)
|
||||
{
|
||||
STANDARD_VM_CONTRACT;
|
||||
_ASSERTE(pMD != NULL);
|
||||
_ASSERTE(!pMD->IsNoMetadata());
|
||||
_ASSERTE(pConfig != NULL);
|
||||
_ASSERTE(pDecoderMemory != NULL);
|
||||
|
||||
COR_ILMETHOD_DECODER* pHeader = NULL;
|
||||
COR_ILMETHOD* ilHeader = pConfig->GetILHeader();
|
||||
if (ilHeader == NULL)
|
||||
return NULL;
|
||||
|
||||
COR_ILMETHOD_DECODER::DecoderStatus status = COR_ILMETHOD_DECODER::FORMAT_ERROR;
|
||||
{
|
||||
// Decoder ctor can AV on a malformed method header
|
||||
AVInRuntimeImplOkayHolder AVOkay;
|
||||
pHeader = new (pDecoderMemory) COR_ILMETHOD_DECODER(ilHeader, pMD->GetMDImport(), &status);
|
||||
}
|
||||
|
||||
if (status == COR_ILMETHOD_DECODER::FORMAT_ERROR)
|
||||
COMPlusThrowHR(COR_E_BADIMAGEFORMAT, BFA_BAD_IL);
|
||||
|
||||
return pHeader;
|
||||
}
|
||||
|
||||
COR_ILMETHOD_DECODER* GetAndVerifyILHeader(MethodDesc* pMD, PrepareCodeConfig* pConfig, COR_ILMETHOD_DECODER* pIlDecoderMemory)
|
||||
{
|
||||
STANDARD_VM_CONTRACT;
|
||||
_ASSERTE(pMD != NULL);
|
||||
if (pMD->IsIL())
|
||||
{
|
||||
return GetAndVerifyMetadataILHeader(pMD, pConfig, pIlDecoderMemory);
|
||||
}
|
||||
else if (pMD->IsILStub())
|
||||
{
|
||||
ILStubResolver* pResolver = pMD->AsDynamicMethodDesc()->GetILStubResolver();
|
||||
return pResolver->GetILHeader();
|
||||
}
|
||||
|
||||
_ASSERTE(pMD->IsNoMetadata());
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
PCODE MethodDesc::JitCompileCodeLockedEventWrapper(PrepareCodeConfig* pConfig, JitListLockEntry* pEntry)
|
||||
{
|
||||
STANDARD_VM_CONTRACT;
|
||||
|
@ -759,11 +806,18 @@ PCODE MethodDesc::JitCompileCodeLockedEventWrapper(PrepareCodeConfig* pConfig, J
|
|||
}
|
||||
#endif // PROFILING_SUPPORTED
|
||||
|
||||
// The profiler may have changed the code on the callback. Need to
|
||||
// pick up the new code.
|
||||
//
|
||||
// (don't want this for OSR, need to see how it works)
|
||||
COR_ILMETHOD_DECODER ilDecoderTemp;
|
||||
COR_ILMETHOD_DECODER* pilHeader = GetAndVerifyILHeader(this, pConfig, &ilDecoderTemp);
|
||||
|
||||
if (!ETW_TRACING_CATEGORY_ENABLED(MICROSOFT_WINDOWS_DOTNETRUNTIME_PROVIDER_DOTNET_Context,
|
||||
TRACE_LEVEL_VERBOSE,
|
||||
CLR_JIT_KEYWORD))
|
||||
{
|
||||
pCode = JitCompileCodeLocked(pConfig, pEntry, &sizeOfCode);
|
||||
pCode = JitCompileCodeLocked(pConfig, pilHeader, pEntry, &sizeOfCode);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -778,12 +832,13 @@ PCODE MethodDesc::JitCompileCodeLockedEventWrapper(PrepareCodeConfig* pConfig, J
|
|||
// a small stub of native code but no native-IL mapping.
|
||||
#ifndef FEATURE_INTERPRETER
|
||||
ETW::MethodLog::MethodJitting(this,
|
||||
pilHeader,
|
||||
&namespaceOrClassName,
|
||||
&methodName,
|
||||
&methodSignature);
|
||||
#endif
|
||||
|
||||
pCode = JitCompileCodeLocked(pConfig, pEntry, &sizeOfCode);
|
||||
pCode = JitCompileCodeLocked(pConfig, pilHeader, pEntry, &sizeOfCode);
|
||||
|
||||
// Interpretted methods skip this notification
|
||||
#ifdef FEATURE_INTERPRETER
|
||||
|
@ -869,66 +924,11 @@ PCODE MethodDesc::JitCompileCodeLockedEventWrapper(PrepareCodeConfig* pConfig, J
|
|||
return pCode;
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
COR_ILMETHOD_DECODER* GetAndVerifyMetadataILHeader(MethodDesc* pMD, PrepareCodeConfig* pConfig, COR_ILMETHOD_DECODER* pDecoderMemory)
|
||||
{
|
||||
STANDARD_VM_CONTRACT;
|
||||
_ASSERTE(pMD != NULL);
|
||||
_ASSERTE(!pMD->IsNoMetadata());
|
||||
_ASSERTE(pConfig != NULL);
|
||||
_ASSERTE(pDecoderMemory != NULL);
|
||||
|
||||
COR_ILMETHOD_DECODER* pHeader = NULL;
|
||||
COR_ILMETHOD* ilHeader = pConfig->GetILHeader();
|
||||
if (ilHeader == NULL)
|
||||
return NULL;
|
||||
|
||||
COR_ILMETHOD_DECODER::DecoderStatus status = COR_ILMETHOD_DECODER::FORMAT_ERROR;
|
||||
{
|
||||
// Decoder ctor can AV on a malformed method header
|
||||
AVInRuntimeImplOkayHolder AVOkay;
|
||||
pHeader = new (pDecoderMemory) COR_ILMETHOD_DECODER(ilHeader, pMD->GetMDImport(), &status);
|
||||
}
|
||||
|
||||
if (status == COR_ILMETHOD_DECODER::FORMAT_ERROR)
|
||||
COMPlusThrowHR(COR_E_BADIMAGEFORMAT, BFA_BAD_IL);
|
||||
|
||||
return pHeader;
|
||||
}
|
||||
|
||||
COR_ILMETHOD_DECODER* GetAndVerifyILHeader(MethodDesc* pMD, PrepareCodeConfig* pConfig, COR_ILMETHOD_DECODER* pIlDecoderMemory)
|
||||
{
|
||||
STANDARD_VM_CONTRACT;
|
||||
_ASSERTE(pMD != NULL);
|
||||
if (pMD->IsIL())
|
||||
{
|
||||
return GetAndVerifyMetadataILHeader(pMD, pConfig, pIlDecoderMemory);
|
||||
}
|
||||
else if (pMD->IsILStub())
|
||||
{
|
||||
ILStubResolver* pResolver = pMD->AsDynamicMethodDesc()->GetILStubResolver();
|
||||
return pResolver->GetILHeader();
|
||||
}
|
||||
|
||||
_ASSERTE(pMD->IsNoMetadata());
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
PCODE MethodDesc::JitCompileCodeLocked(PrepareCodeConfig* pConfig, JitListLockEntry* pEntry, ULONG* pSizeOfCode)
|
||||
PCODE MethodDesc::JitCompileCodeLocked(PrepareCodeConfig* pConfig, COR_ILMETHOD_DECODER* pilHeader, JitListLockEntry* pEntry, ULONG* pSizeOfCode)
|
||||
{
|
||||
STANDARD_VM_CONTRACT;
|
||||
|
||||
PCODE pCode = NULL;
|
||||
|
||||
// The profiler may have changed the code on the callback. Need to
|
||||
// pick up the new code.
|
||||
//
|
||||
// (don't want this for OSR, need to see how it works)
|
||||
COR_ILMETHOD_DECODER ilDecoderTemp;
|
||||
COR_ILMETHOD_DECODER* pilHeader = GetAndVerifyILHeader(this, pConfig, &ilDecoderTemp);
|
||||
|
||||
CORJIT_FLAGS jitFlags;
|
||||
PCODE pOtherCode = NULL;
|
||||
|
||||
|
|
|
@ -286,7 +286,7 @@ bool AddVersionResilientHashCodeForInstruction(ILInstructionParser *parser, xxHa
|
|||
hash->Add(varValue);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case InlineVar: // 2 byte value which is token change resilient
|
||||
{
|
||||
uint16_t varValue;
|
||||
|
@ -388,6 +388,12 @@ bool GetVersionResilientILCodeHashCode(MethodDesc *pMD, int* hashCode, unsigned*
|
|||
|
||||
initLocals = (options & CORINFO_OPT_INIT_LOCALS) == CORINFO_OPT_INIT_LOCALS;
|
||||
}
|
||||
else if (!pMD->HasILHeader())
|
||||
{
|
||||
// Dynamically generated IL methods like UnsafeAccessors may not have
|
||||
// an IL header.
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
COR_ILMETHOD_DECODER header(pMD->GetILHeader(TRUE), pMD->GetMDImport(), NULL);
|
||||
|
|
|
@ -63,9 +63,6 @@
|
|||
<ExcludeList Include="$(XunitTestBinBase)/Loader/binding/tracing/BinderTracingTest.Basic/*">
|
||||
<Issue>https://github.com/dotnet/runtime/issues/57786</Issue>
|
||||
</ExcludeList>
|
||||
<ExcludeList Include="$(XunitTestBinBase)/Loader/binding/tracing/BinderTracingTest.ResolutionFlow/*">
|
||||
<Issue>https://github.com/dotnet/runtime/issues/90580</Issue>
|
||||
</ExcludeList>
|
||||
<ExcludeList Include="$(XunitTestBinBase)/Interop/MonoAPI/**">
|
||||
<Issue>CoreCLR does not implement the mono embedding API</Issue>
|
||||
</ExcludeList>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue