Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork 35.2k
gh-139922: Tail calling for MSVC (VS 2026)#139962
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
82d125932486589ac430d085c1d70b12f2eacf48f535e96c1d7737e986f19cf40013cc48db59ebc9d23c19e02c266ec77450f8ff75d908b40786133e699d4066d6c395584fec7eeeaa86f3d52581618e22008d1d7c8438868b41cfc7316fc9214d5b52c6f9c34d98d37ec626ead1c5a24155337File 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 |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| Allow building CPython with the tail calling interpreter on Visual Studio 2026 MSVC. This provides a performance gain over the prior interpreter for MSVC. Patch by Ken Jin, Brandt Bucher, and Chris Eibl. With help from the MSVC team including Hulon Jenkins. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -598,7 +598,9 @@ | ||
| <ClCompile Include="..\Python\bltinmodule.c" /> | ||
| <ClCompile Include="..\Python\bootstrap_hash.c" /> | ||
| <ClCompile Include="..\Python\brc.c" /> | ||
| <ClCompile Include="..\Python\ceval.c" /> | ||
| <ClCompile Include="..\Python\ceval.c"> | ||
| <AdditionalOptions Condition="'$(UseTailCallInterp)' == 'true' and $(PlatformToolset) != 'ClangCL'">/std:clatest %(AdditionalOptions)</AdditionalOptions> | ||
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. What happens if we pass this option to clang-cl? Does it break? Any possibility of passing a specific /std:c rather than "latest"? MemberAuthor 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. So I've worked with Chris on this and apparently it builds with clang-cl still the last time I checked with him? @chris-eibl
| ||
| </ClCompile> | ||
| <ClCompile Include="..\Python\codecs.c" /> | ||
| <ClCompile Include="..\Python\codegen.c" /> | ||
| <ClCompile Include="..\Python\compile.c" /> | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -960,10 +960,12 @@ extern void _PyUOpPrint(const _PyUOpInstruction *uop); | ||
| PyObject ** | ||
| _PyObjectArray_FromStackRefArray(_PyStackRef *input, Py_ssize_t nargs, PyObject **scratch) | ||
| _PyObjectArray_FromStackRefArray(_PyThreadStateImpl *_tstate, _PyStackRef *restrict input, Py_ssize_t nargs) | ||
zooba marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. | ||
| { | ||
| PyObject **result; | ||
| if (nargs > MAX_STACKREF_SCRATCH) { | ||
| /* +1 because vectorcall might use -1 to write self */ | ||
| PyObject **target = _tstate->stackref_scratch + _tstate->n_stackref_scratch_used + nargs + 1; | ||
| if (target > _tstate->stackref_scratch + MAX_STACKREF_SCRATCH) { | ||
| // +1 in case PY_VECTORCALL_ARGUMENTS_OFFSET is set. | ||
| result = PyMem_Malloc((nargs + 1) * sizeof(PyObject *)); | ||
| if (result == NULL) { | ||
| @@ -972,7 +974,9 @@ _PyObjectArray_FromStackRefArray(_PyStackRef *input, Py_ssize_t nargs, PyObject | ||
| result++; | ||
| } | ||
| else { | ||
| result = scratch; | ||
| result = _tstate->stackref_scratch + _tstate->n_stackref_scratch_used; | ||
| _tstate->n_stackref_scratch_used += (int)nargs + 1; | ||
| assert(_tstate->n_stackref_scratch_used < MAX_STACKREF_SCRATCH); | ||
| } | ||
| for (int i = 0; i < nargs; i++) { | ||
| result[i] = PyStackRef_AsPyObjectBorrow(input[i]); | ||
| @@ -981,10 +985,15 @@ _PyObjectArray_FromStackRefArray(_PyStackRef *input, Py_ssize_t nargs, PyObject | ||
| } | ||
| void | ||
| _PyObjectArray_Free(PyObject **array, PyObject **scratch) | ||
| _PyObjectArray_Free(_PyThreadStateImpl *_tstate, PyObject **array, Py_ssize_t nargs, PyObject **temp_arr) | ||
| { | ||
| if (array != scratch) { | ||
| PyMem_Free(array); | ||
| /* -1 because we +1 previously */ | ||
| if (array == temp_arr) { | ||
| _tstate->n_stackref_scratch_used -= ((int)nargs + 1); | ||
| assert(_tstate->n_stackref_scratch_used >= 0); | ||
| } | ||
| else { | ||
| PyMem_Free(array-1); | ||
| } | ||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
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.
How arbitrary is this amount? What is the usual amount of space required for conversions?
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.
We used to arbitrarily always consume 10 PyObject/PyStackRef per call. Meaning even if you had a single item, the whole 10 slot space would be used.