Repository: dotnet/runtime
File: src/coreclr/vm/eventtrace.cpp (C++)

Code before:
        THROWS;
        GC_NOTRIGGER;
    } CONTRACTL_END;

    _ASSERTE(pLoaderAllocatorFilter == nullptr || pLoaderAllocatorFilter->IsCollectible());
    _ASSERTE(pLoaderAllocatorFilter == nullptr || !fGetCodeIds);

    // Set of methods for which we already have sent a MethodDetails event.
    // Only used when sending rich debug info that would otherwise send a lot
    // of duplicate events.
    MethodDescSet sentMethodDetailsSet;
    MethodDescSet* pSentMethodDetailsSet = fSendRichDebugInfoEvent ? &sentMethodDetailsSet : NULL;

#ifdef FEATURE_INTERPRETER
    for (int i = 0; i < 2; i++)
#endif // FEATURE_INTERPRETER
    {
        CodeHeapIterator heapIterator = 
#ifdef FEATURE_INTERPRETER
        (i == 0) ?
#endif
            ExecutionManager::GetEEJitManager()->GetCodeHeapIterator(pLoaderAllocatorFilter)
#ifdef FEATURE_INTERPRETER
        :
#endif
            ExecutionManager::GetInterpreterJitManager()->GetCodeHeapIterator(pLoaderAllocatorFilter);
        while (heapIterator.Next())
        {
            MethodDesc * pMD = heapIterator.GetMethod();
            if (pMD == NULL)
                continue;

            PCODE codeStart = PINSTRToPCODE(heapIterator.GetMethodCode());

#ifdef FEATURE_INTERPRETER
            // Interpreter-TODO - If the code for this was generated by the interpreter, the native
            // code start which will match up with the NativeCodeVersion/GetNativeCode result is the
            // IntepreterPrecode, which is not what is found in the NativeCode portion of the MethodDesc
            // or in the NativeCodeVersion. So we should build out the ability to get the right result
            // as otherwise we will continue through the loop and skip all the interpreter data.
#endif // FEATURE_INTERPRETER

            // Get info relevant to the native code version. In some cases, such as collectible loader
            // allocators, we don't support code versioning so we need to short circuit the call.
            // This also allows our caller to avoid having to pre-enter the relevant locks.
            // see code:#TableLockHolder
            DWORD nativeCodeVersionId = 0;
            ReJITID ilCodeId = 0;
            NativeCodeVersion nativeCodeVersion;
#ifdef FEATURE_CODE_VERSIONING
            if (fGetCodeIds && pMD->IsVersionable())

Review comment (bug):
When FEATURE_INTERPRETER is not defined, the ternary operator starting on line 4999 becomes syntactically incorrect. The code would expand to just the first branch without the conditional, resulting in a compilation error. The entire ternary expression (lines 4997-5005) needs to be wrapped in FEATURE_INTERPRETER guards, or restructured to use if/else statements that properly handle both FEATURE_INTERPRETER being defined and undefined.

Code after:
    _ASSERTE(pLoaderAllocatorFilter == nullptr || !fGetCodeIds);

#ifdef FEATURE_JIT
    SendEventsForJitMethodsHelper2(
        ExecutionManager::GetEEJitManager()->GetCodeHeapIterator(pLoaderAllocatorFilter),
        dwEventOptions,
        fLoadOrDCStart,
        fUnloadOrDCEnd,
        fSendMethodEvent,
        fSendILToNativeMapEvent,
        fSendRichDebugInfoEvent,
        fGetCodeIds);
#endif // FEATURE_JIT

#ifdef FEATURE_INTERPRETER
    SendEventsForJitMethodsHelper2(
        ExecutionManager::GetInterpreterJitManager()->GetCodeHeapIterator(pLoaderAllocatorFilter),
        dwEventOptions,
        fLoadOrDCStart,
        fUnloadOrDCEnd,
        fSendMethodEvent,
        fSendILToNativeMapEvent,
        fSendRichDebugInfoEvent,
        fGetCodeIds);
#endif // FEATURE_INTERPRETER
}
// Called be ETW::MethodLog::SendEventsForJitMethods
// Sends the ETW events once our caller determines whether or not rejit locks can be acquired
VOID ETW::MethodLog::SendEventsForJitMethodsHelper2(
                                                   CodeHeapIterator heapIterator,
                                                   DWORD dwEventOptions,
                                                   BOOL fLoadOrDCStart,
                                                   BOOL fUnloadOrDCEnd,
                                                   BOOL fSendMethodEvent,
                                                   BOOL fSendILToNativeMapEvent,
                                                   BOOL fSendRichDebugInfoEvent,
                                                   BOOL fGetCodeIds)
{
    CONTRACTL{
        THROWS;
        GC_NOTRIGGER;
    } CONTRACTL_END;

    // Set of methods for which we already have sent a MethodDetails event.
    // Only used when sending rich debug info that would otherwise send a lot
    // of duplicate events.
    MethodDescSet sentMethodDetailsSet;
    MethodDescSet* pSentMethodDetailsSet = fSendRichDebugInfoEvent ? &sentMethodDetailsSet : NULL;

    while (heapIterator.Next())
    {