-
Notifications
You must be signed in to change notification settings - Fork 5.3k
Apx requirements for VM and GC stubs #116806
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 8 commits
ff010bb
28b9dd7
2cf1452
a9f3523
9a5563e
3629e56
343607b
0241da3
33792cc
7f9f4c3
943308e
d4cffc7
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -1464,24 +1464,29 @@ typedef struct DECLSPEC_ALIGN(16) _CONTEXT { | |
| M512 Zmm31; | ||
| }; | ||
|
|
||
| struct | ||
| // XSTATE_APX | ||
| union | ||
| { | ||
| DWORD64 R16; | ||
| DWORD64 R17; | ||
| DWORD64 R18; | ||
| DWORD64 R19; | ||
| DWORD64 R20; | ||
| DWORD64 R21; | ||
| DWORD64 R22; | ||
| DWORD64 R23; | ||
| DWORD64 R24; | ||
| DWORD64 R25; | ||
| DWORD64 R26; | ||
| DWORD64 R27; | ||
| DWORD64 R28; | ||
| DWORD64 R29; | ||
| DWORD64 R30; | ||
| DWORD64 R31; | ||
| struct | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @dotnet/dotnet-diag I believe
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I cannot say for sure at the moment. It depends on the decision if we want the debugger to track these new EGPRs. Once the context structure gets finalized is when we can say with surety about what might get impacted. Thoughts?
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As of now, we have avoided making any kind of debugger changes since they would need windows OS to have
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sorry missed this comment earlier when @jkotas first pinged. Generally the managed debugger needs to be aware of all registers because at various points it saves them and later restores them. If the debugger isn't aware of all the registers it needs to save then we can easily end up in situations where an app works without the debugger, but trying to step through the code in the debugger behaves unpredictably. For example here is a recent debugger bug where x86 floating point register capture/restore got inadvertently broken: https://devdiv.visualstudio.com/DevDiv/_workitems/edit/2428652 If we wanted to make this work available prior to having the debugger portions implemented and tested I think it would need to be explicitly an opt-in feature with warnings that debugging is unsupported.
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. thanks @noahfalk
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. A common way we've done it in the past is to define an environment variable and then only use the new registers if the env var is set. Later on once it is fully supported we can switch the default value so the env var becomes an opt-out rather than opt-in. Here is an example for AVX registers: https://github.com/dotnet/runtime/blob/main/src/coreclr/inc/clrconfigvalues.h#L673 I'd prefer if the opt-in mechanism was included in this PR so that we don't create any window of builds where debugging is broken.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @noahfalk, The opt-in for APX already exists on L681 ( We automatically add a config switch per ISA (or ISA group in some cases) when the detection logic is added to the VM.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks @tannergooding! Glad to see its already in place. I'd also ask that anywhere we advertise the env var should make it clear managed debugging isn't supported.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍. We notably do not document these switches and rarely advertise them. They are considered advanced and primarily for people doing local testing, so they can validate downlevel hardware. There will likely be a blog post that lets people know about the switch when hardware does become available (so not until after .NET 10 ships) and we can ensure any nuances, such as the GC or debugger experience not working end to end, are called out there. |
||
| { | ||
| DWORD64 R16; | ||
| DWORD64 R17; | ||
| DWORD64 R18; | ||
| DWORD64 R19; | ||
| DWORD64 R20; | ||
| DWORD64 R21; | ||
| DWORD64 R22; | ||
| DWORD64 R23; | ||
| DWORD64 R24; | ||
| DWORD64 R25; | ||
| DWORD64 R26; | ||
| DWORD64 R27; | ||
| DWORD64 R28; | ||
| DWORD64 R29; | ||
| DWORD64 R30; | ||
| DWORD64 R31; | ||
| }; | ||
| DWORD64 R[16]; | ||
| }; | ||
|
|
||
| } CONTEXT, *PCONTEXT, *LPCONTEXT; | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -205,7 +205,7 @@ BOOL DacUnwindStackFrame(CONTEXT * pContext, KNONVOLATILE_CONTEXT_POINTERS* pCon | |
|
|
||
| if (res && pContextPointers) | ||
| { | ||
| for (int i = 0; i < 16; i++) | ||
| for (int i = 0; i < 32; i++) | ||
|
||
| { | ||
| *(&pContextPointers->Rax + i) = &pContext->Rax + i; | ||
| } | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -59,6 +59,11 @@ void ClearRegDisplayArgumentAndScratchRegisters(REGDISPLAY * pRD) | |
| pContextPointers->R9 = NULL; | ||
| pContextPointers->R10 = NULL; | ||
| pContextPointers->R11 = NULL; | ||
|
|
||
| #if defined(TARGET_UNIX) | ||
| for (int i=0; i < 16; i++) | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Similar question. Can/should we limit this to only scenarios with APX enabled? Same question applies to all the other loops/handling for the extended registers here.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Notably this can also just be a
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Same question as here https://github.com/dotnet/runtime/pull/116806/files#r2208598605
Yes this can be a memset. But then it would differ from how things are done under ARM. Current coding convention only extends what was already present. |
||
| pRD->volatileCurrContextPointers.R[i] = NULL; | ||
| #endif // TARGET_UNIX | ||
| } | ||
|
|
||
| void TransitionFrame::UpdateRegDisplay_Impl(const PREGDISPLAY pRD, bool updateFloats) | ||
|
|
@@ -227,6 +232,11 @@ void ResumableFrame::UpdateRegDisplay_Impl(const PREGDISPLAY pRD, bool updateFlo | |
| pRD->pCurrentContextPointers->R14 = &m_Regs->R14; | ||
| pRD->pCurrentContextPointers->R15 = &m_Regs->R15; | ||
|
|
||
| #if defined(TARGET_UNIX) | ||
| for (int i = 0; i < 16; i++) | ||
| pRD->volatileCurrContextPointers.R[i] = &m_Regs->R[i]; | ||
| #endif // TARGET_UNIX | ||
|
|
||
| pRD->IsCallerContextValid = FALSE; | ||
| pRD->IsCallerSPValid = FALSE; // Don't add usage of this field. This is only temporary. | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why does this part need to be UNIX specific? Isn't this equally applicable to Windows and we just won't be using it until the OS feature detection is available?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is one of the limitations right now. We discussed this briefly during out meeting. We have to wait for widows to expose APX EGPR context. Without it, we cannot enable GC pathways for windows since windows
CONTEXTwould not have those registers exposed. Linux uses theCONTEXTdefined inpal.hwhere as for windows it uses the one defined in `winnt.h' in the SDK file.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not quite sure I'm understanding. The Win32
CONTEXTstruct never has any extended registers as part of it (no YMM, no ZMM, no KMASK, etc).There is "hidden" extra data you can query for by setting
CONTEXT_XSTATEand then further setting specificXSTATEbits such asXSTATE_MASK_AVX,XSTATE_MASK_AVX512, etc. This extra data is laid out mirroring whatXSAVE/XRSTRreturn and theXSTATE_MASK_*flags directly map to therequested-feature bitmapbits fromXCR0for performance reasons, but I don't believe is strictly guaranteed to be this way (even if unlikely to change) and so we cannot pre-code such support.Because Windows hasn't defined
XSTATE_MASK_APXyet and we cannot guarantee it will matchXCR0(specifically bit 19), we cannot enable this for Windows. However, we should be able to reasonably setup everything so that it is essentially a 1-liner to enable. Namely all areas of the JIT currently use the sameminipal_getcpufeaturesfunction and cache them. This includesvxsortin the GC, NativeAOT, the general VM, etc.So, my thought is most of these paths shouldn't be unconditionally doing
APXhandling, they should rather be doing something likeif (IsApxSupported()) { /* handle extra 16 regs */ }. We can then haveUNIXreturn true if APX has been enabled (there's no reason to expend the cycles doing save/restore for these areas otherwise) and we can haveWINDOWSstatically returnfalse.This ensures that all of the handling only requires us to touch the
IsApxSupported()function (which is likely just reading the cachedInstructionSet_*flag) when Windows does define the relevant bits.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the response. I am working on making the above changes. To sum up -
We use the
cpufeaturescached by GC and only runEGPRhandling when APX is enabled. Furthermore, we disable APX support for windows inIsAPXSupportedand hence making it a 1 liner change for windows.