void celHPath::Restart () { while(HasNextInternal(reverse)) { NextInternal(reverse); } // reset travelled distance advanced = 0; }
PTR_VOID StackFrameIterator::HandleExCollide(PTR_ExInfo pExInfo, PTR_VOID collapsingTargetFrame) { STRESS_LOG3(LF_STACKWALK, LL_INFO10000, " [ ex collide ] kind = %d, pass = %d, idxCurClause = %d\n", pExInfo->m_kind, pExInfo->m_passNumber, pExInfo->m_idxCurClause); UInt32 curFlags = m_dwFlags; // If we aren't invoking a funclet (i.e. idxCurClause == -1), and we're doing a GC stackwalk, we don't // want the 2nd-pass collided behavior because that behavior assumes that the previous frame was a // funclet, which isn't the case when taking a GC at some points in the EH dispatch code. So we treat it // as if the 2nd pass hasn't actually started yet. if ((pExInfo->m_passNumber == 1) || (pExInfo->m_idxCurClause == 0xFFFFFFFF)) { ASSERT_MSG(!(curFlags & ApplyReturnAddressAdjustment), "did not expect to collide with a 1st-pass ExInfo during a EH stackwalk"); InternalInit(m_pThread, pExInfo->m_pExContext, curFlags); m_pNextExInfo = pExInfo->m_pPrevExInfo; CalculateCurrentMethodState(); ASSERT(IsValid()); if ((pExInfo->m_kind == EK_HardwareFault) && (curFlags & RemapHardwareFaultsToSafePoint)) GetCodeManager()->RemapHardwareFaultToGCSafePoint(&m_methodInfo, &m_codeOffset); } else { // // Copy our state from the previous StackFrameIterator // this->UpdateFromExceptionDispatch((PTR_StackFrameIterator)&pExInfo->m_frameIter); // Sync our 'current' ExInfo with the updated state (we may have skipped other dispatches) ResetNextExInfoForSP(m_RegDisplay.GetSP()); if ((m_dwFlags & ApplyReturnAddressAdjustment) && (curFlags & ApplyReturnAddressAdjustment)) { // Counteract our pre-adjusted m_ControlPC, since the caller of this routine will apply the // adjustment again once we return. m_ControlPC = AdjustReturnAddressForward(m_ControlPC); } m_dwFlags = curFlags; if ((m_ControlPC != 0) && // the dispatch in ExInfo could have gone unhandled (m_dwFlags & CollapseFunclets)) { CalculateCurrentMethodState(); ASSERT(IsValid()); if (GetCodeManager()->IsFunclet(&m_methodInfo)) { // We just unwound out of a funclet, now we need to keep unwinding until we find the 'main // body' associated with this funclet and then unwind out of that. collapsingTargetFrame = m_FramePointer; } else { // We found the main body, now unwind out of that and we're done. // In the case where the caller *was* the main body, we didn't need to set // collapsingTargetFrame, so it is zero in that case. ASSERT(!collapsingTargetFrame || (collapsingTargetFrame == m_FramePointer)); NextInternal(); collapsingTargetFrame = 0; } } } return collapsingTargetFrame; }
iMapNode* celHPath::Previous () { return NextInternal(!reverse); }
iMapNode* celHPath::Next () { return NextInternal(reverse); }