Fix vs2019 optimization issue take 2 (dotnet/coreclr#27452)
authorJan Vorlicek <janvorli@microsoft.com>
Sat, 26 Oct 2019 22:47:06 +0000 (15:47 -0700)
committerJan Kotas <jkotas@microsoft.com>
Sat, 26 Oct 2019 22:47:06 +0000 (15:47 -0700)
* Revert "Fix the problem with the VS2019 fix on x86 (dotnet/coreclr#26957)"

This reverts commit dotnet/coreclr@4081d86f221e6694f0dfd13b99e0d5b1045d2e89.

* Revert "Fix issue with locals overlapping out of scope GCFrame (dotnet/coreclr#26763)"

This reverts commit dotnet/coreclr@6059e75e13593b0820e178f8baaace32c09aca6e.

* Fix VS2019 optimization issue take 2

* Stop using FrameWithCookie for GCFrame
* Removed call to SetHasPromotedBytes, the function, the field on
thread and its getter / setter as it is not used for anything.
* Updated ifdefs on GetGCFrame and GetFrame

Commit migrated from https://github.com/dotnet/coreclr/commit/d815d217f1930c4443834db41f172474953ede9b

15 files changed:
src/coreclr/src/inc/vptr_list.h
src/coreclr/src/strongname/api/common.h
src/coreclr/src/vm/common.h
src/coreclr/src/vm/exceptionhandling.cpp
src/coreclr/src/vm/exceptionhandling.h
src/coreclr/src/vm/exstate.cpp
src/coreclr/src/vm/exstate.h
src/coreclr/src/vm/frames.cpp
src/coreclr/src/vm/frames.h
src/coreclr/src/vm/gccover.cpp
src/coreclr/src/vm/gcenv.ee.cpp
src/coreclr/src/vm/i386/excepx86.cpp
src/coreclr/src/vm/olevariant.cpp
src/coreclr/src/vm/threads.cpp
src/coreclr/src/vm/threads.h

index 0476533..a50c4e2 100644 (file)
@@ -67,7 +67,6 @@ VPTR_CLASS(DebuggerExitFrame)
 VPTR_CLASS(DebuggerU2MCatchHandlerFrame)
 VPTR_CLASS(FaultingExceptionFrame)
 VPTR_CLASS(FuncEvalFrame)
-VPTR_CLASS(GCFrame)
 VPTR_CLASS(HelperMethodFrame)
 VPTR_CLASS(HelperMethodFrame_1OBJ)
 VPTR_CLASS(HelperMethodFrame_2OBJ)
index 4e16729..17c867f 100644 (file)
@@ -117,6 +117,7 @@ typedef VPTR(class EEDbgInterfaceImpl)  PTR_EEDbgInterfaceImpl;
 typedef VPTR(class DebugInfoManager)    PTR_DebugInfoManager;
 typedef DPTR(class FieldDesc)           PTR_FieldDesc;
 typedef VPTR(class Frame)               PTR_Frame;
+typedef VPTR(class GCFrame)             PTR_GCFrame;
 typedef VPTR(class ICodeManager)        PTR_ICodeManager;
 typedef VPTR(class IJitManager)         PTR_IJitManager;
 typedef DPTR(class InstMethodHashTable) PTR_InstMethodHashTable;
index 9f9b123..9909239 100644 (file)
@@ -138,6 +138,7 @@ typedef VPTR(class EEDbgInterfaceImpl)  PTR_EEDbgInterfaceImpl;
 typedef VPTR(class DebugInfoManager)    PTR_DebugInfoManager;
 typedef DPTR(class FieldDesc)           PTR_FieldDesc;
 typedef VPTR(class Frame)               PTR_Frame;
+typedef VPTR(class GCFrame)             PTR_GCFrame;
 typedef VPTR(class ICodeManager)        PTR_ICodeManager;
 typedef VPTR(class IJitManager)         PTR_IJitManager;
 typedef VPTR(struct IUnknown)           PTR_IUnknown;
index 48984c7..cd95a79 100644 (file)
@@ -4020,13 +4020,6 @@ void ExceptionTracker::ResetLimitFrame()
     m_pLimitFrame = m_pThread->GetFrame();
 }
 
