Skip to content

Commit 20aeb3a

Browse files
authored
GH-143026: Fix assertion error in executor management. (GH-143104)
1 parent 25c294b commit 20aeb3a

File tree

5 files changed

+28
-28
lines changed

5 files changed

+28
-28
lines changed

Include/internal/pycore_object.h

Lines changed: 0 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -252,25 +252,6 @@ _Py_DECREF_SPECIALIZED(PyObject *op, const destructor destruct)
252252
}
253253
}
254254

255-
static inline void
256-
_Py_DECREF_NO_DEALLOC(PyObject *op)
257-
{
258-
if (_Py_IsImmortal(op)) {
259-
_Py_DECREF_IMMORTAL_STAT_INC();
260-
return;
261-
}
262-
_Py_DECREF_STAT_INC();
263-
#ifdef Py_REF_DEBUG
264-
_Py_DEC_REFTOTAL(PyInterpreterState_Get());
265-
#endif
266-
op->ob_refcnt--;
267-
#ifdef Py_DEBUG
268-
if (op->ob_refcnt <= 0) {
269-
_Py_FatalRefcountError("Expected a positive remaining refcount");
270-
}
271-
#endif
272-
}
273-
274255
#else
275256
// TODO: implement Py_DECREF specializations for Py_GIL_DISABLED build
276257
static inline void
@@ -279,12 +260,6 @@ _Py_DECREF_SPECIALIZED(PyObject *op, const destructor destruct)
279260
Py_DECREF(op);
280261
}
281262

282-
static inline void
283-
_Py_DECREF_NO_DEALLOC(PyObject *op)
284-
{
285-
Py_DECREF(op);
286-
}
287-
288263
static inline int
289264
_Py_REF_IS_MERGED(Py_ssize_t ob_ref_shared)
290265
{

Include/internal/pycore_optimizer.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ typedef struct {
2727
uint8_t valid;
2828
uint8_t chain_depth; // Must be big enough for MAX_CHAIN_DEPTH - 1.
2929
bool warm;
30+
uint8_t pending_deletion;
3031
int32_t index; // Index of ENTER_EXECUTOR (if code isn't NULL, below).
3132
_PyBloomFilter bloom;
3233
_PyExecutorLinkListNode links;

Lib/test/test_capi/test_opt.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3114,6 +3114,26 @@ def testfunc(n):
31143114
self.assertNotIn("_POP_TOP_INT", uops)
31153115
self.assertIn("_POP_TOP_NOP", uops)
31163116

3117+
def test_143026(self):
3118+
# https://github.com/python/cpython/issues/143026
3119+
3120+
result = script_helper.run_python_until_end('-c', textwrap.dedent("""
3121+
import gc
3122+
thresholds = gc.get_threshold()
3123+
try:
3124+
gc.set_threshold(1)
3125+
3126+
def f1():
3127+
for i in range(5000):
3128+
globals()[''] = i
3129+
3130+
f1()
3131+
finally:
3132+
gc.set_threshold(*thresholds)
3133+
"""), PYTHON_JIT="1")
3134+
self.assertEqual(result[0].rc, 0, result)
3135+
3136+
31173137
def global_identity(x):
31183138
return x
31193139

Python/optimizer.c

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -310,7 +310,7 @@ _Py_ClearExecutorDeletionList(PyInterpreterState *interp)
310310
while (ts) {
311311
_PyExecutorObject *current = (_PyExecutorObject *)ts->current_executor;
312312
if (current != NULL) {
313-
_Py_DECREF_NO_DEALLOC((PyObject *)current);
313+
Py_DECREF((PyObject *)current);
314314
}
315315
ts = ts->next;
316316
}
@@ -320,6 +320,10 @@ _Py_ClearExecutorDeletionList(PyInterpreterState *interp)
320320
static void
321321
add_to_pending_deletion_list(_PyExecutorObject *self)
322322
{
323+
if (self->vm_data.pending_deletion) {
324+
return;
325+
}
326+
self->vm_data.pending_deletion = 1;
323327
PyInterpreterState *interp = PyInterpreterState_Get();
324328
self->vm_data.links.previous = NULL;
325329
self->vm_data.links.next = interp->executor_deletion_list_head;
@@ -627,7 +631,7 @@ _PyJit_translate_single_bytecode_to_trace(
627631
uint32_t target = 0;
628632

629633
target = Py_IsNone((PyObject *)old_code)
630-
? (int)(target_instr - _Py_INTERPRETER_TRAMPOLINE_INSTRUCTIONS_PTR)
634+
? (uint32_t)(target_instr - _Py_INTERPRETER_TRAMPOLINE_INSTRUCTIONS_PTR)
631635
: INSTR_IP(target_instr, old_code);
632636

633637
// Rewind EXTENDED_ARG so that we see the whole thing.
@@ -1666,6 +1670,7 @@ void
16661670
_Py_ExecutorInit(_PyExecutorObject *executor, const _PyBloomFilter *dependency_set)
16671671
{
16681672
executor->vm_data.valid = true;
1673+
executor->vm_data.pending_deletion = 0;
16691674
for (int i = 0; i < _Py_BLOOM_FILTER_WORDS; i++) {
16701675
executor->vm_data.bloom.bits[i] = dependency_set->bits[i];
16711676
}

Tools/cases_generator/analyzer.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -673,7 +673,6 @@ def has_error_without_pop(op: parser.CodeDef) -> bool:
673673
"_PyUnicode_Equal",
674674
"_PyUnicode_JoinArray",
675675
"_Py_CHECK_EMSCRIPTEN_SIGNALS_PERIODICALLY",
676-
"_Py_DECREF_NO_DEALLOC",
677676
"_Py_ID",
678677
"_Py_IsImmortal",
679678
"_Py_IsOwnedByCurrentThread",

0 commit comments

Comments
 (0)