Skip to content

Commit ed49df7

Browse files
authored
[release/11.0-preview1] Revert "Bring a few jithelpers to new unwind plan (#123307)" (#123715)
Backport of #123696 to release/11.0-preview1 /cc @janvorli ## Customer Impact - [ ] Customer reported - [x] Found internally Very frequent intermittent runtime crashes caused by buggy CPU context manipulations. ## Regression - [x] Yes - [ ] No Regression introduced by #123307, merged on Thu Jan 22, 2026. ## Testing Default CI run. ## Risk Low, clean revert of the offending PR.
1 parent 32cae38 commit ed49df7

18 files changed

+165
-848
lines changed

src/coreclr/pal/inc/unixasmmacrosarm64.inc

Lines changed: 0 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -468,29 +468,6 @@ C_FUNC(\Name\()_End):
468468
add \target, sp, #192
469469
.endm
470470

471-
// Epilog for PUSH_COOP_PINVOKE_FRAME_WITH_FLOATS - restores FP callee-saved and returns
472-
.macro POP_COOP_PINVOKE_FRAME_WITH_FLOATS_RETURN
473-
474-
// Restore FP callee-saved registers (d8-d15) from sp+0
475-
ldp d8, d9, [sp, #0]
476-
ldp d10, d11, [sp, #16]
477-
ldp d12, d13, [sp, #32]
478-
ldp d14, d15, [sp, #48]
479-
480-
// Deallocate space for FloatArgumentRegisters + FP callee-saved
481-
EPILOG_STACK_FREE 192
482-
483-
// Restore callee-saved registers
484-
EPILOG_RESTORE_REG_PAIR x27, x28, 80
485-
EPILOG_RESTORE_REG_PAIR x25, x26, 64
486-
EPILOG_RESTORE_REG_PAIR x23, x24, 48
487-
EPILOG_RESTORE_REG_PAIR x21, x22, 32
488-
EPILOG_RESTORE_REG_PAIR x19, x20, 16
489-
490-
EPILOG_RESTORE_REG_PAIR_INDEXED fp, lr, 176
491-
ret
492-
.endm
493-
494471
// ------------------------------------------------------------------
495472
// Macro to generate Redirection Stubs
496473
//

src/coreclr/pal/inc/unixasmmacrosloongarch64.inc

Lines changed: 0 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -443,31 +443,6 @@ C_FUNC(\Name\()_End):
443443
addi.d \target, $sp, 128
444444
.endm
445445

446-
// ------------------------------------------------------------------
447-
// Epilog macro for PUSH_COOP_PINVOKE_FRAME_WITH_FLOATS that restores all registers and returns.
448-
// Use this for JIT helpers that may return normally (unlike IL_Throw which never returns).
449-
.macro POP_COOP_PINVOKE_FRAME_WITH_FLOATS_RETURN
450-
// Restore FP callee-saved registers (f24-f31) from offset 0
451-
fld.d $f24, $sp, 0
452-
fld.d $f25, $sp, 8
453-
fld.d $f26, $sp, 16
454-
fld.d $f27, $sp, 24
455-
fld.d $f28, $sp, 32
456-
fld.d $f29, $sp, 40
457-
fld.d $f30, $sp, 48
458-
fld.d $f31, $sp, 56
459-
460-
// Restore callee-saved registers from offset 128
461-
RESTORE_CALLEESAVED_REGISTERS $sp, 128
462-
463-
// Restore fp, ra
464-
EPILOG_RESTORE_REG_PAIR 22, 1, 128
465-
466-
// Deallocate stack and return
467-
EPILOG_STACK_FREE 288
468-
EPILOG_RETURN
469-
.endm
470-
471446
// ------------------------------------------------------------------
472447
// Macro to generate Redirection Stubs
473448
//

src/coreclr/pal/inc/unixasmmacrosriscv64.inc

Lines changed: 0 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -394,35 +394,6 @@ C_FUNC(\Name):
394394
addi \target, sp, 160
395395
.endm
396396

397-
// ------------------------------------------------------------------
398-
// Epilog macro for PUSH_COOP_PINVOKE_FRAME_WITH_FLOATS that restores all registers and returns.
399-
// Use this for JIT helpers that may return normally (unlike IL_Throw which never returns).
400-
.macro POP_COOP_PINVOKE_FRAME_WITH_FLOATS_RETURN
401-
// Restore FP callee-saved registers (fs0-fs11 = f8,f9,f18-f27) from offset 0
402-
fld fs0, 0(sp) // f8
403-
fld fs1, 8(sp) // f9
404-
fld fs2, 16(sp) // f18
405-
fld fs3, 24(sp) // f19
406-
fld fs4, 32(sp) // f20
407-
fld fs5, 40(sp) // f21
408-
fld fs6, 48(sp) // f22
409-
fld fs7, 56(sp) // f23
410-
fld fs8, 64(sp) // f24
411-
fld fs9, 72(sp) // f25
412-
fld fs10, 80(sp) // f26
413-
fld fs11, 88(sp) // f27
414-
415-
// Restore callee-saved registers from offset 160
416-
RESTORE_CALLEESAVED_REGISTERS sp, 160
417-
418-
// Restore fp, ra
419-
EPILOG_RESTORE_REG_PAIR fp, ra, 160
420-
421-
// Deallocate stack and return
422-
EPILOG_STACK_FREE 352
423-
EPILOG_RETURN
424-
.endm
425-
426397
// ------------------------------------------------------------------
427398
// Macro to generate Redirection Stubs
428399
//

src/coreclr/vm/amd64/AsmHelpers.asm

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -402,15 +402,12 @@ NESTED_END OnCallCountThresholdReachedStub, _TEXT
402402
extern JIT_PatchpointWorkerWorkerWithPolicy:proc
403403

404404
NESTED_ENTRY JIT_Patchpoint, _TEXT
405-
; Use PUSH_COOP_PINVOKE_FRAME_WITH_FLOATS to save all registers including FP callee-saved
406-
; This allows us to build a complete CONTEXT from TransitionBlock without RtlCaptureContext
407-
PUSH_COOP_PINVOKE_FRAME_WITH_FLOATS rcx
405+
PROLOG_WITH_TRANSITION_BLOCK
408406

409-
; RCX contains pointer to TransitionBlock
407+
lea rcx, [rsp + __PWTB_TransitionBlock] ; TransitionBlock *
410408
call JIT_PatchpointWorkerWorkerWithPolicy
411409

412-
; If we return, restore all registers and return to caller
413-
POP_COOP_PINVOKE_FRAME_WITH_FLOATS_RETURN
410+
EPILOG_WITH_TRANSITION_BLOCK_RETURN
414411
NESTED_END JIT_Patchpoint, _TEXT
415412

416413
; first arg register holds iloffset, which needs to be moved to the second register, and the first register filled with NULL

src/coreclr/vm/amd64/AsmMacros.inc

Lines changed: 8 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -503,14 +503,13 @@ PUSH_COOP_PINVOKE_FRAME_WITH_FLOATS macro target
503503

504504
PUSH_CALLEE_SAVED_REGISTERS
505505

506-
; Allocate space for: shadow (32) + FP callee-saved (160) + float args (64) + padding (8) = 264 bytes
507-
; This makes RSP 16-byte aligned (8 + 64 + 264 = 336, and original RSP - 336 is 16-byte aligned)
508-
alloc_stack 264
506+
; Allocate space for: shadow for call (32) + FP callee-saved (160) + float args (64) + arg regs (32) + padding (8) = 296 bytes
507+
; Shadow space at offset 0 is reserved for the call to IL_Throw_Impl etc.
508+
; This makes RSP 16-byte aligned (8 + 64 + 296 = 368, and original RSP - 368 is 16-byte aligned)
509+
alloc_stack 296
509510

510-
; Save argument registers into caller's shadow space
511-
; TransitionBlock is at rsp + 264, sizeof(TransitionBlock) = 72
512-
; So argument registers go at rsp + 264 + 72 = rsp + 336
513-
SAVE_ARGUMENT_REGISTERS 336
511+
; Save argument registers at offset 256 (32 + 160 + 64)
512+
SAVE_ARGUMENT_REGISTERS 256
514513

515514
; Save float argument registers at offset 192 (32 + 160)
516515
SAVE_FLOAT_ARGUMENT_REGISTERS 192
@@ -531,31 +530,8 @@ PUSH_COOP_PINVOKE_FRAME_WITH_FLOATS macro target
531530

532531
END_PROLOGUE
533532

534-
; TransitionBlock pointer points to CalleeSavedRegisters at rsp + 264
535-
lea target, [rsp + 264]
536-
537-
endm
538-
539-
; Epilog for PUSH_COOP_PINVOKE_FRAME_WITH_FLOATS - restores XMM callee-saved and returns
540-
POP_COOP_PINVOKE_FRAME_WITH_FLOATS_RETURN macro
541-
542-
; Restore FP callee-saved registers (xmm6-xmm15) from offset 32 (after shadow space)
543-
movdqa xmm6, [rsp + 20h]
544-
movdqa xmm7, [rsp + 30h]
545-
movdqa xmm8, [rsp + 40h]
546-
movdqa xmm9, [rsp + 50h]
547-
movdqa xmm10, [rsp + 60h]
548-
movdqa xmm11, [rsp + 70h]
549-
movdqa xmm12, [rsp + 80h]
550-
movdqa xmm13, [rsp + 90h]
551-
movdqa xmm14, [rsp + 0A0h]
552-
movdqa xmm15, [rsp + 0B0h]
553-
554-
; Deallocate stack space (264 bytes)
555-
add rsp, 264
556-
557-
POP_CALLEE_SAVED_REGISTERS
558-
ret
533+
; TransitionBlock pointer points to CalleeSavedRegisters at rsp + 296
534+
lea target, [rsp + 296]
559535

560536
endm
561537

src/coreclr/vm/arm64/asmconstants.h

Lines changed: 0 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -101,38 +101,12 @@ ASMCONSTANTS_C_ASSERT(SIZEOF__Frame == sizeof(Frame));
101101
#endif
102102
ASMCONSTANTS_C_ASSERT(SIZEOF__CONTEXT == sizeof(T_CONTEXT));
103103

104-
#define OFFSETOF__CONTEXT__ContextFlags 0x0
105-
ASMCONSTANTS_C_ASSERT(OFFSETOF__CONTEXT__ContextFlags == offsetof(T_CONTEXT, ContextFlags));
106-
107-
// CONTEXT_INTEGER_BIT is bit 1 in ContextFlags (from pal.h CONTEXT_INTEGER definition)
108-
#define CONTEXT_INTEGER_BIT 1
109-
110-
#define OFFSETOF__CONTEXT__X0 0x08
111-
ASMCONSTANTS_C_ASSERT(OFFSETOF__CONTEXT__X0 == offsetof(T_CONTEXT, X0));
112-
113104
#define OFFSETOF__CONTEXT__X19 0xA0
114105
ASMCONSTANTS_C_ASSERT(OFFSETOF__CONTEXT__X19 == offsetof(T_CONTEXT, X19));
115106

116107
#define OFFSETOF__CONTEXT__Fp 0xF0
117108
ASMCONSTANTS_C_ASSERT(OFFSETOF__CONTEXT__Fp == offsetof(T_CONTEXT, Fp));
118109

119-
#define OFFSETOF__CONTEXT__Lr 0xF8
120-
ASMCONSTANTS_C_ASSERT(OFFSETOF__CONTEXT__Lr == offsetof(T_CONTEXT, Lr));
121-
122-
#define OFFSETOF__CONTEXT__Sp 0x100
123-
ASMCONSTANTS_C_ASSERT(OFFSETOF__CONTEXT__Sp == offsetof(T_CONTEXT, Sp));
124-
125-
#define OFFSETOF__CONTEXT__Pc 0x108
126-
ASMCONSTANTS_C_ASSERT(OFFSETOF__CONTEXT__Pc == offsetof(T_CONTEXT, Pc));
127-
128-
// Floating point registers V[0..31] start at 0x110, each is 16 bytes (NEON128)
129-
// Non-volatile FP registers are V8-V15 (d8-d15)
130-
#define OFFSETOF__CONTEXT__V0 0x110
131-
ASMCONSTANTS_C_ASSERT(OFFSETOF__CONTEXT__V0 == offsetof(T_CONTEXT, V));
132-
133-
// CONTEXT_FLOATING_POINT_BIT is bit 2 in ContextFlags
134-
#define CONTEXT_FLOATING_POINT_BIT 2
135-
136110
#define OFFSETOF__DynamicHelperStubArgs__Constant1 0x0
137111
ASMCONSTANTS_C_ASSERT(OFFSETOF__DynamicHelperStubArgs__Constant1
138112
== offsetof(DynamicHelperStubArgs, Constant1));

src/coreclr/vm/arm64/asmhelpers.S

Lines changed: 1 addition & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -586,11 +586,9 @@ NESTED_END OnCallCountThresholdReachedStub, _TEXT
586586
NESTED_ENTRY JIT_Patchpoint, _TEXT, NoHandler
587587
PROLOG_WITH_TRANSITION_BLOCK
588588

589-
// x0 = pointer to TransitionBlock
590-
add x0, sp, #__PWTB_TransitionBlock
589+
add x0, sp, #__PWTB_TransitionBlock // TransitionBlock *
591590
bl C_FUNC(JIT_PatchpointWorkerWorkerWithPolicy)
592591

593-
// If we return, restore all registers and return to caller
594592
EPILOG_WITH_TRANSITION_BLOCK_RETURN
595593
NESTED_END JIT_Patchpoint, _TEXT
596594

@@ -2899,62 +2897,3 @@ NESTED_ENTRY IL_Rethrow, _TEXT, NoHandler
28992897
brk #0
29002898
NESTED_END IL_Rethrow, _TEXT
29012899

2902-
// ------------------------------------------------------------------
2903-
// ClrRestoreNonvolatileContextWorker
2904-
//
2905-
// Restores registers based on ContextFlags and jumps to the target IP.
2906-
// When CONTEXT_INTEGER is set, restores ALL integer registers (x0-x28)
2907-
// because exception handling needs x0 (exception object).
2908-
// When CONTEXT_FLOATING_POINT is set, restores non-volatile FP regs (d8-d15).
2909-
//
2910-
// Arguments:
2911-
// x0 - pointer to CONTEXT structure
2912-
//
2913-
// Does not return - jumps directly to the Pc stored in the CONTEXT
2914-
// ------------------------------------------------------------------
2915-
LEAF_ENTRY ClrRestoreNonvolatileContextWorker, _TEXT
2916-
2917-
// Save context pointer in x16 since we'll overwrite x0
2918-
mov x16, x0
2919-
2920-
// Check ContextFlags to see if we should restore floating point registers
2921-
ldr w17, [x16, #OFFSETOF__CONTEXT__ContextFlags]
2922-
tbz w17, #CONTEXT_FLOATING_POINT_BIT, LOCAL_LABEL(SkipFloatingPointRestore)
2923-
2924-
// Restore non-volatile FP registers d8-d15 (lower 64 bits of v8-v15)
2925-
// V8 is at OFFSETOF__CONTEXT__V0 + 8*16 = 0x110 + 0x80 = 0x190
2926-
ldp q8, q9, [x16, #(OFFSETOF__CONTEXT__V0 + 8*16)]
2927-
ldp q10, q11, [x16, #(OFFSETOF__CONTEXT__V0 + 10*16)]
2928-
ldp q12, q13, [x16, #(OFFSETOF__CONTEXT__V0 + 12*16)]
2929-
ldp q14, q15, [x16, #(OFFSETOF__CONTEXT__V0 + 14*16)]
2930-
2931-
LOCAL_LABEL(SkipFloatingPointRestore):
2932-
// Check ContextFlags to see if we should restore integer registers
2933-
tbz w17, #CONTEXT_INTEGER_BIT, LOCAL_LABEL(SkipIntegerRestore)
2934-
2935-
// Restore argument registers x0-x7 (exception handling needs x0 for exception object)
2936-
// and non-volatile registers x19-x28
2937-
ldp x0, x1, [x16, #OFFSETOF__CONTEXT__X0]
2938-
ldp x2, x3, [x16, #(OFFSETOF__CONTEXT__X0 + 16)]
2939-
ldp x4, x5, [x16, #(OFFSETOF__CONTEXT__X0 + 32)]
2940-
ldp x6, x7, [x16, #(OFFSETOF__CONTEXT__X0 + 48)]
2941-
// Skip x8-x18: x8-x15 are scratch, x16-x17 we're using, x18 is platform reserved
2942-
ldp x19, x20, [x16, #OFFSETOF__CONTEXT__X19]
2943-
ldp x21, x22, [x16, #(OFFSETOF__CONTEXT__X19 + 16)]
2944-
ldp x23, x24, [x16, #(OFFSETOF__CONTEXT__X19 + 32)]
2945-
ldp x25, x26, [x16, #(OFFSETOF__CONTEXT__X19 + 48)]
2946-
ldp x27, x28, [x16, #(OFFSETOF__CONTEXT__X19 + 64)]
2947-
2948-
LOCAL_LABEL(SkipIntegerRestore):
2949-
// Restore fp (x29) and lr (x30)
2950-
ldp fp, lr, [x16, #OFFSETOF__CONTEXT__Fp]
2951-
2952-
// Load Sp and Pc into scratch registers (after all other loads)
2953-
ldr x17, [x16, #OFFSETOF__CONTEXT__Sp]
2954-
ldr x16, [x16, #OFFSETOF__CONTEXT__Pc]
2955-
2956-
// Set sp and jump to target
2957-
mov sp, x17
2958-
br x16
2959-
2960-
LEAF_END ClrRestoreNonvolatileContextWorker, _TEXT

src/coreclr/vm/arm64/asmhelpers.asm

Lines changed: 1 addition & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -1013,11 +1013,9 @@ __HelperNakedFuncName SETS "$helper":CC:"Naked"
10131013
NESTED_ENTRY JIT_Patchpoint
10141014
PROLOG_WITH_TRANSITION_BLOCK
10151015

1016-
; x0 = pointer to TransitionBlock
1017-
add x0, sp, #__PWTB_TransitionBlock
1016+
add x0, sp, #__PWTB_TransitionBlock ; TransitionBlock *
10181017
bl JIT_PatchpointWorkerWorkerWithPolicy
10191018

1020-
; If we return, restore all registers and return to caller
10211019
EPILOG_WITH_TRANSITION_BLOCK_RETURN
10221020
NESTED_END
10231021

@@ -3185,63 +3183,5 @@ CopyLoop
31853183
brk #0
31863184
NESTED_END IL_Rethrow
31873185

3188-
; ------------------------------------------------------------------
3189-
; ClrRestoreNonvolatileContextWorker
3190-
;
3191-
; Restores registers based on ContextFlags and jumps to PC.
3192-
; When CONTEXT_INTEGER is set, restores ALL integer registers (x0-x28)
3193-
; because exception handling needs x0 (exception object).
3194-
; When CONTEXT_FLOATING_POINT is set, restores non-volatile FP regs (d8-d15).
3195-
;
3196-
; x0 - pointer to CONTEXT structure
3197-
; x1 - unused (SSP, not used on ARM64)
3198-
; ------------------------------------------------------------------
3199-
LEAF_ENTRY ClrRestoreNonvolatileContextWorker
3200-
3201-
; Save CONTEXT pointer in x16 before we potentially clobber x0
3202-
mov x16, x0
3203-
3204-
; Check if CONTEXT_FLOATING_POINT bit is set (bit 2)
3205-
ldr w17, [x16, #OFFSETOF__CONTEXT__ContextFlags]
3206-
tbz w17, #2, SkipFloatingPointRestore
3207-
3208-
; Restore non-volatile FP registers d8-d15 (full q8-q15)
3209-
; V8 is at OFFSETOF__CONTEXT__V0 + 8*16 = 0x110 + 0x80 = 0x190
3210-
ldp q8, q9, [x16, #(OFFSETOF__CONTEXT__V0 + 128)]
3211-
ldp q10, q11, [x16, #(OFFSETOF__CONTEXT__V0 + 160)]
3212-
ldp q12, q13, [x16, #(OFFSETOF__CONTEXT__V0 + 192)]
3213-
ldp q14, q15, [x16, #(OFFSETOF__CONTEXT__V0 + 224)]
3214-
3215-
SkipFloatingPointRestore
3216-
; Check if CONTEXT_INTEGER bit is set
3217-
tbz w17, #1, SkipIntegerRestore ; CONTEXT_INTEGER_BIT = 1
3218-
3219-
; Restore argument registers x0-x7 (exception handling needs x0 for exception object)
3220-
; and non-volatile registers x19-x28
3221-
ldp x0, x1, [x16, #OFFSETOF__CONTEXT__X0]
3222-
ldp x2, x3, [x16, #(OFFSETOF__CONTEXT__X0 + 16)]
3223-
ldp x4, x5, [x16, #(OFFSETOF__CONTEXT__X0 + 32)]
3224-
ldp x6, x7, [x16, #(OFFSETOF__CONTEXT__X0 + 48)]
3225-
; Skip x8-x18: x8-x15 are scratch, x16-x17 we're using, x18 is platform reserved
3226-
ldp x19, x20, [x16, #OFFSETOF__CONTEXT__X19]
3227-
ldp x21, x22, [x16, #(OFFSETOF__CONTEXT__X19 + 16)]
3228-
ldp x23, x24, [x16, #(OFFSETOF__CONTEXT__X19 + 32)]
3229-
ldp x25, x26, [x16, #(OFFSETOF__CONTEXT__X19 + 48)]
3230-
ldp x27, x28, [x16, #(OFFSETOF__CONTEXT__X19 + 64)]
3231-
3232-
SkipIntegerRestore
3233-
; Restore fp and lr
3234-
ldp fp, lr, [x16, #OFFSETOF__CONTEXT__Fp]
3235-
3236-
; Load Sp and Pc (x16 will be overwritten)
3237-
ldr x17, [x16, #OFFSETOF__CONTEXT__Pc]
3238-
ldr x16, [x16, #OFFSETOF__CONTEXT__Sp]
3239-
3240-
; Set sp and jump
3241-
mov sp, x16
3242-
br x17
3243-
3244-
LEAF_END ClrRestoreNonvolatileContextWorker
3245-
32463186
; Must be at very end of file
32473187
END

src/coreclr/vm/arm64/asmmacros.h

Lines changed: 0 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -253,29 +253,6 @@ OFFSETOF__ee_alloc_context EQU OFFSETOF__RuntimeThreadLocals__ee_alloc_context
253253
add $Target, sp, #192
254254
MEND
255255

256-
; Epilog for PUSH_COOP_PINVOKE_FRAME_WITH_FLOATS - restores FP callee-saved and returns
257-
MACRO
258-
POP_COOP_PINVOKE_FRAME_WITH_FLOATS_RETURN
259-
260-
; Restore FP callee-saved registers (d8-d15) from sp+0
261-
ldp d8, d9, [sp, #0]
262-
ldp d10, d11, [sp, #16]
263-
ldp d12, d13, [sp, #32]
264-
ldp d14, d15, [sp, #48]
265-
266-
; Deallocate space for FloatArgumentRegisters + FP callee-saved
267-
EPILOG_STACK_FREE 192
268-
269-
; Restore callee-saved registers
270-
EPILOG_RESTORE_REG_PAIR x27, x28, #80
271-
EPILOG_RESTORE_REG_PAIR x25, x26, #64
272-
EPILOG_RESTORE_REG_PAIR x23, x24, #48
273-
EPILOG_RESTORE_REG_PAIR x21, x22, #32
274-
EPILOG_RESTORE_REG_PAIR x19, x20, #16
275-
276-
EPILOG_RESTORE_REG_PAIR_RET fp, lr, #176!
277-
MEND
278-
279256
#define GC_ALLOC_FINALIZE 1
280257

281258
;-----------------------------------------------------------------------------

0 commit comments

Comments
 (0)