diff options
author | Dino Viehland <dinoviehland@meta.com> | 2024-04-22 05:57:05 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-04-22 05:57:05 (GMT) |
commit | 8b541c017ea92040add608b3e0ef8dc85e9e6060 (patch) | |
tree | 880ff7c97041f374d21197b1b486686f2d64c998 /Python | |
parent | 1446024124fb98c3051199760380685f8a2fd127 (diff) | |
download | cpython-8b541c017ea92040add608b3e0ef8dc85e9e6060.zip cpython-8b541c017ea92040add608b3e0ef8dc85e9e6060.tar.gz cpython-8b541c017ea92040add608b3e0ef8dc85e9e6060.tar.bz2 |
gh-112075: Make instance attributes stored in inline "dict" thread safe (#114742)
Make instance attributes stored in inline "dict" thread safe on free-threaded builds
Diffstat (limited to 'Python')
-rw-r--r-- | Python/bytecodes.c | 15 | ||||
-rw-r--r-- | Python/executor_cases.c.h | 10 | ||||
-rw-r--r-- | Python/generated_cases.c.h | 13 | ||||
-rw-r--r-- | Python/specialize.c | 3 |
4 files changed, 17 insertions, 24 deletions
diff --git a/Python/bytecodes.c b/Python/bytecodes.c index c1fbd3c..b7511b9 100644 --- a/Python/bytecodes.c +++ b/Python/bytecodes.c @@ -1947,15 +1947,13 @@ dummy_func( op(_CHECK_ATTR_WITH_HINT, (owner -- owner)) { assert(Py_TYPE(owner)->tp_flags & Py_TPFLAGS_MANAGED_DICT); - PyManagedDictPointer *managed_dict = _PyObject_ManagedDictPointer(owner); - PyDictObject *dict = managed_dict->dict; + PyDictObject *dict = _PyObject_GetManagedDict(owner); DEOPT_IF(dict == NULL); assert(PyDict_CheckExact((PyObject *)dict)); } op(_LOAD_ATTR_WITH_HINT, (hint/1, owner -- attr, null if (oparg & 1))) { - PyManagedDictPointer *managed_dict = _PyObject_ManagedDictPointer(owner); - PyDictObject *dict = managed_dict->dict; + PyDictObject *dict = _PyObject_GetManagedDict(owner); DEOPT_IF(hint >= (size_t)dict->ma_keys->dk_nentries); PyObject *name = GETITEM(FRAME_CO_NAMES, oparg>>1); if (DK_IS_UNICODE(dict->ma_keys)) { @@ -2072,14 +2070,15 @@ dummy_func( op(_GUARD_DORV_NO_DICT, (owner -- owner)) { assert(Py_TYPE(owner)->tp_dictoffset < 0); assert(Py_TYPE(owner)->tp_flags & Py_TPFLAGS_INLINE_VALUES); - DEOPT_IF(_PyObject_ManagedDictPointer(owner)->dict); + DEOPT_IF(_PyObject_GetManagedDict(owner)); DEOPT_IF(_PyObject_InlineValues(owner)->valid == 0); } op(_STORE_ATTR_INSTANCE_VALUE, (index/1, value, owner --)) { STAT_INC(STORE_ATTR, hit); - assert(_PyObject_ManagedDictPointer(owner)->dict == NULL); + assert(_PyObject_GetManagedDict(owner) == NULL); PyDictValues *values = _PyObject_InlineValues(owner); + PyObject *old_value = values->values[index]; values->values[index] = value; if (old_value == NULL) { @@ -2088,6 +2087,7 @@ dummy_func( else { Py_DECREF(old_value); } + Py_DECREF(owner); } @@ -2102,8 +2102,7 @@ dummy_func( assert(type_version != 0); DEOPT_IF(tp->tp_version_tag != type_version); assert(tp->tp_flags & Py_TPFLAGS_MANAGED_DICT); - PyManagedDictPointer *managed_dict = _PyObject_ManagedDictPointer(owner); - PyDictObject *dict = managed_dict->dict; + PyDictObject *dict = _PyObject_GetManagedDict(owner); DEOPT_IF(dict == NULL); assert(PyDict_CheckExact((PyObject *)dict)); PyObject *name = GETITEM(FRAME_CO_NAMES, oparg); diff --git a/Python/executor_cases.c.h b/Python/executor_cases.c.h index df87f91..841ce8c 100644 --- a/Python/executor_cases.c.h +++ b/Python/executor_cases.c.h @@ -1998,8 +1998,7 @@ PyObject *owner; owner = stack_pointer[-1]; assert(Py_TYPE(owner)->tp_flags & Py_TPFLAGS_MANAGED_DICT); - PyManagedDictPointer *managed_dict = _PyObject_ManagedDictPointer(owner); - PyDictObject *dict = managed_dict->dict; + PyDictObject *dict = _PyObject_GetManagedDict(owner); if (dict == NULL) { UOP_STAT_INC(uopcode, miss); JUMP_TO_JUMP_TARGET(); @@ -2015,8 +2014,7 @@ oparg = CURRENT_OPARG(); owner = stack_pointer[-1]; uint16_t hint = (uint16_t)CURRENT_OPERAND(); - PyManagedDictPointer *managed_dict = _PyObject_ManagedDictPointer(owner); - PyDictObject *dict = managed_dict->dict; + PyDictObject *dict = _PyObject_GetManagedDict(owner); if (hint >= (size_t)dict->ma_keys->dk_nentries) { UOP_STAT_INC(uopcode, miss); JUMP_TO_JUMP_TARGET(); @@ -2159,7 +2157,7 @@ owner = stack_pointer[-1]; assert(Py_TYPE(owner)->tp_dictoffset < 0); assert(Py_TYPE(owner)->tp_flags & Py_TPFLAGS_INLINE_VALUES); - if (_PyObject_ManagedDictPointer(owner)->dict) { + if (_PyObject_GetManagedDict(owner)) { UOP_STAT_INC(uopcode, miss); JUMP_TO_JUMP_TARGET(); } @@ -2177,7 +2175,7 @@ value = stack_pointer[-2]; uint16_t index = (uint16_t)CURRENT_OPERAND(); STAT_INC(STORE_ATTR, hit); - assert(_PyObject_ManagedDictPointer(owner)->dict == NULL); + assert(_PyObject_GetManagedDict(owner) == NULL); PyDictValues *values = _PyObject_InlineValues(owner); PyObject *old_value = values->values[index]; values->values[index] = value; diff --git a/Python/generated_cases.c.h b/Python/generated_cases.c.h index a426d9e..058cac8 100644 --- a/Python/generated_cases.c.h +++ b/Python/generated_cases.c.h @@ -4017,16 +4017,14 @@ // _CHECK_ATTR_WITH_HINT { assert(Py_TYPE(owner)->tp_flags & Py_TPFLAGS_MANAGED_DICT); - PyManagedDictPointer *managed_dict = _PyObject_ManagedDictPointer(owner); - PyDictObject *dict = managed_dict->dict; + PyDictObject *dict = _PyObject_GetManagedDict(owner); DEOPT_IF(dict == NULL, LOAD_ATTR); assert(PyDict_CheckExact((PyObject *)dict)); } // _LOAD_ATTR_WITH_HINT { uint16_t hint = read_u16(&this_instr[4].cache); - PyManagedDictPointer *managed_dict = _PyObject_ManagedDictPointer(owner); - PyDictObject *dict = managed_dict->dict; + PyDictObject *dict = _PyObject_GetManagedDict(owner); DEOPT_IF(hint >= (size_t)dict->ma_keys->dk_nentries, LOAD_ATTR); PyObject *name = GETITEM(FRAME_CO_NAMES, oparg>>1); if (DK_IS_UNICODE(dict->ma_keys)) { @@ -5309,7 +5307,7 @@ { assert(Py_TYPE(owner)->tp_dictoffset < 0); assert(Py_TYPE(owner)->tp_flags & Py_TPFLAGS_INLINE_VALUES); - DEOPT_IF(_PyObject_ManagedDictPointer(owner)->dict, STORE_ATTR); + DEOPT_IF(_PyObject_GetManagedDict(owner), STORE_ATTR); DEOPT_IF(_PyObject_InlineValues(owner)->valid == 0, STORE_ATTR); } // _STORE_ATTR_INSTANCE_VALUE @@ -5317,7 +5315,7 @@ { uint16_t index = read_u16(&this_instr[4].cache); STAT_INC(STORE_ATTR, hit); - assert(_PyObject_ManagedDictPointer(owner)->dict == NULL); + assert(_PyObject_GetManagedDict(owner) == NULL); PyDictValues *values = _PyObject_InlineValues(owner); PyObject *old_value = values->values[index]; values->values[index] = value; @@ -5380,8 +5378,7 @@ assert(type_version != 0); DEOPT_IF(tp->tp_version_tag != type_version, STORE_ATTR); assert(tp->tp_flags & Py_TPFLAGS_MANAGED_DICT); - PyManagedDictPointer *managed_dict = _PyObject_ManagedDictPointer(owner); - PyDictObject *dict = managed_dict->dict; + PyDictObject *dict = _PyObject_GetManagedDict(owner); DEOPT_IF(dict == NULL, STORE_ATTR); assert(PyDict_CheckExact((PyObject *)dict)); PyObject *name = GETITEM(FRAME_CO_NAMES, oparg); diff --git a/Python/specialize.c b/Python/specialize.c index 5e14bb5..ee51781 100644 --- a/Python/specialize.c +++ b/Python/specialize.c @@ -852,8 +852,7 @@ specialize_dict_access( instr->op.code = values_op; } else { - PyManagedDictPointer *managed_dict = _PyObject_ManagedDictPointer(owner); - PyDictObject *dict = managed_dict->dict; + PyDictObject *dict = _PyObject_GetManagedDict(owner); if (dict == NULL || !PyDict_CheckExact(dict)) { SPECIALIZATION_FAIL(base_op, SPEC_FAIL_NO_DICT); return 0; |