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

Code before:
    // which calls SizeOfArgStack, which thinks it may load value types.
    // However all these will have previously been loaded.
    //
    // I'm not entirely convinced this is the best places to put this: CrawlFrame::GetExactGenericArgsToken
    // may be another option.
    ENABLE_FORBID_GC_LOADER_USE_IN_THIS_SCOPE();

    MethodDesc *pFunction = GetFunction();
    _ASSERTE (pFunction->RequiresInstArg());

    MetaSig msig(pFunction);
    ArgIterator argit (&msig);

    INT offs = argit.GetParamTypeArgOffset();

    TADDR taParamTypeArg = *PTR_TADDR(GetTransitionBlock() + offs);
    return PTR_VOID(taParamTypeArg);
}

TADDR TransitionFrame::GetAddrOfThis()
{
    WRAPPER_NO_CONTRACT;
    MethodDesc *pFunction = GetFunction();
    MetaSig msig(pFunction);
    ArgIterator argit (&msig);
    return GetTransitionBlock() + argit.GetThisOffset();
}

VASigCookie * TransitionFrame::GetVASigCookie()
{
#if defined(TARGET_X86)
    LIMITED_METHOD_CONTRACT;
    return dac_cast<PTR_VASigCookie>(
        *dac_cast<PTR_TADDR>(GetTransitionBlock() +
        sizeof(TransitionBlock)));
#else
    WRAPPER_NO_CONTRACT;
    MetaSig msig(GetFunction());
    ArgIterator argit(&msig);
    return PTR_VASigCookie(
        *dac_cast<PTR_TADDR>(GetTransitionBlock() + argit.GetVASigCookieOffset()));
#endif
}

#ifndef DACCESS_COMPILE
PrestubMethodFrame::PrestubMethodFrame(TransitionBlock * pTransitionBlock, MethodDesc * pMD)
    : FramedMethodFrame(FrameIdentifier::PrestubMethodFrame, pTransitionBlock, pMD)
{
    LIMITED_METHOD_CONTRACT;
}
#endif // #ifndef DACCESS_COMPILE

Review comment (suggestion):
The `GetAddrOfThis()` API can be called from various locations. It might be worth caching this value somewhere. The previous implementation had far less state than what is being done here.

Code after:
    // which calls SizeOfArgStack, which thinks it may load value types.
    // However all these will have previously been loaded.
    //
    // I'm not entirely convinced this is the best places to put this: CrawlFrame::GetExactGenericArgsToken
    // may be another option.
    ENABLE_FORBID_GC_LOADER_USE_IN_THIS_SCOPE();

    MethodDesc *pFunction = GetFunction();
    _ASSERTE (pFunction->RequiresInstArg());

    MetaSig msig(pFunction);
    ArgIterator argit (&msig);

    INT offs = argit.GetParamTypeArgOffset();

    TADDR taParamTypeArg = *PTR_TADDR(GetTransitionBlock() + offs);
    return PTR_VOID(taParamTypeArg);
}

TADDR TransitionFrame::GetAddrOfThis()
{
    WRAPPER_NO_CONTRACT;
    return GetTransitionBlock() + ArgIterator::GetThisOffset();
}

VASigCookie * TransitionFrame::GetVASigCookie()
{
#if defined(TARGET_X86)
    LIMITED_METHOD_CONTRACT;
    return dac_cast<PTR_VASigCookie>(
        *dac_cast<PTR_TADDR>(GetTransitionBlock() +
        sizeof(TransitionBlock)));
#else
    WRAPPER_NO_CONTRACT;
    MetaSig msig(GetFunction());
    ArgIterator argit(&msig);
    return PTR_VASigCookie(
        *dac_cast<PTR_TADDR>(GetTransitionBlock() + argit.GetVASigCookieOffset()));
#endif
}

#ifndef DACCESS_COMPILE
PrestubMethodFrame::PrestubMethodFrame(TransitionBlock * pTransitionBlock, MethodDesc * pMD)
    : FramedMethodFrame(FrameIdentifier::PrestubMethodFrame, pTransitionBlock, pMD)
{
    LIMITED_METHOD_CONTRACT;
}
#endif // #ifndef DACCESS_COMPILE

BOOL PrestubMethodFrame::TraceFrame_Impl(Thread *thread, BOOL fromPatch,
                                    TraceDestination *trace, REGDISPLAY *regs)