From 2d9199d9ad52469d587ecbf12ade3af2fcd91289 Mon Sep 17 00:00:00 2001 From: Richard L Ford Date: Wed, 8 Jul 2015 00:17:53 -0700 Subject: [PATCH] Modify conservative GC code for unaligned InlinedCallFrames When making pinvoke calls the JITs allocate InlinedCallFrames within their stack frames to record the location of the managed stack frame. These InlinedCallFrames are not necessarily 8-byte aligned. These were being used as the topStack in src/vm/gcenv.cpp, in the method GCToEEInterface::ScanStackRoots. This change checks to see if a frame is an InlinedCallFrame. If so then its GetCallSiteSP method is used to get the real top of stack. This will always be aligned. There were two problem before this change wwhen the frame was misaligned (e.g. ending with 4 or c): 1. GCToEEInterface::ScanStackRoots starts at the topStack and look at every 8-byte chunk as if it were a pointer. But if topStack is unaligned it is not really finding the pointers on the stack. 2. When it gets to the bottom the 8-byte access read the first 4 bytes ok, but the last 4 bytes go beyond mapped addresses and an access violation results. --- src/vm/gcenv.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/vm/gcenv.cpp b/src/vm/gcenv.cpp index ea7d634..963ca3a 100644 --- a/src/vm/gcenv.cpp +++ b/src/vm/gcenv.cpp @@ -511,7 +511,14 @@ VOID GCToEEInterface::ScanStackRoots(Thread * pThread, promote_func* fn, ScanCon // Since we report every thing as pinned, we don't need to run following code for relocation phase. if (sc->promotion) { - Object ** topStack = (Object **)pThread->GetFrame(); + Frame* pTopFrame = pThread->GetFrame(); + Object ** topStack = (Object **)pTopFrame; + if ((pTopFrame != ((Frame*)-1)) + && (pTopFrame->GetVTablePtr() == InlinedCallFrame::GetMethodFrameVPtr())) { + // It is an InlinedCallFrame. Get SP from it. + InlinedCallFrame* pInlinedFrame = (InlinedCallFrame*)pTopFrame; + topStack = (Object **)pInlinedFrame->GetCallSiteSP(); + } Object ** bottomStack = (Object **) pThread->GetCachedStackBase(); Object ** walk; for (walk = topStack; walk < bottomStack; walk ++) -- 2.7.4