Skip to content

Commit eafb0d6

Browse files
github-actions[bot]AaronRobinsonMSFTtlakollo
authored
[release/8.0-rc1] [release/8.0] Events for IL methods without IL headers (#92317)
* 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. * Debugger check for no IL header * Update src/coreclr/debug/daccess/stack.cpp Co-authored-by: Tlakaelel Axayakatl Ceja <[email protected]> * Review feedback * Remove redundent calls and another spot to check. * Move header include --------- Co-authored-by: Aaron R Robinson <[email protected]> Co-authored-by: Tlakaelel Axayakatl Ceja <[email protected]>
1 parent 034d27f commit eafb0d6

File tree

8 files changed

+90
-76
lines changed

8 files changed

+90
-76
lines changed

src/coreclr/debug/daccess/stack.cpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1253,14 +1253,19 @@ ClrDataFrame::GetLocalSig(MetaSig** sig,
12531253
{
12541254
// It turns out we cannot really get rid of this check. Dynamic methods
12551255
// (including IL stubs) do not have their local sig's available after JIT time.
1256-
if (!m_methodDesc->IsIL())
1256+
// IL methods with dynamically generated IL (for example, UnsafeAccessors) may
1257+
// not have an IL header.
1258+
COR_ILMETHOD* ilHeader = m_methodDesc->IsIL()
1259+
? m_methodDesc->GetILHeader()
1260+
: NULL;
1261+
if (ilHeader == NULL)
12571262
{
12581263
*sig = NULL;
12591264
*count = 0;
12601265
return E_FAIL;
12611266
}
12621267

1263-
COR_ILMETHOD_DECODER methodDecoder(m_methodDesc->GetILHeader());
1268+
COR_ILMETHOD_DECODER methodDecoder(ilHeader);
12641269
mdSignature localSig = methodDecoder.GetLocalVarSigTok() ?
12651270
methodDecoder.GetLocalVarSigTok() : mdSignatureNil;
12661271
if (localSig == mdSignatureNil)

src/coreclr/inc/eventtracebase.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -905,7 +905,7 @@ namespace ETW
905905
BOOL fSendRichDebugInfoEvent,
906906
BOOL fGetCodeIds);
907907
static VOID SendEventsForNgenMethods(Module *pModule, DWORD dwEventOptions);
908-
static VOID SendMethodJitStartEvent(MethodDesc *pMethodDesc, SString *namespaceOrClassName=NULL, SString *methodName=NULL, SString *methodSignature=NULL);
908+
static VOID SendMethodJitStartEvent(MethodDesc *pMethodDesc, COR_ILMETHOD_DECODER* methodDecoder, SString *namespaceOrClassName=NULL, SString *methodName=NULL, SString *methodSignature=NULL);
909909
static VOID SendMethodILToNativeMapEvent(MethodDesc * pMethodDesc, DWORD dwEventOptions, PCODE pNativeCodeStartAddress, DWORD nativeCodeId, ReJITID ilCodeId);
910910
static VOID SendMethodRichDebugInfo(MethodDesc * pMethodDesc, PCODE pNativeCodeStartAddress, DWORD nativeCodeId, ReJITID ilCodeId, MethodDescSet* sentMethodDetailsSet);
911911
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
938938

939939
static VOID GetR2RGetEntryPointStart(MethodDesc *pMethodDesc);
940940
static VOID GetR2RGetEntryPoint(MethodDesc *pMethodDesc, PCODE pEntryPoint);
941-
static VOID MethodJitting(MethodDesc *pMethodDesc, SString *namespaceOrClassName, SString *methodName, SString *methodSignature);
941+
static VOID MethodJitting(MethodDesc *pMethodDesc, COR_ILMETHOD_DECODER* methodDecoder, SString *namespaceOrClassName, SString *methodName, SString *methodSignature);
942942
static VOID MethodJitted(MethodDesc *pMethodDesc, SString *namespaceOrClassName, SString *methodName, SString *methodSignature, PCODE pNativeCodeStartAddress, PrepareCodeConfig *pConfig);
943943
static VOID SendMethodDetailsEvent(MethodDesc *pMethodDesc);
944944
static VOID SendNonDuplicateMethodDetailsEvent(MethodDesc* pMethodDesc, MethodDescSet* set);
@@ -952,7 +952,7 @@ namespace ETW
952952
public:
953953
static VOID GetR2RGetEntryPointStart(MethodDesc *pMethodDesc) {};
954954
static VOID GetR2RGetEntryPoint(MethodDesc *pMethodDesc, PCODE pEntryPoint) {};
955-
static VOID MethodJitting(MethodDesc *pMethodDesc, SString *namespaceOrClassName, SString *methodName, SString *methodSignature);
955+
static VOID MethodJitting(MethodDesc *pMethodDesc, COR_ILMETHOD_DECODER* methodDecoder, SString *namespaceOrClassName, SString *methodName, SString *methodSignature);
956956
static VOID MethodJitted(MethodDesc *pMethodDesc, SString *namespaceOrClassName, SString *methodName, SString *methodSignature, PCODE pNativeCodeStartAddress, PrepareCodeConfig *pConfig);
957957
static VOID StubInitialized(ULONGLONG ullHelperStartAddress, LPCWSTR pHelperName) {};
958958
static VOID StubsInitialized(PVOID *pHelperStartAddress, PVOID *pHelperNames, LONG ulNoOfHelpers) {};

src/coreclr/utilcode/stresslog.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,9 @@
1212
#include "switches.h"
1313
#include "stresslog.h"
1414
#include "clrhost.h"
15+
#include "ex.h"
1516
#define DONOT_DEFINE_ETW_CALLBACK
1617
#include "eventtracebase.h"
17-
#include "ex.h"
1818

1919
#if !defined(STRESS_LOG_READONLY)
2020
#ifdef HOST_WINDOWS

src/coreclr/vm/eventtrace.cpp

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3555,7 +3555,7 @@ VOID ETW::MethodLog::MethodJitted(MethodDesc *pMethodDesc, SString *namespaceOrC
35553555
/*************************************************/
35563556
/* This is called by the runtime when method jitting started */
35573557
/*************************************************/
3558-
VOID ETW::MethodLog::MethodJitting(MethodDesc *pMethodDesc, SString *namespaceOrClassName, SString *methodName, SString *methodSignature)
3558+
VOID ETW::MethodLog::MethodJitting(MethodDesc *pMethodDesc, COR_ILMETHOD_DECODER* methodDecoder, SString *namespaceOrClassName, SString *methodName, SString *methodSignature)
35593559
{
35603560
CONTRACTL {
35613561
NOTHROW;
@@ -3570,7 +3570,7 @@ VOID ETW::MethodLog::MethodJitting(MethodDesc *pMethodDesc, SString *namespaceOr
35703570
CLR_JIT_KEYWORD))
35713571
{
35723572
pMethodDesc->GetMethodInfo(*namespaceOrClassName, *methodName, *methodSignature);
3573-
ETW::MethodLog::SendMethodJitStartEvent(pMethodDesc, namespaceOrClassName, methodName, methodSignature);
3573+
ETW::MethodLog::SendMethodJitStartEvent(pMethodDesc, methodDecoder, namespaceOrClassName, methodName, methodSignature);
35743574
}
35753575
} EX_CATCH { } EX_END_CATCH(SwallowAllExceptions);
35763576
}
@@ -4528,7 +4528,12 @@ VOID ETW::MethodLog::SendNonDuplicateMethodDetailsEvent(MethodDesc* pMethodDesc,
45284528
/*****************************************************************/
45294529
/* This routine is used to send an ETW event just before a method starts jitting*/
45304530
/*****************************************************************/
4531-
VOID ETW::MethodLog::SendMethodJitStartEvent(MethodDesc *pMethodDesc, SString *namespaceOrClassName, SString *methodName, SString *methodSignature)
4531+
VOID ETW::MethodLog::SendMethodJitStartEvent(
4532+
MethodDesc *pMethodDesc,
4533+
COR_ILMETHOD_DECODER* methodDecoder,
4534+
SString *namespaceOrClassName,
4535+
SString *methodName,
4536+
SString *methodSignature)
45324537
{
45334538
CONTRACTL {
45344539
THROWS;
@@ -4566,15 +4571,13 @@ VOID ETW::MethodLog::SendMethodJitStartEvent(MethodDesc *pMethodDesc, SString *n
45664571
ulMethodToken = (ULONG)0;
45674572
}
45684573
else
4569-
ulMethodToken = (ULONG)pMethodDesc->GetMemberDef();
4570-
4571-
if(pMethodDesc->IsIL())
45724574
{
4573-
COR_ILMETHOD_DECODER::DecoderStatus decoderstatus = COR_ILMETHOD_DECODER::FORMAT_ERROR;
4574-
COR_ILMETHOD_DECODER ILHeader(pMethodDesc->GetILHeader(), pMethodDesc->GetMDImport(), &decoderstatus);
4575-
ulMethodILSize = (ULONG)ILHeader.GetCodeSize();
4575+
ulMethodToken = (ULONG)pMethodDesc->GetMemberDef();
45764576
}
45774577

4578+
if (methodDecoder != NULL)
4579+
ulMethodILSize = methodDecoder->GetCodeSize();
4580+
45784581
SString tNamespace, tMethodName, tMethodSignature;
45794582
if(!namespaceOrClassName|| !methodName|| !methodSignature || (methodName->IsEmpty() && namespaceOrClassName->IsEmpty() && methodSignature->IsEmpty()))
45804583
{

src/coreclr/vm/jitinterface.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12286,7 +12286,7 @@ static CorJitResult CompileMethodWithEtwWrapper(EEJitManager *jitMgr,
1228612286

1228712287
SString namespaceOrClassName, methodName, methodSignature;
1228812288
// Fire an ETW event to mark the beginning of JIT'ing
12289-
ETW::MethodLog::MethodJitting(reinterpret_cast<MethodDesc*>(info->ftn), &namespaceOrClassName, &methodName, &methodSignature);
12289+
ETW::MethodLog::MethodJitting(reinterpret_cast<MethodDesc*>(info->ftn), NULL, &namespaceOrClassName, &methodName, &methodSignature);
1229012290

1229112291
CorJitResult ret = jitMgr->m_jit->compileMethod(comp, info, flags, nativeEntry, nativeSizeOfCode);
1229212292

src/coreclr/vm/method.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1819,7 +1819,7 @@ class MethodDesc
18191819
PCODE GetMulticoreJitCode(PrepareCodeConfig* pConfig, bool* pWasTier0);
18201820
PCODE JitCompileCode(PrepareCodeConfig* pConfig);
18211821
PCODE JitCompileCodeLockedEventWrapper(PrepareCodeConfig* pConfig, JitListLockEntry* pEntry);
1822-
PCODE JitCompileCodeLocked(PrepareCodeConfig* pConfig, JitListLockEntry* pLockEntry, ULONG* pSizeOfCode);
1822+
PCODE JitCompileCodeLocked(PrepareCodeConfig* pConfig, COR_ILMETHOD_DECODER* pilHeader, JitListLockEntry* pLockEntry, ULONG* pSizeOfCode);
18231823

18241824
public:
18251825
bool TryGenerateUnsafeAccessor(DynamicResolver** resolver, COR_ILMETHOD_DECODER** methodILDecoder);

src/coreclr/vm/prestub.cpp

Lines changed: 58 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -709,6 +709,53 @@ PCODE MethodDesc::JitCompileCode(PrepareCodeConfig* pConfig)
709709
}
710710
}
711711

712+
namespace
713+
{
714+
COR_ILMETHOD_DECODER* GetAndVerifyMetadataILHeader(MethodDesc* pMD, PrepareCodeConfig* pConfig, COR_ILMETHOD_DECODER* pDecoderMemory)
715+
{
716+
STANDARD_VM_CONTRACT;
717+
_ASSERTE(pMD != NULL);
718+
_ASSERTE(!pMD->IsNoMetadata());
719+
_ASSERTE(pConfig != NULL);
720+
_ASSERTE(pDecoderMemory != NULL);
721+
722+
COR_ILMETHOD_DECODER* pHeader = NULL;
723+
COR_ILMETHOD* ilHeader = pConfig->GetILHeader();
724+
if (ilHeader == NULL)
725+
return NULL;
726+
727+
COR_ILMETHOD_DECODER::DecoderStatus status = COR_ILMETHOD_DECODER::FORMAT_ERROR;
728+
{
729+
// Decoder ctor can AV on a malformed method header
730+
AVInRuntimeImplOkayHolder AVOkay;
731+
pHeader = new (pDecoderMemory) COR_ILMETHOD_DECODER(ilHeader, pMD->GetMDImport(), &status);
732+
}
733+
734+
if (status == COR_ILMETHOD_DECODER::FORMAT_ERROR)
735+
COMPlusThrowHR(COR_E_BADIMAGEFORMAT, BFA_BAD_IL);
736+
737+
return pHeader;
738+
}
739+
740+
COR_ILMETHOD_DECODER* GetAndVerifyILHeader(MethodDesc* pMD, PrepareCodeConfig* pConfig, COR_ILMETHOD_DECODER* pIlDecoderMemory)
741+
{
742+
STANDARD_VM_CONTRACT;
743+
_ASSERTE(pMD != NULL);
744+
if (pMD->IsIL())
745+
{
746+
return GetAndVerifyMetadataILHeader(pMD, pConfig, pIlDecoderMemory);
747+
}
748+
else if (pMD->IsILStub())
749+
{
750+
ILStubResolver* pResolver = pMD->AsDynamicMethodDesc()->GetILStubResolver();
751+
return pResolver->GetILHeader();
752+
}
753+
754+
_ASSERTE(pMD->IsNoMetadata());
755+
return NULL;
756+
}
757+
}
758+
712759
PCODE MethodDesc::JitCompileCodeLockedEventWrapper(PrepareCodeConfig* pConfig, JitListLockEntry* pEntry)
713760
{
714761
STANDARD_VM_CONTRACT;
@@ -759,11 +806,18 @@ PCODE MethodDesc::JitCompileCodeLockedEventWrapper(PrepareCodeConfig* pConfig, J
759806
}
760807
#endif // PROFILING_SUPPORTED
761808

809+
// The profiler may have changed the code on the callback. Need to
810+
// pick up the new code.
811+
//
812+
// (don't want this for OSR, need to see how it works)
813+
COR_ILMETHOD_DECODER ilDecoderTemp;
814+
COR_ILMETHOD_DECODER* pilHeader = GetAndVerifyILHeader(this, pConfig, &ilDecoderTemp);
815+
762816
if (!ETW_TRACING_CATEGORY_ENABLED(MICROSOFT_WINDOWS_DOTNETRUNTIME_PROVIDER_DOTNET_Context,
763817
TRACE_LEVEL_VERBOSE,
764818
CLR_JIT_KEYWORD))
765819
{
766-
pCode = JitCompileCodeLocked(pConfig, pEntry, &sizeOfCode);
820+
pCode = JitCompileCodeLocked(pConfig, pilHeader, pEntry, &sizeOfCode);
767821
}
768822
else
769823
{
@@ -778,12 +832,13 @@ PCODE MethodDesc::JitCompileCodeLockedEventWrapper(PrepareCodeConfig* pConfig, J
778832
// a small stub of native code but no native-IL mapping.
779833
#ifndef FEATURE_INTERPRETER
780834
ETW::MethodLog::MethodJitting(this,
835+
pilHeader,
781836
&namespaceOrClassName,
782837
&methodName,
783838
&methodSignature);
784839
#endif
785840

786-
pCode = JitCompileCodeLocked(pConfig, pEntry, &sizeOfCode);
841+
pCode = JitCompileCodeLocked(pConfig, pilHeader, pEntry, &sizeOfCode);
787842

788843
// Interpretted methods skip this notification
789844
#ifdef FEATURE_INTERPRETER
@@ -869,66 +924,11 @@ PCODE MethodDesc::JitCompileCodeLockedEventWrapper(PrepareCodeConfig* pConfig, J
869924
return pCode;
870925
}
871926

872-
namespace
873-
{
874-
COR_ILMETHOD_DECODER* GetAndVerifyMetadataILHeader(MethodDesc* pMD, PrepareCodeConfig* pConfig, COR_ILMETHOD_DECODER* pDecoderMemory)
875-
{
876-
STANDARD_VM_CONTRACT;
877-
_ASSERTE(pMD != NULL);
878-
_ASSERTE(!pMD->IsNoMetadata());
879-
_ASSERTE(pConfig != NULL);
880-
_ASSERTE(pDecoderMemory != NULL);
881-
882-
COR_ILMETHOD_DECODER* pHeader = NULL;
883-
COR_ILMETHOD* ilHeader = pConfig->GetILHeader();
884-
if (ilHeader == NULL)
885-
return NULL;
886-
887-
COR_ILMETHOD_DECODER::DecoderStatus status = COR_ILMETHOD_DECODER::FORMAT_ERROR;
888-
{
889-
// Decoder ctor can AV on a malformed method header
890-
AVInRuntimeImplOkayHolder AVOkay;
891-
pHeader = new (pDecoderMemory) COR_ILMETHOD_DECODER(ilHeader, pMD->GetMDImport(), &status);
892-
}
893-
894-
if (status == COR_ILMETHOD_DECODER::FORMAT_ERROR)
895-
COMPlusThrowHR(COR_E_BADIMAGEFORMAT, BFA_BAD_IL);
896-
897-
return pHeader;
898-
}
899-
900-
COR_ILMETHOD_DECODER* GetAndVerifyILHeader(MethodDesc* pMD, PrepareCodeConfig* pConfig, COR_ILMETHOD_DECODER* pIlDecoderMemory)
901-
{
902-
STANDARD_VM_CONTRACT;
903-
_ASSERTE(pMD != NULL);
904-
if (pMD->IsIL())
905-
{
906-
return GetAndVerifyMetadataILHeader(pMD, pConfig, pIlDecoderMemory);
907-
}
908-
else if (pMD->IsILStub())
909-
{
910-
ILStubResolver* pResolver = pMD->AsDynamicMethodDesc()->GetILStubResolver();
911-
return pResolver->GetILHeader();
912-
}
913-
914-
_ASSERTE(pMD->IsNoMetadata());
915-
return NULL;
916-
}
917-
}
918-
919-
PCODE MethodDesc::JitCompileCodeLocked(PrepareCodeConfig* pConfig, JitListLockEntry* pEntry, ULONG* pSizeOfCode)
927+
PCODE MethodDesc::JitCompileCodeLocked(PrepareCodeConfig* pConfig, COR_ILMETHOD_DECODER* pilHeader, JitListLockEntry* pEntry, ULONG* pSizeOfCode)
920928
{
921929
STANDARD_VM_CONTRACT;
922930

923931
PCODE pCode = NULL;
924-
925-
// The profiler may have changed the code on the callback. Need to
926-
// pick up the new code.
927-
//
928-
// (don't want this for OSR, need to see how it works)
929-
COR_ILMETHOD_DECODER ilDecoderTemp;
930-
COR_ILMETHOD_DECODER* pilHeader = GetAndVerifyILHeader(this, pConfig, &ilDecoderTemp);
931-
932932
CORJIT_FLAGS jitFlags;
933933
PCODE pOtherCode = NULL;
934934

src/coreclr/vm/versionresilienthashcode.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -286,7 +286,7 @@ bool AddVersionResilientHashCodeForInstruction(ILInstructionParser *parser, xxHa
286286
hash->Add(varValue);
287287
break;
288288
}
289-
289+
290290
case InlineVar: // 2 byte value which is token change resilient
291291
{
292292
uint16_t varValue;
@@ -388,6 +388,12 @@ bool GetVersionResilientILCodeHashCode(MethodDesc *pMD, int* hashCode, unsigned*
388388

389389
initLocals = (options & CORINFO_OPT_INIT_LOCALS) == CORINFO_OPT_INIT_LOCALS;
390390
}
391+
else if (!pMD->HasILHeader())
392+
{
393+
// Dynamically generated IL methods like UnsafeAccessors may not have
394+
// an IL header.
395+
return false;
396+
}
391397
else
392398
{
393399
COR_ILMETHOD_DECODER header(pMD->GetILHeader(TRUE), pMD->GetMDImport(), NULL);

0 commit comments

Comments
 (0)