-void ExceptionTracker::ResetInitialExplicitFrame()
-{
-    LIMITED_METHOD_CONTRACT;
-
-    m_pInitialExplicitFrame = m_pThread->GetFrame();
-}
-
 //
 // static
 void ExceptionTracker::ResumeExecution(
index c99f4db..3cdea90 100644 (file)
@@ -299,8 +299,6 @@ public:
         return m_pInitialExplicitFrame;
     }
 
-    void ResetInitialExplicitFrame();
-
 #ifdef FEATURE_PAL
     // Reset the range of explicit frames, the limit frame and the scanned
     // stack range before unwinding a sequence of native frames. These frames
index 79ba262..59eed33 100644 (file)
@@ -35,8 +35,6 @@ ThreadExceptionState::ThreadExceptionState()
 {
 #ifdef FEATURE_EH_FUNCLETS
     m_pCurrentTracker = NULL;
-#else
-    m_ppBottomFrameDuringUnwind = NULL;
 #endif // FEATURE_EH_FUNCLETS
 
     m_flag = TEF_None;
index 1689872..991b987 100644 (file)
@@ -25,8 +25,6 @@ class EHClauseInfo;
 
 extern StackWalkAction COMPlusUnwindCallback(CrawlFrame *pCf, ThrowCallbackType *pData);
 
-typedef DPTR(PTR_Frame)                 PTR_PTR_Frame;
-
 //
 // This class serves as a forwarding and abstraction layer for the EH subsystem.
 // Since we have two different implementations, this class is needed to unify 
@@ -160,24 +158,12 @@ public:
     }
 #else
     ExInfo                  m_currentExInfo;
-    PTR_PTR_Frame           m_ppBottomFrameDuringUnwind;
 public:
     PTR_ExInfo                 GetCurrentExceptionTracker()
     {
         LIMITED_METHOD_CONTRACT;
         return PTR_ExInfo(PTR_HOST_MEMBER_TADDR(ThreadExceptionState, this, m_currentExInfo));
     }
-
-    PTR_PTR_Frame GetPtrToBottomFrameDuringUnwind()
-    {
-        return m_ppBottomFrameDuringUnwind;
-    }
-
-    void SetPtrToBottomFrameDuringUnwind(PTR_PTR_Frame framePtr)
-    {
-        m_ppBottomFrameDuringUnwind = framePtr;
-    }
-
 #endif
 
 #ifdef FEATURE_CORRUPTING_EXCEPTIONS
index 63796d9..7d34056 100644 (file)
@@ -331,9 +331,6 @@ bool Frame::HasValidVTablePtr(Frame * pFrame)
     if (vptr == HelperMethodFrame::GetMethodFrameVPtr())
         return true;
 
-    if (vptr == GCFrame::GetMethodFrameVPtr())
-        return true;
-
     if (vptr == DebuggerSecurityCodeMarkFrame::GetMethodFrameVPtr())
         return true;
 
@@ -908,6 +905,35 @@ GCFrame::GCFrame(Thread *pThread, OBJECTREF *pObjRefs, UINT numObjRefs, BOOL may
     Init(pThread, pObjRefs, numObjRefs, maybeInterior);
 }
 
