@@ -106,14 +106,21 @@ void CodeGen::genEmitGSCookieCheck(bool pushReg)
106
106
// we are generating GS cookie check after a GT_RETURN block.
107
107
// Note: On Amd64 System V RDX is an arg register - REG_ARG_2 - as well
108
108
// as return register for two-register-returned structs.
109
+ #ifdef TARGET_X86
110
+ // Note: ARG_0 can be REG_ASYNC_CONTINUATION_RET
111
+ // we will check for that later if we end up saving/restoring this.
112
+ regGSCheck = REG_ARG_0;
113
+ regNumber regGSCheckAlternative = REG_ARG_1;
114
+ #else
115
+ // these cannot be a part of any kind of return
116
+ regGSCheck = REG_R8;
117
+ regNumber regGSCheckAlternative = REG_R9;
118
+ #endif
119
+
109
120
if (compiler->lvaKeepAliveAndReportThis () && compiler->lvaGetDesc (compiler->info .compThisArg )->lvIsInReg () &&
110
- (compiler->lvaGetDesc (compiler->info .compThisArg )->GetRegNum () == REG_ARG_0 ))
121
+ (compiler->lvaGetDesc (compiler->info .compThisArg )->GetRegNum () == regGSCheck ))
111
122
{
112
- regGSCheck = REG_ARG_1;
113
- }
114
- else
115
- {
116
- regGSCheck = REG_ARG_0;
123
+ regGSCheck = regGSCheckAlternative;
117
124
}
118
125
}
119
126
else
@@ -158,6 +165,14 @@ void CodeGen::genEmitGSCookieCheck(bool pushReg)
158
165
{
159
166
// AOT case - GS cookie value needs to be accessed through an indirection.
160
167
168
+ // if we use the continuation reg, the pop/push requires no-GC
169
+ // this can happen only when AOT supports async on x86
170
+ if (compiler->compIsAsync () && (regGSCheck == REG_ASYNC_CONTINUATION_RET))
171
+ {
172
+ regMaskGSCheck = RBM_ASYNC_CONTINUATION_RET;
173
+ GetEmitter ()->emitDisableGC ();
174
+ }
175
+
161
176
pushedRegs = genPushRegs (regMaskGSCheck, &byrefPushedRegs, &norefPushedRegs);
162
177
163
178
instGen_Set_Reg_To_Imm (EA_HANDLE_CNS_RELOC, regGSCheck, (ssize_t )compiler->gsGlobalSecurityCookieAddr );
0 commit comments