[cDAC] X86 support TailCallFrame#116792
Conversation
There was a problem hiding this comment.
Pull Request Overview
This PR adds support for handling TailCallFrame in the cDAC on Windows x86 by introducing a new TailCallFrame type and integrating it into the stack walking and frame handling mechanism.
- Added TailCallFrame class with proper field calculations.
- Extended the IPlatformFrameHandler interface and updated X86FrameHandler and FrameIterator to process TailCallFrame.
- Updated native support via cdac_data in frames.h and the corresponding data descriptors in datadescriptor.h.
Reviewed Changes
Copilot reviewed 8 out of 8 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| Data/Frames/TailCallFrame.cs | New TailCallFrame type that calculates CalleeSavedRegisters and ReturnAddress. |
| Contracts/StackWalk/FrameHandling/X86FrameHandler.cs | Implements HandleTailCallFrame, updating Eip/Esp and processing callee-saved registers. |
| Contracts/StackWalk/FrameHandling/IPlatformFrameHandler.cs | Extends the interface to include TailCallFrame handling. |
| Contracts/StackWalk/FrameHandling/FrameIterator.cs | Adds TailCallFrame support in the frame iteration logic. |
| Contracts/StackWalk/FrameHandling/BaseFrameHandler.cs | Provides default (exception-throwing) implementation for TailCallFrame. |
| Abstractions/DataType.cs | Updates enum to include TailCallFrame. |
| vm/frames.h | Adds native support by specializing cdac_data for TailCallFrame. |
| debug/runtimeinfo/datadescriptor.h | Registers TailCallFrame with proper conditional compilation for Windows x86. |
Comments suppressed due to low confidence (3)
src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/StackWalk/FrameHandling/X86FrameHandler.cs:38
- Add tests to verify that the TailCallFrame handling correctly updates Eip and Esp based on the frame data on Windows x86.
if (_target.GetTypeInfo(DataType.TailCallFrame).Size is not uint tailCallFrameSize)
src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Contracts/StackWalk/FrameHandling/BaseFrameHandler.cs:75
- [nitpick] Consider overriding HandleTailCallFrame in platform-specific frame handlers to avoid hitting the default exception, or update the documentation to clarify that the default implementation is intentional for unsupported platforms.
public virtual void HandleTailCallFrame(TailCallFrame tailCallFrame)
src/native/managed/cdac/Microsoft.Diagnostics.DataContractReader.Contracts/Data/Frames/TailCallFrame.cs:1
- [nitpick] Consider adding a comment indicating that TailCallFrame is exclusive to Windows x86 to aid future maintainability.
// Licensed to the .NET Foundation under one or more agreements.
|
Tagging subscribers to this area: @steveisok, @dotnet/dotnet-diag |
|
What would it take to switch x86 tailcalls to work the same way as other archs so that we do not need this special handling? |
runtime/src/coreclr/vm/frames.h Lines 2290 to 2307 in 9fe86ca It appears that this is where we take the JIT_TailCall path. runtime/src/coreclr/jit/morph.cpp Lines 4614 to 4619 in 9fe86ca There seems two ways to remove the TailCallFrames
|
It's a big chunk of work. We don't have fast tailcalls for x86 JIT. I resurrected @jakobbotsch's branch and updated it but it still had too many unhandled edge cases and unoptimal codegen (https://github.com/filipnavara/runtime/tree/FEATURE_INSTANTIATINGSTUB_AS_IL). I may give it another go at some point but even if I manage to get it working the risk of the change is high. |
|
For posterity, I wrote a comment why I gave up doing the x86 fast tailcalls last time: #116331 (comment) |
|
We can switch explicit tailcalls to the portable tailcall mechanism easily. It works fine for x86, it is just a bit slower compared to the existing optimized helper-based path. Here are the old measurements: We could also switch only VSD tailcalls to the portable mechanism if that gets us most of the way of simplifying this. We already switched delegates like this in #70269. |
Contributes to #114019
TailCallFrameare exclusive to Windows x86, add support for handling them in the cDAC. TailCallFrames are only generated when tail calls to VSD methods.Verified using the following F# script to generate a stack trace with a TailCallFrame.