@@ -6629,7 +6629,7 @@ materialize_managed_dict_lock_held(PyObject *obj)
6629
6629
OBJECT_STAT_INC (dict_materialized_on_request );
6630
6630
PyDictObject * dict = make_dict_from_instance_attributes (interp , keys , values );
6631
6631
FT_ATOMIC_STORE_PTR_RELEASE (_PyObject_ManagedDictPointer (obj )-> dict ,
6632
- (PyDictObject * )dict );
6632
+ (PyDictObject * )dict );
6633
6633
return dict ;
6634
6634
}
6635
6635
@@ -6713,8 +6713,6 @@ store_instance_attr_lock_held(PyObject *obj, PyDictValues *values,
6713
6713
if (ix == DKIX_EMPTY ) {
6714
6714
int res ;
6715
6715
if (dict == NULL ) {
6716
- // Make the dict but don't publish it in the object
6717
- // so that no one else will see it.
6718
6716
dict = materialize_managed_dict_lock_held (obj );
6719
6717
if (dict == NULL ) {
6720
6718
return -1 ;
@@ -6795,15 +6793,14 @@ store_instance_attr_dict(PyObject *obj, PyDictObject *dict, PyObject *name, PyOb
6795
6793
}
6796
6794
6797
6795
int
6798
- _PyObject_TryStoreInstanceAttribute (PyObject * obj , PyObject * name , PyObject * value )
6796
+ _PyObject_StoreInstanceAttribute (PyObject * obj , PyObject * name , PyObject * value )
6799
6797
{
6800
6798
PyDictValues * values = _PyObject_InlineValues (obj );
6801
6799
if (!FT_ATOMIC_LOAD_UINT8_RELAXED (values -> valid )) {
6802
6800
return store_instance_attr_dict (obj , _PyObject_GetManagedDict (obj ), name , value );
6803
6801
}
6804
6802
6805
6803
#ifdef Py_GIL_DISABLED
6806
- int res ;
6807
6804
// We have a valid inline values, at least for now... There are two potential
6808
6805
// races with having the values become invalid. One is the dictionary
6809
6806
// being detached from the object. The other is if someone is inserting
@@ -6816,24 +6813,20 @@ _PyObject_TryStoreInstanceAttribute(PyObject *obj, PyObject *name, PyObject *val
6816
6813
// prevent resizing.
6817
6814
PyDictObject * dict = _PyObject_GetManagedDict (obj );
6818
6815
if (dict == NULL ) {
6816
+ int res ;
6819
6817
Py_BEGIN_CRITICAL_SECTION (obj );
6820
6818
dict = _PyObject_GetManagedDict (obj );
6821
6819
6822
6820
if (dict == NULL ) {
6823
6821
res = store_instance_attr_lock_held (obj , values , name , value );
6824
6822
}
6825
- else {
6826
- // We lost a race with the materialization of the dict, we'll
6827
- // try the insert with it...
6828
- goto with_dict ;
6829
- }
6830
6823
Py_END_CRITICAL_SECTION ();
6824
+
6825
+ if (dict == NULL ) {
6826
+ return res ;
6827
+ }
6831
6828
}
6832
- else {
6833
- with_dict :
6834
- res = store_instance_attr_dict (obj , dict , name , value );
6835
- }
6836
- return res ;
6829
+ return store_instance_attr_dict (obj , dict , name , value );
6837
6830
#else
6838
6831
return store_instance_attr_lock_held (obj , values , name , value );
6839
6832
#endif
@@ -6873,28 +6866,28 @@ _PyObject_ManagedDictValidityCheck(PyObject *obj)
6873
6866
// Attempts to get an instance attribute from the inline values. Returns 0 if
6874
6867
// the lookup from the inline values was successful or 1 if the inline values
6875
6868
// are no longer valid. No error is set in either case.
6876
- int
6869
+ bool
6877
6870
_PyObject_TryGetInstanceAttribute (PyObject * obj , PyObject * name , PyObject * * attr )
6878
6871
{
6879
6872
assert (PyUnicode_CheckExact (name ));
6880
6873
PyDictValues * values = _PyObject_InlineValues (obj );
6881
6874
if (!FT_ATOMIC_LOAD_UINT8_RELAXED (values -> valid )) {
6882
- return 1 ;
6875
+ return false ;
6883
6876
}
6884
6877
6885
6878
PyDictKeysObject * keys = CACHED_KEYS (Py_TYPE (obj ));
6886
6879
assert (keys != NULL );
6887
6880
Py_ssize_t ix = _PyDictKeys_StringLookup (keys , name );
6888
6881
if (ix == DKIX_EMPTY ) {
6889
6882
* attr = NULL ;
6890
- return 0 ;
6883
+ return true ;
6891
6884
}
6892
6885
6893
6886
#ifdef Py_GIL_DISABLED
6894
6887
PyObject * value = _Py_atomic_load_ptr_relaxed (& values -> values [ix ]);
6895
6888
if (value == NULL || _Py_TryIncrefCompare (& values -> values [ix ], value )) {
6896
6889
* attr = value ;
6897
- return 0 ;
6890
+ return true ;
6898
6891
}
6899
6892
6900
6893
PyDictObject * dict = _PyObject_GetManagedDict (obj );
@@ -6916,33 +6909,34 @@ _PyObject_TryGetInstanceAttribute(PyObject *obj, PyObject *name, PyObject **attr
6916
6909
Py_END_CRITICAL_SECTION ();
6917
6910
6918
6911
if (success ) {
6919
- return 0 ;
6912
+ return true ;
6920
6913
}
6921
6914
}
6922
6915
6923
6916
// We have a dictionary, we'll need to lock it to prevent
6924
6917
// the values from being resized.
6925
6918
assert (dict != NULL );
6926
- int res ;
6919
+
6920
+ bool success ;
6927
6921
Py_BEGIN_CRITICAL_SECTION (dict );
6928
6922
6929
6923
if (dict -> ma_values == values &&
6930
6924
FT_ATOMIC_LOAD_UINT8_RELAXED (values -> valid )) {
6931
6925
value = _Py_atomic_load_ptr_relaxed (& values -> values [ix ]);
6932
6926
* attr = Py_XNewRef (value );
6933
- res = 0 ;
6927
+ success = true ;
6934
6928
} else {
6935
6929
// Caller needs to lookup from the dictionary
6936
- res = 1 ;
6930
+ success = false ;
<
A851
/td>6937
6931
}
6938
6932
6939
6933
Py_END_CRITICAL_SECTION ();
6940
6934
6941
- return res ;
6935
+ return success ;
6942
6936
#else
6943
6937
PyObject * value = values -> values [ix ];
6944
6938
* attr = Py_XNewRef (value );
6945
- return 0 ;
6939
+ return true ;
6946
6940
#endif
6947
6941
}
6948
6942
@@ -7003,14 +6997,9 @@ PyObject_VisitManagedDict(PyObject *obj, visitproc visit, void *arg)
7003
6997
static bool
7004
6998
set_dict_inline_values (PyObject * obj , PyObject * new_dict )
7005
6999
{
7006
- PyDictValues * values = _PyObject_InlineValues (obj );
7000
+ _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED (obj );
7007
7001
7008
- if (values -> valid ) {
7009
- for (Py_ssize_t i = 0 ; i < values -> capacity ; i ++ ) {
7010
- Py_CLEAR (values -> values [i ]);
7011
- }
7012
- values -> valid = 0 ;
7013
- }
7002
+ PyDictValues * values = _PyObject_InlineValues (obj );
7014
7003
7015
7004
#ifdef Py_GIL_DISABLED
7016
7005
PyDictObject * dict = _PyObject_ManagedDictPointer (obj )-> dict ;
@@ -7022,6 +7011,14 @@ set_dict_inline_values(PyObject *obj, PyObject *new_dict)
7022
7011
7023
7012
Py_XINCREF (new_dict );
7024
7013
_PyObject_ManagedDictPointer (obj )-> dict = (PyDictObject * )new_dict ;
7014
+
7015
+ if (values -> valid ) {
7016
+ FT_ATOMIC_STORE_UINT8_RELAXED (values -> valid , 0 );
7017
+ for (Py_ssize_t i = 0 ; i < values -> capacity ; i ++ ) {
7018
+ Py_CLEAR (values -> values [i ]);
7019
+ }
7020
+ }
7021
+
7025
7022
return true;
7026
7023
}
7027
7024
@@ -7032,7 +7029,7 @@ _PyObject_SetManagedDict(PyObject *obj, PyObject *new_dict)
7032
7029
assert (_PyObject_InlineValuesConsistencyCheck (obj ));
7033
7030
PyTypeObject * tp = Py_TYPE (obj );
7034
7031
if (tp -> tp_flags & Py_TPFLAGS_INLINE_VALUES ) {
7035
- PyDictObject * dict = _PyObject_ManagedDictPointer (obj )-> dict ;
7032
+ PyDictObject * dict = _PyObject_GetManagedDict (obj );
7036
7033
if (dict ) {
7037
7034
#ifdef Py_GIL_DISABLED
7038
7035
clear_dict :
@@ -7120,7 +7117,7 @@ PyObject_GenericGetDict(PyObject *obj, void *context)
7120
7117
dict = _PyObject_GetManagedDict (obj );
7121
7118
if (dict == NULL &&
7122
7119
(tp -> tp_flags & Py_TPFLAGS_INLINE_VALUES ) &&
7123
- _PyObject_InlineValues (obj )-> valid ) {
7120
+ FT_ATOMIC_LOAD_UINT8_RELAXED ( _PyObject_InlineValues (obj )-> valid ) ) {
7124
7121
dict = _PyObject_MaterializeManagedDict (obj );
7125
7122
}
7126
7123
else if (dict == NULL ) {
0 commit comments