+GCFrame::~GCFrame()
+{
+    CONTRACTL
+    {
+        NOTHROW;
+        GC_NOTRIGGER;
+        MODE_ANY;
+    }
+    CONTRACTL_END;
+
+    // Do a manual switch to the GC cooperative mode instead of using the GCX_COOP_THREAD_EXISTS
+    // macro so that this function isn't slowed down by having to deal with FS:0 chain on x86 Windows.
+    BOOL wasCoop = m_pCurThread->PreemptiveGCDisabled();
+    if (!wasCoop)
+    {
+        m_pCurThread->DisablePreemptiveGC();
+    }
+
+    // When the frame is destroyed, make sure it is no longer in the
+    // frame chain managed by the Thread.
+
+    Pop();
+
+    if (!wasCoop)
+    {
+        m_pCurThread->EnablePreemptiveGC();
+    }
+}
+
 void GCFrame::Init(Thread *pThread, OBJECTREF *pObjRefs, UINT numObjRefs, BOOL maybeInterior)
 {
     CONTRACTL
@@ -946,10 +972,9 @@ void GCFrame::Init(Thread *pThread, OBJECTREF *pObjRefs, UINT numObjRefs, BOOL m
     m_pCurThread    = pThread;
     m_MaybeInterior = maybeInterior;
 
-    Frame::Push(m_pCurThread);
+    Push(m_pCurThread);
 }
 
-
 //
 // GCFrame Object Scanning
 //
@@ -986,124 +1011,49 @@ void GCFrame::GcScanRoots(promote_func *fn, ScanContext* sc)
 
 
 #ifndef DACCESS_COMPILE
-//--------------------------------------------------------------------
-// Pops the GCFrame and cancels the GC protection.
-//--------------------------------------------------------------------
-VOID GCFrame::Pop()
-{
-    WRAPPER_NO_CONTRACT;
 
-    Frame::Pop(m_pCurThread);
-#ifdef _DEBUG
-    m_pCurThread->EnableStressHeap();
-    for(UINT i = 0; i < m_numObjRefs; i++)
-        Thread::ObjectRefNew(&m_pObjRefs[i]);       // Unprotect them
-#endif
-}
-
-#ifndef CROSSGEN_COMPILE
-// GCFrame destructor removes the GCFrame from the current thread's explicit frame list.
-// This prevents issues in functions that have HELPER_METHOD_FRAME_BEGIN / END around 
-// GCPROTECT_BEGIN / END and where the C++ compiler places some local variables over 
-// the stack location of the GCFrame local variable after the variable goes out of scope. 
-GCFrame::~GCFrame()
+void GCFrame::Push(Thread *pThread)
 {
     CONTRACTL
     {
         NOTHROW;
         GC_NOTRIGGER;
-        MODE_ANY;
+        MODE_COOPERATIVE;
     }
     CONTRACTL_END;
 
-    if (m_Next != NULL)
-    {
-        // Do a manual switch to the GC cooperative mode instead of using the GCX_COOP_THREAD_EXISTS
-        // macro so that this function isn't slowed down by having to deal with FS:0 chain on x86 Windows.
-        BOOL wasCoop = m_pCurThread->PreemptiveGCDisabled();
-        if (!wasCoop)
-        {
-            m_pCurThread->DisablePreemptiveGC();
-        }
-
-        // When the frame is destroyed, make sure it is no longer in the
-        // frame chain managed by the Thread.
-
-        Pop();
+    m_Next = pThread->GetGCFrame();
 
-#ifndef FEATURE_PAL
-
-        PTR_Frame frame = NULL;
-
-#ifdef FEATURE_EH_FUNCLETS
-        PTR_ExceptionTracker pCurrentTracker = m_pCurThread->GetExceptionState()->GetCurrentExceptionTracker();
-        if (pCurrentTracker != NULL)
-        {
-            frame = pCurrentTracker->GetInitialExplicitFrame();
-        }
-#else
-        PTR_PTR_Frame ptrToInitialFrame = m_pCurThread->GetExceptionState()->GetPtrToBottomFrameDuringUnwind();
-        if (ptrToInitialFrame != NULL)
-        {
-            frame = *ptrToInitialFrame;
-            if (frame == this)
-            {
-                // The current frame that was just popped was the bottom frame used
-                // as an initial frame to scan stack frames.
-                // Update the bottom frame pointer to point to the first valid frame.
-                *ptrToInitialFrame = m_pCurThread->m_pFrame;
-            }
-        }
-#endif // FEATURE_EH_FUNCLETS
-
-        if (frame != NULL)
-        {
-            // There is an initial explicit frame, so we need to scan the explicit frame chain starting at
-            // that frame to see if the current frame that is being destroyed was on the chain.
-
-            while ((frame != FRAME_TOP) && (frame != this))
-            {
-                PTR_Frame nextFrame = frame->PtrNextFrame();
-                if (nextFrame == this)
-                {
-                    // Repair frame chain from the initial explicit frame to the current frame,
-                    // skipping the current GCFrame that was destroyed
-                    frame->m_Next = m_pCurThread->m_pFrame;
-                    break;
-                }
-                frame = nextFrame;
-                _ASSERTE(frame != NULL);
-            }
-        }
-#endif // !FEATURE_PAL
+    // GetOsPageSize() is used to relax the assert for cases where two Frames are
+    // declared in the same source function. We cannot predict the order
+    // in which the C compiler will lay them out in the stack frame.
+    // So GetOsPageSize() is a guess of the maximum stack frame size of any method
+    // with multiple Frames in mscorwks.dll
+    _ASSERTE(((m_Next == NULL) ||
+              (PBYTE(m_Next) + (2 * GetOsPageSize())) > PBYTE(this)) &&
+             "Pushing a GCFrame out of order ?");
 
-        if (!wasCoop)
-        {
-            m_pCurThread->EnablePreemptiveGC();
-        }
-    }
+    pThread->SetGCFrame(this);
 }
 
-ExceptionFilterFrame::~ExceptionFilterFrame()
+//--------------------------------------------------------------------
+// Pops the GCFrame and cancels the GC protection.
+//--------------------------------------------------------------------
+VOID GCFrame::Pop()
 {
-    CONTRACTL
-    {
-        NOTHROW;
-        GC_NOTRIGGER;
-        MODE_ANY;
-    }
-    CONTRACTL_END;
+    WRAPPER_NO_CONTRACT;
 
-    if (m_Next != NULL)
-    {
-        GCX_COOP();
-        // When the frame is destroyed, make sure it is no longer in the
-        // frame chain managed by the Thread.
-        Pop();
-    }
-}
+    _ASSERTE(m_pCurThread->GetGCFrame() == this && "Popping a GCFrame out of order ?");
+
+    m_pCurThread->SetGCFrame(m_Next);
+    m_Next = NULL;
 
-#endif // !CROSSGEN_COMPILE
+#ifdef _DEBUG
+    m_pCurThread->EnableStressHeap();
+    for(UINT i = 0; i < m_numObjRefs; i++)
+        Thread::ObjectRefNew(&m_pObjRefs[i]);       // Unprotect them
+#endif
+}
 
 #ifdef FEATURE_INTERPRETER
 // Methods of IntepreterFrame.
