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

Code before:
// Called be ETW::MethodLog::SendEventsForJitMethods
// Sends the ETW events once our caller determines whether or not rejit locks can be acquired
VOID ETW::MethodLog::SendEventsForJitMethodsHelper(LoaderAllocator *pLoaderAllocatorFilter,
                                                   DWORD dwEventOptions,
                                                   BOOL fLoadOrDCStart,
                                                   BOOL fUnloadOrDCEnd,
                                                   BOOL fSendMethodEvent,
                                                   BOOL fSendILToNativeMapEvent,
                                                   BOOL fSendRichDebugInfoEvent,
                                                   BOOL fGetCodeIds)
{
    CONTRACTL{
        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
        :   ExecutionManager::GetInterpreterJitManager()->GetCodeHeapIterator(pLoaderAllocatorFilter)
#endif
            ;
        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

Review comment (refactor):
Nit: Maybe this change could be simplified by extracting the loop logic into a method just holding the while loop and then call that method from this method? Then the logic in this method won't need the loop but instead just do direct call to the internal method like:

```
SendEventsForJitMethodsHelper2(ExecutionManager::GetEEJitManager(), ....);
#ifdef FEATURE_INTERPRETER
SendEventsForJitMethodsHelper2(ExecutionManager::GetInterpreterJitManager(), ....);
#endif
```

Just a thought.

Code after:
// Called be ETW::MethodLog::SendEventsForJitMethods
// Sends the ETW events once our caller determines whether or not rejit locks can be acquired
VOID ETW::MethodLog::SendEventsForJitMethodsHelper(LoaderAllocator *pLoaderAllocatorFilter,
                                                   DWORD dwEventOptions,
                                                   BOOL fLoadOrDCStart,
                                                   BOOL fUnloadOrDCEnd,
                                                   BOOL fSendMethodEvent,
                                                   BOOL fSendILToNativeMapEvent,
                                                   BOOL fSendRichDebugInfoEvent,
                                                   BOOL fGetCodeIds)
{
    _ASSERTE(pLoaderAllocatorFilter == nullptr || pLoaderAllocatorFilter->IsCollectible());
    _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{