Skip to content

Commit 0c27a1a

Browse files
committed
use FFI calls for refcounting on all abi3 versions (#4324)
* use FFI calls for refcounting on all abi3 versions * fix implementation on PyPy
1 parent 6e9eadd commit 0c27a1a

File tree

2 files changed

+36
-56
lines changed

2 files changed

+36
-56
lines changed

newsfragments/4324.changed.md

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Use FFI function calls for reference counting on all abi3 versions.

pyo3-ffi/src/object.rs

+35-56
Original file line numberDiff line numberDiff line change
@@ -490,11 +490,9 @@ extern "C" {
490490
#[cfg_attr(GraalPy, link_name = "_Py_DecRef")]
491491
pub fn Py_DecRef(o: *mut PyObject);
492492

493-
#[cfg(Py_3_10)]
494-
#[cfg_attr(PyPy, link_name = "_PyPy_IncRef")]
493+
#[cfg(all(Py_3_10, not(PyPy)))]
495494
pub fn _Py_IncRef(o: *mut PyObject);
496-
#[cfg(Py_3_10)]
497-
#[cfg_attr(PyPy, link_name = "_PyPy_DecRef")]
495+
#[cfg(all(Py_3_10, not(PyPy)))]
498496
pub fn _Py_DecRef(o: *mut PyObject);
499497

500498
#[cfg(GraalPy)]
@@ -509,35 +507,23 @@ extern "C" {
509507

510508
#[inline(always)]
511509
pub unsafe fn Py_INCREF(op: *mut PyObject) {
512-
#[cfg(any(
513-
GraalPy,
514-
all(Py_LIMITED_API, Py_3_12),
515-
all(
516-
py_sys_config = "Py_REF_DEBUG",
517-
Py_3_10,
518-
not(all(Py_3_12, not(Py_LIMITED_API)))
519-
)
520-
))]
510+
// On limited API or with refcount debugging, let the interpreter do refcounting
511+
#[cfg(any(Py_LIMITED_API, py_sys_config = "Py_REF_DEBUG", GraalPy))]
521512
{
522-
_Py_IncRef(op);
523-
}
513+
// _Py_IncRef was added to the ABI in 3.10; skips null checks
514+
#[cfg(all(Py_3_10, not(PyPy)))]
515+
{
516+
_Py_IncRef(op);
517+
}
524518

525-
#[cfg(all(py_sys_config = "Py_REF_DEBUG", not(Py_3_10)))]
526-
{
527-
return Py_IncRef(op);
519+
#[cfg(any(not(Py_3_10), PyPy))]
520+
{
521+
Py_IncRef(op);
522+
}
528523
}
529524

530-
#[cfg(any(
531-
all(Py_LIMITED_API, not(Py_3_12)),
532-
all(
533-
not(Py_LIMITED_API),
534-
not(GraalPy),
535-
any(
536-
not(py_sys_config = "Py_REF_DEBUG"),
537-
all(py_sys_config = "Py_REF_DEBUG", Py_3_12),
538-
)
539-
),
540-
))]
525+
// version-specific builds are allowed to directly manipulate the reference count
526+
#[cfg(not(any(any(Py_LIMITED_API, py_sys_config = "Py_REF_DEBUG", GraalPy))))]
541527
{
542528
#[cfg(all(Py_3_12, target_pointer_width = "64"))]
543529
{
@@ -564,9 +550,6 @@ pub unsafe fn Py_INCREF(op: *mut PyObject) {
564550

565551
// Skipped _Py_INCREF_STAT_INC - if anyone wants this, please file an issue
566552
// or submit a PR supporting Py_STATS build option and pystats.h
567-
568-
#[cfg(all(py_sys_config = "Py_REF_DEBUG", Py_3_12))]
569-
_Py_INCREF_IncRefTotal();
570553
}
571554
}
572555

@@ -576,35 +559,31 @@ pub unsafe fn Py_INCREF(op: *mut PyObject) {
576559
track_caller
577560
)]
578561
pub unsafe fn Py_DECREF(op: *mut PyObject) {
562+
// On limited API or with refcount debugging, let the interpreter do refcounting
563+
// On 3.12+ we implement refcount debugging to get better assertion locations on negative refcounts
579564
#[cfg(any(
580-
GraalPy,
581-
all(Py_LIMITED_API, Py_3_12),
582-
all(
583-
py_sys_config = "Py_REF_DEBUG",
584-
Py_3_10,
585-
not(all(Py_3_12, not(Py_LIMITED_API)))
586-
)
565+
Py_LIMITED_API,
566+
all(py_sys_config = "Py_REF_DEBUG", not(Py_3_12)),
567+
GraalPy
587568
))]
588569
{
589-
_Py_DecRef(op);
590-
}
570+
// _Py_DecRef was added to the ABI in 3.10; skips null checks
571+
#[cfg(all(Py_3_10, not(PyPy)))]
572+
{
573+
_Py_DecRef(op);
574+
}
591575

592-
#[cfg(all(py_sys_config = "Py_REF_DEBUG", not(Py_3_10)))]
593-
{
594-
return Py_DecRef(op);
576+
#[cfg(any(not(Py_3_10), PyPy))]
577+
{
578+
Py_DecRef(op);
579+
}
595580
}
596581

597-
#[cfg(any(
598-
all(Py_LIMITED_API, not(Py_3_12)),
599-
all(
600-
not(Py_LIMITED_API),
601-
not(GraalPy),
602-
any(
603-
not(py_sys_config = "Py_REF_DEBUG"),
604-
all(py_sys_config = "Py_REF_DEBUG", Py_3_12),
605-
)
606-
),
607-
))]
582+
#[cfg(not(any(
583+
Py_LIMITED_API,
584+
all(py_sys_config = "Py_REF_DEBUG", not(Py_3_12)),
585+
GraalPy
586+
)))]
608587
{
609588
#[cfg(Py_3_12)]
610589
if _Py_IsImmortal(op) != 0 {
@@ -614,7 +593,7 @@ pub unsafe fn Py_DECREF(op: *mut PyObject) {
614593
// Skipped _Py_DECREF_STAT_INC - if anyone needs this, please file an issue
615594
// or submit a PR supporting Py_STATS build option and pystats.h
616595

617-
#[cfg(all(py_sys_config = "Py_REF_DEBUG", Py_3_12))]
596+
#[cfg(py_sys_config = "Py_REF_DEBUG")]
618597
_Py_DECREF_DecRefTotal();
619598

620599
#[cfg(Py_3_12)]

0 commit comments

Comments
 (0)