diff --git a/Doc/data/python3.13.abi b/Doc/data/python3.13.abi
index d02189517317d7..e0588167eba04e 100644
--- a/Doc/data/python3.13.abi
+++ b/Doc/data/python3.13.abi
@@ -1670,7 +1670,7 @@
-
+
@@ -1688,7 +1688,7 @@
-
+
@@ -1703,7 +1703,7 @@
-
+
@@ -1737,10 +1737,10 @@
-
+
-
+
@@ -1828,11 +1828,11 @@
-
+
-
+
@@ -1844,14 +1844,14 @@
-
+
-
+
@@ -1870,7 +1870,7 @@
-
+
@@ -1898,7 +1898,7 @@
-
+
@@ -1940,7 +1940,7 @@
-
+
@@ -1957,7 +1957,7 @@
-
+
@@ -1974,7 +1974,7 @@
-
+
@@ -2001,13 +2001,13 @@
-
+
-
+
@@ -2015,7 +2015,7 @@
-
+
@@ -2100,7 +2100,7 @@
-
+
@@ -2125,7 +2125,7 @@
-
+
@@ -2164,7 +2164,7 @@
-
+
@@ -3393,7 +3393,7 @@
-
+
@@ -3447,7 +3447,7 @@
-
+
@@ -3558,7 +3558,7 @@
-
+
@@ -3567,7 +3567,7 @@
-
+
@@ -3653,7 +3653,7 @@
-
+
@@ -3675,12 +3675,12 @@
-
+
-
+
@@ -3697,7 +3697,7 @@
-
+
@@ -3896,7 +3896,7 @@
-
+
@@ -3973,7 +3973,7 @@
-
+
@@ -4010,7 +4010,7 @@
-
+
@@ -4070,7 +4070,7 @@
-
+
@@ -4817,7 +4817,7 @@
-
+
@@ -4855,7 +4855,7 @@
-
+
@@ -5175,35 +5175,35 @@
-
-
+
+
-
-
-
+
+
+
-
-
+
+
-
-
+
+
-
-
-
+
+
+
-
-
-
+
+
+
-
+
@@ -5261,7 +5261,7 @@
-
+
@@ -5461,7 +5461,7 @@
-
+
@@ -5480,7 +5480,7 @@
-
+
@@ -5665,7 +5665,7 @@
-
+
@@ -5740,7 +5740,7 @@
-
+
@@ -5762,10 +5762,10 @@
-
+
-
+
@@ -5818,7 +5818,7 @@
-
+
@@ -6023,7 +6023,7 @@
-
+
@@ -6140,18 +6140,18 @@
-
+
-
+
-
+
-
+
@@ -6282,8 +6282,8 @@
-
-
+
+
@@ -6331,170 +6331,170 @@
-
-
+
+
-
-
-
-
+
+
+
+
-
-
-
-
-
+
+
+
+
+
-
-
-
+
+
+
-
-
-
-
+
+
+
+
-
-
-
-
+
+
+
+
-
-
-
-
-
+
+
+
+
+
-
-
-
-
-
+
+
+
+
+
-
-
-
-
+
+
+
+
-
-
-
-
-
+
+
+
+
+
-
-
+
+
-
-
-
-
+
+
+
+
-
-
-
-
+
+
+
+
-
-
-
-
+
+
+
+
-
-
-
-
+
+
+
+
-
-
-
-
+
+
+
+
-
-
-
-
-
+
+
+
+
+
-
-
-
-
+
+
+
+
-
-
+
+
-
-
-
+
+
+
-
-
-
+
+
+
-
-
-
-
+
+
+
+
-
-
-
+
+
+
-
-
-
-
+
+
+
+
-
-
-
+
+
+
-
-
+
+
-
-
-
+
+
+
-
-
-
+
+
+
-
-
+
+
-
-
+
+
@@ -6503,11 +6503,11 @@
-
+
-
+
@@ -6848,7 +6848,7 @@
-
+
@@ -6937,7 +6937,7 @@
-
+
@@ -7006,11 +7006,6 @@
-
-
-
-
-
@@ -7107,41 +7102,41 @@
-
-
-
-
+
+
+
+
-
-
-
-
+
+
+
+
-
-
-
-
+
+
+
+
-
-
-
+
+
+
-
-
-
+
+
+
-
-
-
+
+
+
-
+
@@ -7317,7 +7312,7 @@
-
+
@@ -7410,16 +7405,16 @@
-
-
+
+
-
-
+
+
-
+
@@ -7432,6 +7427,11 @@
+
+
+
+
+
@@ -7453,7 +7453,7 @@
-
+
@@ -7542,7 +7542,7 @@
-
+
@@ -7648,7 +7648,7 @@
-
+
@@ -7661,7 +7661,7 @@
-
+
@@ -7698,11 +7698,6 @@
-
-
-
-
-
@@ -7745,7 +7740,7 @@
-
+
@@ -7919,6 +7914,11 @@
+
+
+
+
+
@@ -7941,7 +7941,7 @@
-
+
@@ -7969,7 +7969,7 @@
-
+
@@ -7996,7 +7996,7 @@
-
+
@@ -8055,7 +8055,7 @@
-
+
@@ -8189,7 +8189,7 @@
-
+
@@ -8201,12 +8201,12 @@
-
-
+
+
-
+
@@ -8619,7 +8619,7 @@
-
+
@@ -9207,13 +9207,13 @@
-
+
-
+
-
+
@@ -9407,7 +9407,7 @@
-
+
@@ -9485,7 +9485,7 @@
-
+
@@ -9500,7 +9500,7 @@
-
+
@@ -9519,7 +9519,7 @@
-
+
@@ -9579,30 +9579,30 @@
-
-
-
+
+
+
-
-
+
+
-
-
+
+
-
-
-
+
+
+
-
-
+
+
-
+
@@ -9630,7 +9630,7 @@
-
+
@@ -9675,27 +9675,27 @@
-
-
-
+
+
+
-
-
-
+
+
+
-
-
-
+
+
+
-
-
+
+
-
+
@@ -9715,7 +9715,7 @@
-
+
@@ -9880,114 +9880,114 @@
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
-
-
-
+
+
+
+
+
-
-
-
-
+
+
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
-
+
+
+
-
-
+
+
-
-
+
+
-
-
-
+
+
+
-
-
-
-
+
+
+
+
-
-
-
-
-
+
+
+
+
+
-
-
-
+
+
+
-
-
+
+
-
-
+
+
-
-
-
+
+
+
-
-
-
+
+
+
-
-
-
-
-
+
+
+
+
+
-
+
@@ -10005,7 +10005,7 @@
-
+
@@ -10027,7 +10027,7 @@
-
+
@@ -10689,7 +10689,7 @@
-
+
@@ -10703,7 +10703,7 @@
-
+
@@ -10759,7 +10759,7 @@
-
+
@@ -11892,7 +11892,7 @@
-
+
@@ -11977,7 +11977,7 @@
-
+
@@ -12049,7 +12049,7 @@
-
+
@@ -13346,7 +13346,7 @@
-
+
@@ -13385,7 +13385,7 @@
-
+
@@ -13444,10 +13444,10 @@
-
+
-
+
@@ -14713,29 +14713,29 @@
-
+
-
+
-
+
-
+
-
+
-
-
+
+
-
-
+
+
@@ -14819,7 +14819,7 @@
-
+
@@ -14943,6 +14943,9 @@
+
+
+
@@ -14973,7 +14976,7 @@
-
+
@@ -17251,10 +17254,10 @@
-
+
-
+
@@ -19705,7 +19708,7 @@
-
+
@@ -19713,7 +19716,7 @@
-
+
@@ -19932,7 +19935,7 @@
-
+
@@ -20143,10 +20146,10 @@
-
+
-
+
@@ -20998,7 +21001,7 @@
-
+
@@ -21275,17 +21278,17 @@
-
+
-
+
-
+
-
+
@@ -22618,7 +22621,7 @@
-
+
@@ -23145,7 +23148,7 @@
-
+
@@ -23207,7 +23210,7 @@
-
+
@@ -23258,7 +23261,7 @@
-
+
@@ -23283,7 +23286,7 @@
-
+
@@ -23460,14 +23463,14 @@
-
+
-
+
@@ -23476,7 +23479,7 @@
-
+
@@ -23496,7 +23499,7 @@
-
+
@@ -23530,7 +23533,7 @@
-
+
@@ -23598,7 +23601,7 @@
-
+
@@ -23753,13 +23756,13 @@
-
+
-
+
@@ -23900,7 +23903,7 @@
-
+
@@ -23944,7 +23947,7 @@
-
+
@@ -24425,7 +24428,7 @@
-
+
@@ -24564,7 +24567,7 @@
-
+
@@ -24653,7 +24656,7 @@
-
+
@@ -25164,7 +25167,7 @@
-
+
@@ -25253,7 +25256,7 @@
-
+
@@ -25302,7 +25305,7 @@
-
+
@@ -25409,21 +25412,21 @@
-
+
-
+
-
+
-
-
+
+
-
+
-
+
@@ -25571,76 +25574,76 @@
-
-
-
+
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
-
-
+
+
+
+
-
-
-
-
+
+
+
+
-
-
+
+
-
-
+
+
-
-
-
-
+
+
+
+
-
-
+
+
-
-
-
-
-
+
+
+
+
+
-
-
-
-
+
+
+
+
@@ -25657,7 +25660,7 @@
-
+
@@ -25737,37 +25740,37 @@
-
-
-
+
+
+
-
-
-
-
-
-
+
+
+
+
+
+
-
-
-
-
+
+
+
+
-
-
-
+
+
+
-
+
-
+
@@ -25892,7 +25895,7 @@
-
+
@@ -25902,7 +25905,7 @@
-
+
@@ -26021,7 +26024,7 @@
-
+
@@ -26042,7 +26045,7 @@
-
+
@@ -26075,7 +26078,7 @@
-
+
@@ -26132,7 +26135,7 @@
-
+
@@ -26186,14 +26189,14 @@
-
+
-
+
@@ -26267,21 +26270,21 @@
-
+
-
+
-
+
-
+
@@ -26290,7 +26293,7 @@
-
+
@@ -26334,7 +26337,7 @@
-
+
@@ -26517,116 +26520,116 @@
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
-
-
+
+
+
+
-
-
-
+
+
+
-
-
+
+
-
-
-
+
+
+
-
-
+
+
-
-
-
+
+
+
-
+
-
+
-
-
-
+
+
+
-
-
-
-
+
+
+
+
-
-
-
-
-
+
+
+
+
+
-
-
-
-
-
+
+
+
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
-
-
-
-
+
+
+
+
+
+
-
-
+
+
-
-
-
+
+
+
-
+
-
+
@@ -26910,31 +26913,31 @@
-
-
-
-
+
+
+
+
-
-
-
-
-
+
+
+
+
+
-
-
+
+
-
+
-
+
-
+
@@ -27064,7 +27067,7 @@
-
+
@@ -27085,7 +27088,7 @@
-
+
@@ -27192,7 +27195,7 @@
-
+
@@ -27219,7 +27222,7 @@
-
+
@@ -27369,7 +27372,7 @@
-
+
@@ -27439,44 +27442,44 @@
-
-
-
-
+
+
+
+
-
-
-
-
+
+
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
-
+
+
+
-
+
-
+
@@ -27510,7 +27513,7 @@
-
+
@@ -27519,7 +27522,7 @@
-
+
@@ -27570,7 +27573,7 @@
-
+
@@ -27628,7 +27631,7 @@
-
+
@@ -27637,7 +27640,7 @@
-
+
@@ -27651,7 +27654,7 @@
-
+
@@ -27724,7 +27727,7 @@
-
+
@@ -27736,7 +27739,7 @@
-
+
@@ -27821,7 +27824,7 @@
-
+
@@ -28450,45 +28453,45 @@
-
+
-
+
-
-
+
+
-
-
-
+
+
+
-
-
+
+
-
-
+
+
-
-
-
+
+
+
-
-
+
+
-
-
-
+
+
+
-
+
@@ -28679,69 +28682,69 @@
-
-
+
+
-
-
+
+
-
+
-
-
+
+
-
-
+
+
-
-
-
+
+
+
-
+
-
+
-
-
+
+
-
-
+
+
-
+
-
-
+
+
-
-
-
+
+
+
-
-
+
+
-
+
-
+
@@ -28755,7 +28758,7 @@
-
+
@@ -28952,7 +28955,7 @@
-
+
@@ -29145,7 +29148,7 @@
-
+
@@ -29176,7 +29179,7 @@
-
+
@@ -29184,10 +29187,10 @@
-
+
-
+
@@ -29388,7 +29391,7 @@
-
+
@@ -29412,7 +29415,7 @@
-
+
diff --git a/Include/cpython/pystate.h b/Include/cpython/pystate.h
index f005729fff11b6..72a4969a2ad665 100644
--- a/Include/cpython/pystate.h
+++ b/Include/cpython/pystate.h
@@ -200,6 +200,8 @@ struct _ts {
The PyThreadObject must hold the only reference to this value.
*/
PyObject *threading_local_sentinel;
+
+ _PyStackChunk *datastack_cached_chunk;
};
#ifdef Py_DEBUG
diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-03-11-00-13-59.gh-issue-142183.2iVhJH.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-03-11-00-13-59.gh-issue-142183.2iVhJH.rst
new file mode 100644
index 00000000000000..827224dc71e827
--- /dev/null
+++ b/Misc/NEWS.d/next/Core_and_Builtins/2026-03-11-00-13-59.gh-issue-142183.2iVhJH.rst
@@ -0,0 +1 @@
+Avoid a pathological case where repeated calls at a specific stack depth could be significantly slower.
diff --git a/Python/pystate.c b/Python/pystate.c
index 68e76e4aed5a39..07c69b92d527dc 100644
--- a/Python/pystate.c
+++ b/Python/pystate.c
@@ -1521,6 +1521,7 @@ init_threadstate(_PyThreadStateImpl *_tstate,
tstate->datastack_chunk = NULL;
tstate->datastack_top = NULL;
tstate->datastack_limit = NULL;
+ tstate->datastack_cached_chunk = NULL;
tstate->what_event = -1;
tstate->previous_executor = NULL;
tstate->dict_global_version = 0;
@@ -1655,6 +1656,11 @@ clear_datastack(PyThreadState *tstate)
_PyObject_VirtualFree(chunk, chunk->size);
chunk = prev;
}
+ if (tstate->datastack_cached_chunk != NULL) {
+ _PyObject_VirtualFree(tstate->datastack_cached_chunk,
+ tstate->datastack_cached_chunk->size);
+ tstate->datastack_cached_chunk = NULL;
+ }
}
void
@@ -2934,9 +2940,20 @@ push_chunk(PyThreadState *tstate, int size)
while (allocate_size < (int)sizeof(PyObject*)*(size + MINIMUM_OVERHEAD)) {
allocate_size *= 2;
}
- _PyStackChunk *new = allocate_chunk(allocate_size, tstate->datastack_chunk);
- if (new == NULL) {
- return NULL;
+ _PyStackChunk *new;
+ if (tstate->datastack_cached_chunk != NULL
+ && (size_t)allocate_size <= tstate->datastack_cached_chunk->size)
+ {
+ new = tstate->datastack_cached_chunk;
+ tstate->datastack_cached_chunk = NULL;
+ new->previous = tstate->datastack_chunk;
+ new->top = 0;
+ }
+ else {
+ new = allocate_chunk(allocate_size, tstate->datastack_chunk);
+ if (new == NULL) {
+ return NULL;
+ }
}
if (tstate->datastack_chunk) {
tstate->datastack_chunk->top = tstate->datastack_top -
@@ -2972,12 +2989,17 @@ _PyThreadState_PopFrame(PyThreadState *tstate, _PyInterpreterFrame * frame)
if (base == &tstate->datastack_chunk->data[0]) {
_PyStackChunk *chunk = tstate->datastack_chunk;
_PyStackChunk *previous = chunk->previous;
+ _PyStackChunk *cached = tstate->datastack_cached_chunk;
// push_chunk ensures that the root chunk is never popped:
assert(previous);
tstate->datastack_top = &previous->data[previous->top];
tstate->datastack_chunk = previous;
- _PyObject_VirtualFree(chunk, chunk->size);
tstate->datastack_limit = (PyObject **)(((char *)previous) + previous->size);
+ chunk->previous = NULL;
+ if (cached != NULL) {
+ _PyObject_VirtualFree(cached, cached->size);
+ }
+ tstate->datastack_cached_chunk = chunk;
}
else {
assert(tstate->datastack_top);