Uh oh!
There was an error while loading. Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork 5.6k
JIT: Enable implicit tailcalls for tail-awaits#129255
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
Uh oh!
There was an error while loading. Please reload this page.
Changes from all commits
dcda86e2eb525c6f6428cd4603a84fc43ab653e9820d7296dFile filter
Filter by extension
Conversations
Uh oh!
There was an error while loading. Please reload this page.
Jump to
Uh oh!
There was an error while loading. Please reload this page.
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -66,7 +66,6 @@ var_types Compiler::impImportCall(OPCODE opcode, | ||
| // to see any imperative security. | ||
| // Reverse P/Invokes need a call to CORINFO_HELP_JIT_REVERSE_PINVOKE_EXIT | ||
| // at the end, so tailcalls should be disabled. | ||
| // Async methods need to restore contexts, so tailcalls should be disabled. | ||
| if (info.compFlags & CORINFO_FLG_SYNCH) | ||
| { | ||
| canTailCall = false; | ||
| @@ -77,11 +76,6 @@ var_types Compiler::impImportCall(OPCODE opcode, | ||
| canTailCall = false; | ||
| szCanTailCallFailReason = "Caller is Reverse P/Invoke"; | ||
| } | ||
| else if (compIsAsync()) | ||
| { | ||
| canTailCall = false; | ||
| szCanTailCallFailReason = "Caller is async method"; | ||
| } | ||
| #if !FEATURE_FIXED_OUT_ARGS | ||
| else if (info.compIsVarArgs) | ||
| { | ||
| @@ -1141,6 +1135,18 @@ var_types Compiler::impImportCall(OPCODE opcode, | ||
| BADCODE("Stack should be empty after tailcall"); | ||
| } | ||
| // Async methods need to restore contexts, so in general tailcalls | ||
| // should be disabled. The exception is a tail await: for those the JIT | ||
| // directly returns the callee's continuation to the caller and no | ||
| // context needs to be restored, so the async call can be turned into a | ||
| // real tail call. Any other tail call candidate in an async method | ||
| // must be disqualified. | ||
| if (canTailCall && compIsAsync() && (!call->AsCall()->IsAsync() || !call->AsCall()->GetAsyncInfo().IsTailAwait)) | ||
| { | ||
| canTailCall = false; | ||
| szCanTailCallFailReason = "Caller is async method and call is not a tail await"; | ||
| } | ||
jakobbotsch marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. jakobbotsch marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. jakobbotsch marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. | ||
| // For opportunistic tailcalls we allow implicit widening, i.e. tailcalls from int32 -> int16, since the | ||
| // managed calling convention dictates that the callee widens the value. For explicit tailcalls or async | ||
| // functions we don't want to require this detail of the calling convention to bubble up to helper | ||
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.