Skip to content

Commit 4f5a67a

Browse files
authored
gh-157194: Read the opcode atomically in the specializer (#157195)
1 parent ac430e3 commit 4f5a67a

2 files changed

Lines changed: 7 additions & 2 deletions

File tree

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
Fix a data race in the free-threaded build, reported by ThreadSanitizer,
2+
between the specializer reading an instruction opcode and another thread
3+
writing it. Only reachable when thread-local bytecode is disabled with
4+
``-X tlbc=0``, which makes threads share one copy of the bytecode.

‎Python/specialize.c‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2345,7 +2345,7 @@ _Py_Specialize_BinaryOp(_PyStackRef lhs_st, _PyStackRef rhs_st, _Py_CODEUNIT *in
23452345
assert(_PyOpcode_Caches[BINARY_OP] == INLINE_CACHE_ENTRIES_BINARY_OP);
23462346

23472347
_PyBinaryOpCache *cache = (_PyBinaryOpCache *)(instr + 1);
2348-
if (instr->op.code == BINARY_OP_EXTEND) {
2348+
if (FT_ATOMIC_LOAD_UINT8_RELAXED(instr->op.code) == BINARY_OP_EXTEND) {
23492349
write_ptr(cache->external_cache, NULL);
23502350
}
23512351

@@ -2951,7 +2951,8 @@ _Py_Specialize_GetIter(_PyStackRef iterable, _Py_CODEUNIT *instr)
29512951
void
29522952
_Py_Specialize_Resume(_Py_CODEUNIT *instr, PyThreadState *tstate, _PyInterpreterFrame *frame)
29532953
{
2954-
if (tstate->tracing == 0 && instr->op.code == RESUME) {
2954+
if (tstate->tracing == 0 &&
2955+
FT_ATOMIC_LOAD_UINT8_RELAXED(instr->op.code) == RESUME) {
29552956
if (tstate->interp->jit) {
29562957
PyCodeObject *co = (PyCodeObject *)PyStackRef_AsPyObjectBorrow(frame->f_executable);
29572958
if (co != NULL &&

0 commit comments

Comments
 (0)