Skip to content

Commit

Permalink
[NativeAOT] A few cleanups in stack walking on Windows (#86917)
Browse files Browse the repository at this point in the history
  • Loading branch information
VSadov authored Jun 4, 2023
1 parent 48ce1d9 commit 2bf8f1a
Show file tree
Hide file tree
Showing 6 changed files with 36 additions and 21 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,6 @@ public class Type
[StructLayout(LayoutKind.Sequential)]
public struct RuntimeTypeHandle
{
private EETypePtr _pEEType;
private IntPtr _value;
}
}
2 changes: 2 additions & 0 deletions src/coreclr/nativeaot/Runtime/ICodeManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
5 changes: 5 additions & 0 deletions src/coreclr/nativeaot/Runtime/StackFrameIterator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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));

Expand Down
31 changes: 22 additions & 9 deletions src/coreclr/nativeaot/Runtime/windows/CoffNativeCodeManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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) \
Expand All @@ -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;
Expand All @@ -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;
Expand All @@ -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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,7 @@ namespace System
[StructLayout(LayoutKind.Sequential)]
public unsafe struct RuntimeTypeHandle : IEquatable<RuntimeTypeHandle>, 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)
Expand Down Expand Up @@ -123,7 +120,5 @@ internal bool IsNull
return _value == new IntPtr(0);
}
}

private IntPtr _value;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
}
}
Expand All @@ -32,7 +32,7 @@ internal static class LdTokenHelpers
{
private static RuntimeTypeHandle GetRuntimeTypeHandle(IntPtr pEEType)
{
return new RuntimeTypeHandle(new EETypePtr(pEEType));
return new RuntimeTypeHandle(pEEType);
}
}
}

0 comments on commit 2bf8f1a

Please sign in to comment.