mirror of
https://github.com/python/cpython.git
synced 2026-04-14 15:50:50 +00:00
gh-142183: Cache one datachunk per tstate to prevent alloc/dealloc thrashing (#145789)
Cache one datachunk per tstate to prevent alloc/dealloc thrashing when repeatedly hitting the same call depth at exactly the wrong boundary. --------- Co-authored-by: blurb-it[bot] <43283697+blurb-it[bot]@users.noreply.github.com>
This commit is contained in:
parent
4722202a1a
commit
706fd4ec08
3 changed files with 28 additions and 4 deletions
|
|
@ -1564,6 +1564,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->current_executor = NULL;
|
||||
tstate->jit_exit = NULL;
|
||||
|
|
@ -1714,6 +1715,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
|
||||
|
|
@ -3045,9 +3051,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 -
|
||||
|
|
@ -3083,12 +3100,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);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue