diff --git a/src/coreclr/vm/frames.h b/src/coreclr/vm/frames.h index 892e55586d7abd..fbf222baf36f8e 100644 --- a/src/coreclr/vm/frames.h +++ b/src/coreclr/vm/frames.h @@ -2134,6 +2134,21 @@ typedef DPTR(class InlinedCallFrame) PTR_InlinedCallFrame; class InlinedCallFrame : public Frame { public: + +#ifndef DACCESS_COMPILE +#ifdef FEATURE_INTERPRETER + InlinedCallFrame() : Frame(FrameIdentifier::InlinedCallFrame) + { + WRAPPER_NO_CONTRACT; + m_Datum = NULL; + m_pCallSiteSP = NULL; + m_pCallerReturnAddress = 0; + m_pCalleeSavedFP = 0; + m_pThread = NULL; + } +#endif // FEATURE_INTERPRETER +#endif // DACCESS_COMPILE + MethodDesc *GetFunction_Impl() { WRAPPER_NO_CONTRACT; diff --git a/src/coreclr/vm/interpexec.cpp b/src/coreclr/vm/interpexec.cpp index 372e8b2cfbafc6..9505ee4f5d40e5 100644 --- a/src/coreclr/vm/interpexec.cpp +++ b/src/coreclr/vm/interpexec.cpp @@ -1719,8 +1719,16 @@ void InterpExecMethod(InterpreterFrame *pInterpreterFrame, InterpMethodContextFr // Interpreter-TODO: Remove this { pInterpreterFrame->SetTopInterpMethodContextFrame(pFrame); - GCX_COOP(); - GCHeapUtilities::GetGCHeap()->GarbageCollect(-1, false, collection_blocking | collection_aggressive); + + InlinedCallFrame inlinedCallFrame; + inlinedCallFrame.m_pCallerReturnAddress = (TADDR)ip; + inlinedCallFrame.m_pCallSiteSP = pFrame; + inlinedCallFrame.m_pCalleeSavedFP = (TADDR)stack; + inlinedCallFrame.m_pThread = GetThread(); + inlinedCallFrame.m_Datum = NULL; + inlinedCallFrame.Push(); + GCInterface_Collect(-1, collection_blocking | collection_aggressive, false); + inlinedCallFrame.Pop(); } ip++; break; diff --git a/src/coreclr/vm/stackwalk.cpp b/src/coreclr/vm/stackwalk.cpp index 103aa7fe0db6db..59972a9bae0b4c 100644 --- a/src/coreclr/vm/stackwalk.cpp +++ b/src/coreclr/vm/stackwalk.cpp @@ -1053,9 +1053,6 @@ void StackFrameIterator::CommonCtor(Thread * pThread, PTR_Frame pFrame, ULONG32 m_movedPastFirstExInfo = false; m_fFuncletNotSeen = false; m_fFoundFirstFunclet = false; -#ifdef FEATURE_INTERPRETER - m_walkingInterpreterFrames = false; -#endif #if defined(RECORD_RESUMABLE_FRAME_SP) m_pvResumableFrameTargetSP = NULL; #endif @@ -2848,7 +2845,7 @@ void StackFrameIterator::ProcessCurrentFrame(void) { PREGDISPLAY pRD = m_crawl.GetRegisterSet(); - if (!m_walkingInterpreterFrames) + if (GetIP(pRD->pCurrentContext) != (TADDR)InterpreterFrame::DummyCallerIP) { // We have hit the InterpreterFrame while we were not processing the interpreter frames. // Switch to walking the underlying interpreted frames. @@ -2864,12 +2861,10 @@ void StackFrameIterator::ProcessCurrentFrame(void) pRD->pCurrentContext->ContextFlags = CONTEXT_FULL; SyncRegDisplayToCurrentContext(pRD); ProcessIp(GetControlPC(pRD)); - m_walkingInterpreterFrames = m_crawl.isFrameless; } else { // We have finished walking the interpreted frames. Process the InterpreterFrame itself. - m_walkingInterpreterFrames = false; // Restore the registers to the values they had before we started walking the interpreter frames. SetIP(pRD->pCurrentContext, m_interpExecMethodIP); SetSP(pRD->pCurrentContext, m_interpExecMethodSP); diff --git a/src/coreclr/vm/stackwalk.h b/src/coreclr/vm/stackwalk.h index ca4afa3e2df93a..6b650a277137e3 100644 --- a/src/coreclr/vm/stackwalk.h +++ b/src/coreclr/vm/stackwalk.h @@ -769,7 +769,6 @@ class StackFrameIterator // Indicates that the stack walk has moved past a funclet bool m_fFoundFirstFunclet; #ifdef FEATURE_INTERPRETER - bool m_walkingInterpreterFrames; // Saved registers of the context of the InterpExecMethod. These registers are reused for interpreter frames, // but we need to restore the original values after we are done with all the interpreted frames belonging to // that InterpExecMethod.