@@ -1170,6 +1120,17 @@ BOOL IsProtectedByGCFrame(OBJECTREF *ppObjectRef)
     ENABLE_FORBID_GC_LOADER_USE_IN_THIS_SCOPE ();
     IsProtectedByGCFrameStruct d = {ppObjectRef, 0};
     GetThread()->StackWalkFrames(IsProtectedByGCFrameStackWalkFramesCallback, &d);
+
+    GCFrame* pGCFrame = GetThread()->GetGCFrame();
+    while (pGCFrame != NULL)
+    {
+        if (pGCFrame->Protects(ppObjectRef)) {
+            d.count++;
+        }
+
+        pGCFrame = pGCFrame->PtrNextFrame();
+    }
+
     if (d.count > 1) {
         _ASSERTE(!"Multiple GCFrames protecting the same pointer. This will cause GC corruption!");
     }
index c590e43..6fca31c 100644 (file)
 //    Frame                     - the root class. There are no actual instances
 //    |                           of Frames.
 //    |
-//    +-GCFrame                 - this frame doesn't represent a method call.
-//    |                           it's sole purpose is to let the EE gc-protect
-//    |                           object references that it is manipulating.
-//    |
 //    +- FaultingExceptionFrame - this frame was placed on a method which faulted
 //    |                           to save additional state information
 //    |
@@ -238,7 +234,6 @@ FRAME_TYPE_NAME(DynamicHelperFrame)
 #if !defined(_TARGET_X86_)
 FRAME_TYPE_NAME(StubHelperFrame)
 #endif
-FRAME_TYPE_NAME(GCFrame)
 #ifdef FEATURE_INTERPRETER
 FRAME_TYPE_NAME(InterpreterFrame)
 #endif // FEATURE_INTERPRETER
