Uh oh!
There was an error while loading. Please reload this page.
GH-118095: Make invalidating and clearing executors memory safe - #118459
Conversation
markshannon
commented
May 1, 2024
There are no new tests as I can't see a way to test this, especially the out-of-memory checks. |
| const _PyExecutorObject *side = executor->exits[i].executor; | ||
| executor->exits[i].temperature = initial_unreachable_backoff_counter(); | ||
| if (side != cold) { | ||
| executor->exits[i].executor = cold; |
There was a problem hiding this comment.
Looks like the executor owns the reference to exits[i].executor when that is not equal to the cold exit, but not when it is equal. That is potentially confusing.
There was a problem hiding this comment.
It owns a reference in both cases, it is just that cold exit executors are immortal, so we can be lose with the refcounting.
| _Py_ExecutorClear(exec); | ||
| unlink_executor(exec); | ||
| if (no_memory) { | ||
| exec->vm_data.valid = 0; |
There was a problem hiding this comment.
It's really ok to just skip clearing exec in this case?
There was a problem hiding this comment.
We never execute an executor with valid == 0, so it does what says and invalidates the dependent executor.
It might delay later re-optimizations and defer reclaiming some objects.
We've hit a memory error at this point, so the program is probably dying anyway.
There was a problem hiding this comment.
We've hit a memory error at this point, so the program is probably dying anyway.
That feels like a dangerous assumption -- an app may have a gigabyte array of temp data somewhere that it can free and retry.
markshannon
commented
May 1, 2024
The 32 bit Windows Jit build failure is probably unrelated as it has been flaky lately. |
bedevere-bot
commented
May 1, 2024
|
| exec->vm_data.valid = 0; | ||
| } | ||
| } | ||
| if (is_invalidation) { |
There was a problem hiding this comment.
I don't see any calls where this flag is passed as 0, so maybe the flag argument is no longer needed?
This fixes a crash when an executor forms a reference cycle with itself.
This bug has been present for a while, but was only exposed by #118420.
Also fixes another latent bug in
_Py_Executors_InvalidateDependency, where clearing one executor could clear another leaving the iteration variable pointing to freed memory.The
three main changesamongst the main changes are:_Py_Executors_InvalidateDependencyRESUMEtoRESUME_CHECK: ConvertingENTER_EXECUTORtoRESUME_CHECKwould loose the executor.