@@ -385,7 +385,7 @@ static inline void _PyObject_GC_UNTRACK(
385385 * where the reference count modification requires an atomic operation. This
386386 * allows call sites to specialize for the immortal/local case.
387387 */
388- static inline Py_ALWAYS_INLINE int
388+ static inline int
389389_Py_TryIncrefFast (PyObject * op ) {
390390 uint32_t local = _Py_atomic_load_uint32_relaxed (& op -> ob_ref_local );
391391 local += 1 ;
@@ -394,6 +394,7 @@ _Py_TryIncrefFast(PyObject *op) {
394394 return 1 ;
395395 }
396396 if (_Py_IsOwnedByCurrentThread (op )) {
397+ _Py_INCREF_STAT_INC ();
397398 _Py_atomic_store_uint32_relaxed (& op -> ob_ref_local , local );
398399#ifdef Py_REF_DEBUG
399400 _Py_IncRefTotal (_PyInterpreterState_GET ());
@@ -403,12 +404,11 @@ _Py_TryIncrefFast(PyObject *op) {
403404 return 0 ;
404405}
405406
406- static inline Py_ALWAYS_INLINE int
407+ static inline int
407408_Py_TryIncRefShared (PyObject * op )
408409{
410+ Py_ssize_t shared = _Py_atomic_load_ssize_relaxed (& op -> ob_ref_shared );
409411 for (;;) {
410- Py_ssize_t shared = _Py_atomic_load_ssize_relaxed (& op -> ob_ref_shared );
411-
412412 // If the shared refcount is zero and the object is either merged
413413 // or may not have weak references, then we cannot incref it.
414414 if (shared == 0 || shared == _Py_REF_MERGED ) {
@@ -422,6 +422,7 @@ _Py_TryIncRefShared(PyObject *op)
422422#ifdef Py_REF_DEBUG
423423 _Py_IncRefTotal (_PyInterpreterState_GET ());
424424#endif
425+ _Py_INCREF_STAT_INC ();
425426 return 1 ;
426427 }
427428 }
@@ -447,10 +448,9 @@ _Py_TryAcquireObject(PyObject **src, PyObject *op)
447448/* Loads and increfs an object from ptr, which may contain a NULL value.
448449 Safe with concurrent (atomic) updates to ptr.
449450 NOTE: The writer must set maybe-weakref on the stored object! */
450- static inline Py_ALWAYS_INLINE PyObject *
451- _Py_XFetchRef (PyObject * * ptr )
451+ static inline PyObject *
452+ _Py_XGetRef (PyObject * * ptr )
452453{
453- #ifdef Py_NOGIL
454454 for (;;) {
455455 PyObject * value = _Py_atomic_load_ptr (ptr );
456456 if (value == NULL ) {
@@ -460,14 +460,11 @@ _Py_XFetchRef(PyObject **ptr)
460460 return value ;
461461 }
462462 }
463- #else
464- return Py_XNewRef (* ptr );
465- #endif
466463}
467464
468465/* Attempts to loads and increfs an object from ptr. Returns NULL
469466 on failure, which may be due to a NULL value or a concurrent update. */
470- static inline Py_ALWAYS_INLINE PyObject *
467+ static inline PyObject *
471468_Py_TryXFetchRef (PyObject * * ptr )
472469{
473470 PyObject * value = _Py_atomic_load_ptr (ptr );
@@ -485,32 +482,21 @@ _Py_TryXFetchRef(PyObject **ptr)
485482static inline PyObject *
486483_Py_NewRefWithLock (PyObject * op )
487484{
488- _Py_INCREF_STAT_INC ();
489- uint32_t local = _Py_atomic_load_uint32_relaxed (& op -> ob_ref_local );
490- local += 1 ;
491- if (local == 0 ) {
485+ if (_Py_TryIncrefFast (op )) {
492486 return op ;
493487 }
494-
495- #ifdef Py_REF_DEBUG
496- _Py_IncRefTotal (_PyInterpreterState_GET ());
497- #endif
498- if (_Py_IsOwnedByCurrentThread (op )) {
499- _Py_atomic_store_uint32_relaxed (& op -> ob_ref_local , local );
500- }
501- else {
502- for (;;) {
503- Py_ssize_t shared = _Py_atomic_load_ssize_relaxed (& op -> ob_ref_shared );
504- Py_ssize_t new_shared = shared + (1 << _Py_REF_SHARED_SHIFT );
505- if ((shared & _Py_REF_SHARED_FLAG_MASK ) == 0 ) {
506- new_shared |= _Py_REF_MAYBE_WEAKREF ;
507- }
508- if (_Py_atomic_compare_exchange_ssize (
509- & op -> ob_ref_shared ,
510- & shared ,
511- new_shared )) {
512- return op ;
513- }
488+ _Py_INCREF_STAT_INC ();
489+ for (;;) {
490+ Py_ssize_t shared = _Py_atomic_load_ssize_relaxed (& op -> ob_ref_shared );
491+ Py_ssize_t new_shared = shared + (1 << _Py_REF_SHARED_SHIFT );
492+ if ((shared & _Py_REF_SHARED_FLAG_MASK ) == 0 ) {
493+ new_shared |= _Py_REF_MAYBE_WEAKREF ;
494+ }
495+ if (_Py_atomic_compare_exchange_ssize (
496+ & op -> ob_ref_shared ,
497+ & shared ,
498+ new_shared )) {
499+ return op ;
514500 }
515501 }
516502 return op ;
0 commit comments