@@ -408,7 +403,6 @@ public:
 class Frame : public FrameBase
 {
     friend class CheckAsmOffsets;
-    friend class GCFrame;
 #ifdef DACCESS_COMPILE
     friend void Thread::EnumMemoryRegions(CLRDataEnumMemoryFlags flags);
 #endif
@@ -2464,20 +2458,19 @@ private:
 
 #endif // FEATURE_COMINTEROP
 
-
 //------------------------------------------------------------------------
 // This frame protects object references for the EE's convenience.
 // This frame type actually is created from C++.
+// There is a chain of GCFrames on a Thread, separate from the
+// explicit frames derived from the Frame class.
 //------------------------------------------------------------------------
-class GCFrame : public Frame
+class GCFrame
 {
-    VPTR_VTABLE_CLASS(GCFrame, Frame)
-
 public:
 
 
     //--------------------------------------------------------------------
-    // This constructor pushes a new GCFrame on the frame chain.
+    // This constructor pushes a new GCFrame on the GC frame chain.
     //--------------------------------------------------------------------
 #ifndef DACCESS_COMPILE
     GCFrame() {
@@ -2486,9 +2479,15 @@ public:
 
     GCFrame(OBJECTREF *pObjRefs, UINT numObjRefs, BOOL maybeInterior);
     GCFrame(Thread *pThread, OBJECTREF *pObjRefs, UINT numObjRefs, BOOL maybeInterior);
-#endif
+#ifndef CROSSGEN_COMPILE
+    ~GCFrame();
+#endif // CROSSGEN_COMPILE
+
+#endif // DACCESS_COMPILE
+
     void Init(Thread *pThread, OBJECTREF *pObjRefs, UINT numObjRefs, BOOL maybeInterior);
 
+    void Push(Thread *pThread);
 
     //--------------------------------------------------------------------
     // Pops the GCFrame and cancels the GC protection. Also
@@ -2496,10 +2495,10 @@ public:
     //--------------------------------------------------------------------
     VOID Pop();
 
-    virtual void GcScanRoots(promote_func *fn, ScanContext* sc);
+    void GcScanRoots(promote_func *fn, ScanContext* sc);
 
 #ifdef _DEBUG
-    virtual BOOL Protects(OBJECTREF *ppORef)
+    BOOL Protects(OBJECTREF *ppORef)
     {
         LIMITED_METHOD_CONTRACT;
         for (UINT i = 0; i < m_numObjRefs; i++) {
@@ -2519,22 +2518,18 @@ public:
     }
 #endif
 
-#if defined(_DEBUG_IMPL)
-    const char* GetFrameTypeName() { LIMITED_METHOD_CONTRACT; return "GCFrame"; }
-#endif
+    PTR_GCFrame PtrNextFrame()
+    {
+        WRAPPER_NO_CONTRACT;
+        return m_Next;
+    }
 
 private:
+    PTR_GCFrame   m_Next;
     PTR_OBJECTREF m_pObjRefs;
     UINT          m_numObjRefs;
     PTR_Thread    m_pCurThread;
     BOOL          m_MaybeInterior;
-
-    // Keep as last entry in class
-    DEFINE_VTABLE_GETTER(GCFrame)
-
-#if !defined(DACCESS_COMPILE) && !defined(CROSSGEN_COMPILE)
-    ~GCFrame();
-#endif
 };
 
 #ifdef FEATURE_INTERPRETER
@@ -3264,16 +3259,11 @@ public:
             *m_pShadowSP |= ICodeManager::SHADOW_SP_FILTER_DONE;
         }
     }
-
-#ifndef CROSSGEN_COMPILE
-    ~ExceptionFilterFrame();
-#endif
-
 #endif
 
 private:
     // Keep as last entry in class
-    DEFINE_VTABLE_GETTER_AND_CTOR(ExceptionFilterFrame)
+    DEFINE_VTABLE_GETTER_AND_CTOR_AND_DTOR(ExceptionFilterFrame)
 };
 
 #ifdef _DEBUG
@@ -3545,7 +3535,7 @@ public:
 #endif /*_PREFAST_ */
 
 #define GCPROTECT_BEGIN(ObjRefStruct)                           do {    \
