From 2bf8f1aa83e192a307d5846424880cd61bec1a4f Mon Sep 17 00:00:00 2001 From: Vladimir Sadov Date: Sun, 4 Jun 2023 14:29:52 -0700 Subject: [PATCH] [NativeAOT] A few cleanups in stack walking on Windows (#86917) --- .../src/System/RuntimeTypeHandle.cs | 2 +- src/coreclr/nativeaot/Runtime/ICodeManager.h | 2 ++ .../nativeaot/Runtime/StackFrameIterator.cpp | 5 +++ .../Runtime/windows/CoffNativeCodeManager.cpp | 31 +++++++++++++------ .../src/System/RuntimeTypeHandle.cs | 7 +---- .../src/System/RuntimeTypeHandle.cs | 10 +++--- 6 files changed, 36 insertions(+), 21 deletions(-) diff --git a/src/coreclr/nativeaot/Runtime.Base/src/System/RuntimeTypeHandle.cs b/src/coreclr/nativeaot/Runtime.Base/src/System/RuntimeTypeHandle.cs index 85f880035e904..8ecb99bc49e58 100644 --- a/src/coreclr/nativeaot/Runtime.Base/src/System/RuntimeTypeHandle.cs +++ b/src/coreclr/nativeaot/Runtime.Base/src/System/RuntimeTypeHandle.cs @@ -18,6 +18,6 @@ public class Type [StructLayout(LayoutKind.Sequential)] public struct RuntimeTypeHandle { - private EETypePtr _pEEType; + private IntPtr _value; } } diff --git a/src/coreclr/nativeaot/Runtime/ICodeManager.h b/src/coreclr/nativeaot/Runtime/ICodeManager.h index 4205c62c4de08..b21aa3fde6be7 100644 --- a/src/coreclr/nativeaot/Runtime/ICodeManager.h +++ b/src/coreclr/nativeaot/Runtime/ICodeManager.h @@ -172,6 +172,8 @@ enum UnwindStackFrameFlags // If this is a reverse P/Invoke frame, do not continue the unwind // after extracting the saved transition frame. USFF_StopUnwindOnTransitionFrame = 1, + // Registers not containing GC roots can be omitted. + USFF_GcUnwind = 2, }; class ICodeManager diff --git a/src/coreclr/nativeaot/Runtime/StackFrameIterator.cpp b/src/coreclr/nativeaot/Runtime/StackFrameIterator.cpp index 3dc6e98dfeb76..23eea76432092 100644 --- a/src/coreclr/nativeaot/Runtime/StackFrameIterator.cpp +++ b/src/coreclr/nativeaot/Runtime/StackFrameIterator.cpp @@ -1442,6 +1442,11 @@ void StackFrameIterator::NextInternal() unwindFlags |= USFF_StopUnwindOnTransitionFrame; } + if ((m_dwFlags & GcStackWalkFlags) == GcStackWalkFlags) + { + unwindFlags |= USFF_GcUnwind; + } + FAILFAST_OR_DAC_FAIL(GetCodeManager()->UnwindStackFrame(&m_methodInfo, unwindFlags, &m_RegDisplay, &m_pPreviousTransitionFrame)); diff --git a/src/coreclr/nativeaot/Runtime/windows/CoffNativeCodeManager.cpp b/src/coreclr/nativeaot/Runtime/windows/CoffNativeCodeManager.cpp index 96cc1e3934ef4..cc409cf2167a1 100644 --- a/src/coreclr/nativeaot/Runtime/windows/CoffNativeCodeManager.cpp +++ b/src/coreclr/nativeaot/Runtime/windows/CoffNativeCodeManager.cpp @@ -590,9 +590,9 @@ bool CoffNativeCodeManager::UnwindStackFrame(MethodInfo * pMethodInfo, #define WORDPTR PDWORD #elif defined(TARGET_AMD64) #define FOR_EACH_NONVOLATILE_REGISTER(F) \ - F(Rax, pRax) F(Rcx, pRcx) F(Rdx, pRdx) F(Rbx, pRbx) F(Rbp, pRbp) F(Rsi, pRsi) F(Rdi, pRdi) \ - F(R8, pR8) F(R9, pR9) F(R10, pR10) F(R11, pR11) F(R12, pR12) F(R13, pR13) F(R14, pR14) F(R15, pR15) - #define WORDPTR PDWORD64 + F(Rbx, pRbx) F(Rbp, pRbp) F(Rsi, pRsi) F(Rdi, pRdi) \ + F(R12, pR12) F(R13, pR13) F(R14, pR14) F(R15, pR15) +#define WORDPTR PDWORD64 #elif defined(TARGET_ARM64) #define FOR_EACH_NONVOLATILE_REGISTER(F) \ F(X19, pX19) F(X20, pX20) F(X21, pX21) F(X22, pX22) F(X23, pX23) F(X24, pX24) \ @@ -612,7 +612,11 @@ bool CoffNativeCodeManager::UnwindStackFrame(MethodInfo * pMethodInfo, #if defined(TARGET_X86) PORTABILITY_ASSERT("CoffNativeCodeManager::UnwindStackFrame"); #elif defined(TARGET_AMD64) - memcpy(&context.Xmm6, pRegisterSet->Xmm, sizeof(pRegisterSet->Xmm)); + + if (!(flags & USFF_GcUnwind)) + { + memcpy(&context.Xmm6, pRegisterSet->Xmm, sizeof(pRegisterSet->Xmm)); + } context.Rsp = pRegisterSet->SP; context.Rip = pRegisterSet->IP; @@ -634,10 +638,16 @@ bool CoffNativeCodeManager::UnwindStackFrame(MethodInfo * pMethodInfo, pRegisterSet->pIP = PTR_PCODE(pRegisterSet->SP - sizeof(TADDR)); - memcpy(pRegisterSet->Xmm, &context.Xmm6, sizeof(pRegisterSet->Xmm)); + if (!(flags & USFF_GcUnwind)) + { + memcpy(pRegisterSet->Xmm, &context.Xmm6, sizeof(pRegisterSet->Xmm)); + } #elif defined(TARGET_ARM64) - for (int i = 8; i < 16; i++) - context.V[i].Low = pRegisterSet->D[i - 8]; + if (!(flags & USFF_GcUnwind)) + { + for (int i = 8; i < 16; i++) + context.V[i].Low = pRegisterSet->D[i - 8]; + } context.Sp = pRegisterSet->SP; context.Pc = pRegisterSet->IP; @@ -659,8 +669,11 @@ bool CoffNativeCodeManager::UnwindStackFrame(MethodInfo * pMethodInfo, pRegisterSet->pIP = contextPointers.Lr; - for (int i = 8; i < 16; i++) - pRegisterSet->D[i - 8] = context.V[i].Low; + if (!(flags & USFF_GcUnwind)) + { + for (int i = 8; i < 16; i++) + pRegisterSet->D[i - 8] = context.V[i].Low; + } #endif // defined(TARGET_X86) FOR_EACH_NONVOLATILE_REGISTER(CONTEXT_TO_REGDISPLAY); diff --git a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/RuntimeTypeHandle.cs b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/RuntimeTypeHandle.cs index 3a9e422c9558e..e9c15296ccd88 100644 --- a/src/coreclr/nativeaot/System.Private.CoreLib/src/System/RuntimeTypeHandle.cs +++ b/src/coreclr/nativeaot/System.Private.CoreLib/src/System/RuntimeTypeHandle.cs @@ -16,10 +16,7 @@ namespace System [StructLayout(LayoutKind.Sequential)] public unsafe struct RuntimeTypeHandle : IEquatable, ISerializable { - // - // Caution: There can be and are multiple MethodTable for the "same" type (e.g. int[]). That means - // you can't use the raw IntPtr value for comparisons. - // + private IntPtr _value; internal RuntimeTypeHandle(EETypePtr pEEType) : this(pEEType.RawValue) @@ -123,7 +120,5 @@ internal bool IsNull return _value == new IntPtr(0); } } - - private IntPtr _value; } } diff --git a/src/coreclr/nativeaot/Test.CoreLib/src/System/RuntimeTypeHandle.cs b/src/coreclr/nativeaot/Test.CoreLib/src/System/RuntimeTypeHandle.cs index d921e27015b73..f0401dc09e07a 100644 --- a/src/coreclr/nativeaot/Test.CoreLib/src/System/RuntimeTypeHandle.cs +++ b/src/coreclr/nativeaot/Test.CoreLib/src/System/RuntimeTypeHandle.cs @@ -10,17 +10,17 @@ namespace System [StructLayout(LayoutKind.Sequential)] public struct RuntimeTypeHandle { - private EETypePtr _pEEType; + private IntPtr _value; - internal RuntimeTypeHandle(EETypePtr pEEType) + internal RuntimeTypeHandle(IntPtr value) { - _pEEType = pEEType; + _value = value; } [Intrinsic] internal static unsafe IntPtr ToIntPtr(RuntimeTypeHandle handle) { - return (IntPtr)handle._pEEType.ToPointer(); + return handle._value; } } } @@ -32,7 +32,7 @@ internal static class LdTokenHelpers { private static RuntimeTypeHandle GetRuntimeTypeHandle(IntPtr pEEType) { - return new RuntimeTypeHandle(new EETypePtr(pEEType)); + return new RuntimeTypeHandle(pEEType); } } }