@@ -7186,70 +7186,47 @@ _PyDict_DetachFromObject(PyDictObject *mp, PyObject *obj)
7186
7186
return 0 ;
7187
7187
}
7188
7188
7189
- PyObject *
7190
- PyObject_GenericGetDict (PyObject * obj , void * context )
7189
+ static inline PyObject *
7190
+ ensure_managed_dict (PyObject * obj )
7191
7191
{
7192
- PyInterpreterState * interp = _PyInterpreterState_GET ();
7193
- PyTypeObject * tp = Py_TYPE (obj );
7194
- PyDictObject * dict ;
7195
- if (_PyType_HasFeature (tp , Py_TPFLAGS_MANAGED_DICT )) {
7196
- dict = _PyObject_GetManagedDict (obj );
7197
- if (dict == NULL &&
7198
- (tp -> tp_flags & Py_TPFLAGS_INLINE_VALUES ) &&
7192
+ PyDictObject * dict = _PyObject_GetManagedDict (obj );
7193
+ if (dict == NULL ) {
7194
+ PyTypeObject * tp = Py_TYPE (obj );
7195
+ if ((tp -> tp_flags & Py_TPFLAGS_INLINE_VALUES ) &&
7199
7196
FT_ATOMIC_LOAD_UINT8 (_PyObject_InlineValues (obj )-> valid )) {
7200
7197
dict = _PyObject_MaterializeManagedDict (obj );
7201
7198
}
7202
- else if (dict == NULL ) {
7203
- Py_BEGIN_CRITICAL_SECTION (obj );
7204
-
7199
+ else {
7200
+ #ifdef Py_GIL_DISABLED
7205
7201
// Check again that we're not racing with someone else creating the dict
7202
+ Py_BEGIN_CRITICAL_SECTION (obj );
7206
7203
dict = _PyObject_GetManagedDict (obj );
7207
- if (dict == NULL ) {
7208
- OBJECT_STAT_INC (dict_materialized_on_request );
7209
- dictkeys_incref (CACHED_KEYS (tp ));
7210
- dict = (PyDictObject * )new_dict_with_shared_keys (interp , CACHED_KEYS (tp ));
7211
- FT_ATOMIC_STORE_PTR_RELEASE (_PyObject_ManagedDictPointer (obj )-> dict ,
7212
- (PyDictObject * )dict );
7204
+ if (dict != NULL ) {
7205
+ goto done ;
7213
7206
}
7207
+ #endif
7208
+ OBJECT_STAT_INC (dict_materialized_on_request );
7209
+ dictkeys_incref (CACHED_KEYS (tp ));
7210
+ dict = (PyDictObject * )new_dict_with_shared_keys (_PyInterpreterState_GET (),
7211
+ CACHED_KEYS (tp ));
7212
+ FT_ATOMIC_STORE_PTR_RELEASE (_PyObject_ManagedDictPointer (obj )-> dict ,
7213
+ (PyDictObject * )dict );
7214
7214
7215
+ #ifdef Py_GIL_DISABLED
7216
+ done :
7215
7217
Py_END_CRITICAL_SECTION ();
7218
+ #endif
7216
7219
}
7217
- return Py_XNewRef ((PyObject * )dict );
7218
- }
7219
- else {
7220
- PyObject * * dictptr = _PyObject_ComputedDictPointer (obj );
7221
- if (dictptr == NULL ) {
7222
- PyErr_SetString (PyExc_AttributeError ,
7223
- "This object has no __dict__" );
7224
- return NULL ;
7225
- }
7226
- PyObject * dict = * dictptr ;
7227
- if (dict == NULL ) {
7228
- PyTypeObject * tp = Py_TYPE (obj );
7229
- if (_PyType_HasFeature (tp , Py_TPFLAGS_HEAPTYPE ) && CACHED_KEYS (tp )) {
7230
- dictkeys_incref (CACHED_KEYS (tp ));
7231
- * dictptr = dict = new_dict_with_shared_keys (
7232
- interp , CACHED_KEYS (tp ));
7233
- }
7234
- else {
7235
- * dictptr = dict = PyDict_New ();
7236
- }
7237
- }
7238
- return Py_XNewRef (dict );
7239
7220
}
7221
+ return (PyObject * )dict ;
7240
7222
}
7241
7223
7242
- int
7243
- _PyObjectDict_SetItem (PyTypeObject * tp , PyObject * obj , PyObject * * dictptr ,
7244
- PyObject * key , PyObject * value )
7224
+ static inline PyObject *
7225
+ ensure_nonmanaged_dict (PyObject * obj , PyObject * * dictptr )
7245
7226
{
7246
- PyObject * dict ;
7247
- int res ;
7248
7227
PyDictKeysObject * cached ;
7249
- PyInterpreterState * interp = _PyInterpreterState_GET ();
7250
7228
7251
- assert (dictptr != NULL );
7252
- dict = * dictptr ;
7229
+ PyObject * dict = FT_ATOMIC_LOAD_PTR_RELAXED (* dictptr );
7253
7230
if (dict == NULL ) {
7254
7231
#ifdef Py_GIL_DISABLED
7255
7232
Py_BEGIN_CRITICAL_SECTION (obj );
@@ -7258,7 +7235,9 @@ _PyObjectDict_SetItem(PyTypeObject *tp, PyObject *obj, PyObject **dictptr,
7258
7235
goto done ;
7259
7236
}
7260
7237
#endif
7238
+ PyTypeObject * tp = Py_TYPE (obj );
7261
7239
if ((tp -> tp_flags & Py_TPFLAGS_HEAPTYPE ) && (cached = CACHED_KEYS (tp ))) {
7240
+ PyInterpreterState * interp = _PyInterpreterState_GET ();
7262
7241
assert (!_PyType_HasFeature (tp , Py_TPFLAGS_INLINE_VALUES ));
7263
7242
dictkeys_incref (cached );
7264
7243
dict = new_dict_with_shared_keys (interp , cached );
@@ -7269,14 +7248,45 @@ _PyObjectDict_SetItem(PyTypeObject *tp, PyObject *obj, PyObject **dictptr,
7269
7248
else {
7270
7249
dict = PyDict_New ();
7271
7250
}
7272
- * dictptr = dict ;
7251
+ FT_ATOMIC_STORE_PTR_RELAXED ( * dictptr , dict ) ;
7273
7252
#ifdef Py_GIL_DISABLED
7274
7253
done :
7275
7254
Py_END_CRITICAL_SECTION ();
7276
7255
#endif
7277
- if (dict == NULL ) {
7278
- return -1 ;
7256
+ }
7257
+ return dict ;
7258
+ }
7259
+
7260
+ PyObject *
7261
+ PyObject_GenericGetDict (PyObject * obj , void * context )
7262
+ {
7263
+ PyTypeObject * tp = Py_TYPE (obj );
7264
+ if (_PyType_HasFeature (tp , Py_TPFLAGS_MANAGED_DICT )) {
7265
+ return Py_XNewRef (ensure_managed_dict (obj ));
7266
+ }
7267
+ else {
7268
+ PyObject * * dictptr = _PyObject_ComputedDictPointer (obj );
7269
+ if (dictptr == NULL ) {
7270
+ PyErr_SetString (PyExc_AttributeError ,
7271
+ "This object has no __dict__" );
7272
+ return NULL ;
7279
7273
}
7274
+
7275
+ return Py_XNewRef (ensure_nonmanaged_dict (obj , dictptr ));
7276
+ }
7277
+ }
7278
+
7279
+ int
7280
+ _PyObjectDict_SetItem (PyTypeObject * tp , PyObject * obj , PyObject * * dictptr ,
7281
+ PyObject * key , PyObject * value )
7282
+ {
7283
+ PyObject * dict ;
7284
+ int res ;
7285
+
7286
+ assert (dictptr != NULL );
7287
+ dict = ensure_nonmanaged_dict (obj , dictptr );
7288
+ if (dict == NULL ) {
7289
+ return -1 ;
7280
7290
}
7281
7291
7282
7292
Py_BEGIN_CRITICAL_SECTION (dict );
0 commit comments