-                FrameWithCookie<GCFrame> __gcframe(                     \
+                GCFrame __gcframe(                                      \
                         (OBJECTREF*)&(ObjRefStruct),                    \
                         sizeof(ObjRefStruct)/sizeof(OBJECTREF),         \
                         FALSE);                                         \
@@ -3553,7 +3543,7 @@ public:
                 if (true) { DEBUG_ASSURE_NO_RETURN_BEGIN(GCPROTECT)
 
 #define GCPROTECT_BEGIN_THREAD(pThread, ObjRefStruct)           do {    \
-                FrameWithCookie<GCFrame> __gcframe(                     \
+                GCFrame __gcframe(                                      \
                         pThread,                                        \
                         (OBJECTREF*)&(ObjRefStruct),                    \
                         sizeof(ObjRefStruct)/sizeof(OBJECTREF),         \
@@ -3562,7 +3552,7 @@ public:
                 if (true) { DEBUG_ASSURE_NO_RETURN_BEGIN(GCPROTECT)
 
 #define GCPROTECT_ARRAY_BEGIN(ObjRefArray,cnt) do {                     \
-                FrameWithCookie<GCFrame> __gcframe(                     \
+                GCFrame __gcframe(                                      \
                         (OBJECTREF*)&(ObjRefArray),                     \
                         cnt * sizeof(ObjRefArray) / sizeof(OBJECTREF),  \
                         FALSE);                                         \
@@ -3573,7 +3563,7 @@ public:
                 /* work around Wsizeof-pointer-div warning as we */     \
                 /* mean to capture pointer or object size */            \
                 UINT subjectSize = sizeof(ObjRefStruct);                \
-                FrameWithCookie<GCFrame> __gcframe(                     \
+                GCFrame __gcframe(                                      \
                         (OBJECTREF*)&(ObjRefStruct),                    \
                         subjectSize/sizeof(OBJECTREF),                  \
                         TRUE);                                          \
@@ -3581,7 +3571,7 @@ public:
                 if (true) { DEBUG_ASSURE_NO_RETURN_BEGIN(GCPROTECT)
 
 #define GCPROTECT_BEGININTERIOR_ARRAY(ObjRefArray,cnt) do {             \
-                FrameWithCookie<GCFrame> __gcframe(                     \
+                GCFrame __gcframe(                                      \
                         (OBJECTREF*)&(ObjRefArray),                     \
                         cnt,                                            \
                         TRUE);                                          \
index a455c3d..fac5487 100644 (file)
@@ -1769,7 +1769,7 @@ void DoGcStress (PCONTEXT regs, NativeCodeVersion nativeCodeVersion)
 #endif // !_TARGET_AMD64_ || !PLATFORM_UNIX
     }
 
-    FrameWithCookie<GCFrame> gcFrame;
+    GCFrame gcFrame;
     if (numberOfRegs != 0)
     {
         _ASSERTE(sizeof(OBJECTREF) == sizeof(DWORD_PTR));
@@ -1825,8 +1825,6 @@ void DoGcStress (PCONTEXT regs, NativeCodeVersion nativeCodeVersion)
             _ASSERTE(!"Not expected multi reg return with pointers.");
 #endif // !_TARGET_AMD64_ || !PLATFORM_UNIX   
         }
-
-        gcFrame.Pop();
     }
 
 #if !defined(USE_REDIRECT_FOR_GCSTRESS)
index d1b14a4..76097c1 100644 (file)
@@ -91,8 +91,6 @@ static void ScanStackRoots(Thread * pThread, promote_func* fn, ScanContext* sc)
                 IsGCSpecialThread() ||
                 (GetThread() == ThreadSuspend::GetSuspensionThread() && ThreadStore::HoldingThreadStore()));
 
-    pThread->SetHasPromotedBytes();
-
     Frame* pTopFrame = pThread->GetFrame();
     Object ** topStack = (Object **)pTopFrame;
     if ((pTopFrame != ((Frame*)-1))
@@ -147,6 +145,13 @@ static void ScanStackRoots(Thread * pThread, promote_func* fn, ScanContext* sc)
 #endif // defined(FEATURE_EH_FUNCLETS)
         pThread->StackWalkFrames( GcStackCrawlCallBack, &gcctx, flagsStackWalk);
     }
+
+    GCFrame* pGCFrame = pThread->GetGCFrame();
+    while (pGCFrame != NULL)
+    {
+        pGCFrame->GcScanRoots(fn, sc);
+        pGCFrame = pGCFrame->PtrNextFrame();
+    }
 }
 
 void GCToEEInterface::GcScanRoots(promote_func* fn, int condemned, int max_gen, ScanContext* sc)
index c2b5aae..62d990c 100644 (file)
@@ -554,15 +554,8 @@ EXCEPTION_DISPOSITION ClrDebuggerDoUnwindAndIntercept(EXCEPTION_REGISTRATION_REC
     LOG((LF_EH|LF_CORDB, LL_INFO100, "\t\t: pFunc is 0x%X\n", tct.pFunc));
     LOG((LF_EH|LF_CORDB, LL_INFO100, "\t\t: pStack is 0x%X\n", tct.pStack));
 
-    _ASSERTE(pExState->GetPtrToBottomFrameDuringUnwind() == NULL);
-    pExState->SetPtrToBottomFrameDuringUnwind(&tct.pBottomFrame);
-
     CallRtlUnwindSafe(pEstablisherFrame, RtlUnwindCallback, pExceptionRecord, 0);
 
-    _ASSERTE(pExState->GetPtrToBottomFrameDuringUnwind() == &tct.pBottomFrame);
-    _ASSERTE(*pExState->GetPtrToBottomFrameDuringUnwind() == tct.pBottomFrame);
-    pExState->SetPtrToBottomFrameDuringUnwind(NULL);
-
     ExInfo* pExInfo = pThread->GetExceptionState()->GetCurrentExceptionTracker();
     if (pExInfo->m_ValidInterceptionContext)
     {
@@ -1241,17 +1234,9 @@ CPFH_RealFirstPassHandler(                  // ExceptionContinueSearch, etc.
 
     LOG((LF_EH, LL_INFO100, "CPFH_RealFirstPassHandler: handler found: %s\n", tct.pFunc->m_pszDebugMethodName));
 
-    ThreadExceptionState* pExState = pThread->GetExceptionState();
-    _ASSERTE(pExState->GetPtrToBottomFrameDuringUnwind() == NULL);
-    pExState->SetPtrToBottomFrameDuringUnwind(&tct.pBottomFrame);
-
     CallRtlUnwindSafe(pEstablisherFrame, RtlUnwindCallback, pExceptionRecord, 0);
     // on x86 at least, RtlUnwind always returns
 
-    _ASSERTE(pExState->GetPtrToBottomFrameDuringUnwind() == &tct.pBottomFrame);
-    _ASSERTE(*pExState->GetPtrToBottomFrameDuringUnwind() == tct.pBottomFrame);
-    pExState->SetPtrToBottomFrameDuringUnwind(NULL);
-
     // The CallRtlUnwindSafe could have popped the explicit frame that the tct.pBottomFrame points to (UMThunkPrestubHandler
     // does that). In such case, the tct.pBottomFrame needs to be updated to point to the first valid explicit frame.
     Frame* frame = pThread->GetFrame();
index 3a9f68b..2c4e0f0 100644 (file)
 #define NO_MAPPING ((BYTE) -1)
 
 #define GCPROTECT_BEGIN_VARIANTDATA(/*VARIANTDATA*/vd) do {             \
-                FrameWithCookie<GCFrame> __gcframe(vd.GetObjRefPtr(), 1, FALSE);   \
+                GCFrame __gcframe(vd.GetObjRefPtr(), 1, FALSE);         \
                 /* work around unreachable code warning */              \
                 if (true) { DEBUG_ASSURE_NO_RETURN_BEGIN(GCPROTECT);
 
 
 #define GCPROTECT_END_VARIANTDATA()                                     \
                 DEBUG_ASSURE_NO_RETURN_END(GCPROTECT); }                \
-                __gcframe.Pop(); } while(0)
+                } while(0)
 
 
 //Mapping from CVType to type handle. Used for conversion between the two internally.
index 6f61d9d..f8f707b 100644 (file)
@@ -1319,6 +1319,7 @@ Thread::Thread()
     CONTRACTL_END;
 
     m_pFrame                = FRAME_TOP;
+    m_pGCFrame              = NULL;
 
     m_fPreemptiveGCDisabled = 0;
 
@@ -7986,25 +7987,6 @@ void Thread::SetCulture(OBJECTREF *CultureObj, BOOL bUICulture)
     propSet.Call_RetArgSlot(pNewArgs);
 }
 
-void Thread::SetHasPromotedBytes ()
-{
-    CONTRACTL {
-        NOTHROW;
-        GC_NOTRIGGER;
-    }
-    CONTRACTL_END;
-
-    m_fPromoted = TRUE;
-
-    _ASSERTE(GCHeapUtilities::IsGCInProgress()  && IsGCThread ());
-
-    if (!m_fPreemptiveGCDisabled)
-    {
-        if (FRAME_TOP == GetFrame())
-            m_fPromoted = FALSE;
-    }
-}
-
 BOOL ThreadStore::HoldingThreadStore(Thread *pThread)
 {
     CONTRACTL {
index 9a6466c..389b5f0 100644 (file)
@@ -1673,6 +1673,7 @@ private:
     // or StressLog which may waits on a spinlock.  It is unsafe to suspend a thread while it
     // is in this state.
     Volatile<LONG> m_dwForbidSuspendThread;
+
 public:
 
     static void IncForbidSuspendThread()
@@ -1886,7 +1887,6 @@ public:
     {
         SUPPORTS_DAC;
 
-#ifndef DACCESS_COMPILE
 #ifdef _DEBUG_IMPL
         WRAPPER_NO_CONTRACT;
         if (this == GetThreadNULLOk())
@@ -1895,15 +1895,32 @@ public:
             curSP = (void *)GetCurrentSP();
             _ASSERTE((curSP <= m_pFrame && m_pFrame < m_CacheStackBase) || m_pFrame == (Frame*) -1);
         }
-#else
-        LIMITED_METHOD_CONTRACT;
-        _ASSERTE(!"NYI");
 #endif
-#endif // #ifndef DACCESS_COMPILE
+
         return m_pFrame;
     }
 
     //--------------------------------------------------------------
+    // Returns innermost active GCFrame.
+    //--------------------------------------------------------------
+    PTR_GCFrame GetGCFrame()
+    {
+        SUPPORTS_DAC;
+
+#ifdef _DEBUG_IMPL
+        WRAPPER_NO_CONTRACT;
+        if (this == GetThreadNULLOk())
+        {
+            void* curSP;
+            curSP = (void *)GetCurrentSP();
+            _ASSERTE((m_pGCFrame == NULL) || (curSP <= m_pGCFrame && m_pGCFrame < m_CacheStackBase));
+        }
+#endif
+
+        return m_pGCFrame;
+    }
+
+    //--------------------------------------------------------------
     // Replaces innermost active Frames.
     //--------------------------------------------------------------
 #ifndef DACCESS_COMPILE
@@ -1918,6 +1935,18 @@ public:
 #endif
     ;
 #endif
+
+    //--------------------------------------------------------------
+    // Replaces innermost active GCFrame.
+    //--------------------------------------------------------------
+#ifndef DACCESS_COMPILE
+    void  SetGCFrame(GCFrame *pFrame)
+    {
+        LIMITED_METHOD_CONTRACT;
+        m_pGCFrame = pFrame;
+    }
+#endif
+
     inline Frame* FindFrame(SIZE_T StackPointer);
 
     bool DetectHandleILStubsForDebugger();
@@ -3690,18 +3719,6 @@ private:
 
     LONG            m_TraceCallCount;
 
-    //-----------------------------------------------------------
-    // Bytes promoted on this thread since the last GC?
-    //-----------------------------------------------------------
-    DWORD           m_fPromoted;
-public:
-    void SetHasPromotedBytes ();
-    DWORD GetHasPromotedBytes ()
-    {
-        LIMITED_METHOD_CONTRACT;
-        return m_fPromoted;
-    }
-
 private:
     //-----------------------------------------------------------
     // Last exception to be thrown.
@@ -4893,6 +4910,9 @@ public:
     void SetGCSpecial(bool fGCSpecial);
 
 private:
+
+    PTR_GCFrame m_pGCFrame; // The topmost GC Frame
+
 #ifndef FEATURE_PAL
     WORD m_wCPUGroup;
     DWORD_PTR m_pAffinityMask;