summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVictor Stinner <vstinner@python.org>2022-05-11 11:37:18 (GMT)
committerGitHub <noreply@github.com>2022-05-11 11:37:18 (GMT)
commitffcc7cd57f6a52c6074ecc9f0a9f0177fb1dbfee (patch)
tree2ac1b0284481d8fb8ef958e141043b392e966480
parent707839b0fe02ba2c891a40f40e7a869d84c2c9c5 (diff)
downloadcpython-ffcc7cd57f6a52c6074ecc9f0a9f0177fb1dbfee.zip
cpython-ffcc7cd57f6a52c6074ecc9f0a9f0177fb1dbfee.tar.gz
cpython-ffcc7cd57f6a52c6074ecc9f0a9f0177fb1dbfee.tar.bz2
gh-89653: PEP 670: Convert pycore_gc.h macros to functions (#92649)
Convert the following macros to static inline functions: * _Py_AS_GC() * _PyGCHead_FINALIZED(), _PyGCHead_SET_FINALIZED() * _PyGCHead_NEXT(), _PyGCHead_SET_NEXT() * _PyGCHead_PREV(), _PyGCHead_SET_PREV() * _PyGC_FINALIZED(), _PyGC_SET_FINALIZED() * _PyObject_GC_IS_TRACKED() * _PyObject_GC_MAY_BE_TRACKED() Add a macro wrapping the _PyObject_GC_IS_TRACKED() function to cast the argument to PyObject*.
-rw-r--r--Include/internal/pycore_gc.h72
-rw-r--r--Objects/object.c2
2 files changed, 50 insertions, 24 deletions
diff --git a/Include/internal/pycore_gc.h b/Include/internal/pycore_gc.h
index 16c1893..bfab0ad 100644
--- a/Include/internal/pycore_gc.h
+++ b/Include/internal/pycore_gc.h
@@ -19,17 +19,29 @@ typedef struct {
uintptr_t _gc_prev;
} PyGC_Head;
-#define _Py_AS_GC(o) ((PyGC_Head *)(o)-1)
+static inline PyGC_Head* _Py_AS_GC(PyObject *op) {
+ return (_Py_CAST(PyGC_Head*, op) - 1);
+}
#define _PyGC_Head_UNUSED PyGC_Head
/* True if the object is currently tracked by the GC. */
-#define _PyObject_GC_IS_TRACKED(o) (_Py_AS_GC(o)->_gc_next != 0)
+static inline int _PyObject_GC_IS_TRACKED(PyObject *op) {
+ PyGC_Head *gc = _Py_AS_GC(op);
+ return (gc->_gc_next != 0);
+}
+#define _PyObject_GC_IS_TRACKED(op) _PyObject_GC_IS_TRACKED(_Py_CAST(PyObject*, op))
/* True if the object may be tracked by the GC in the future, or already is.
This can be useful to implement some optimizations. */
-#define _PyObject_GC_MAY_BE_TRACKED(obj) \
- (PyObject_IS_GC(obj) && \
- (!PyTuple_CheckExact(obj) || _PyObject_GC_IS_TRACKED(obj)))
+static inline int _PyObject_GC_MAY_BE_TRACKED(PyObject *obj) {
+ if (!PyObject_IS_GC(obj)) {
+ return 0;
+ }
+ if (PyTuple_CheckExact(obj)) {
+ return _PyObject_GC_IS_TRACKED(obj);
+ }
+ return 1;
+}
/* Bit flags for _gc_prev */
@@ -43,26 +55,40 @@ typedef struct {
// Lowest bit of _gc_next is used for flags only in GC.
// But it is always 0 for normal code.
-#define _PyGCHead_NEXT(g) ((PyGC_Head*)(g)->_gc_next)
-#define _PyGCHead_SET_NEXT(g, p) _Py_RVALUE((g)->_gc_next = (uintptr_t)(p))
+static inline PyGC_Head* _PyGCHead_NEXT(PyGC_Head *gc) {
+ uintptr_t next = gc->_gc_next;
+ return _Py_CAST(PyGC_Head*, next);
+}
+static inline void _PyGCHead_SET_NEXT(PyGC_Head *gc, PyGC_Head *next) {
+ gc->_gc_next = _Py_CAST(uintptr_t, next);
+}
// Lowest two bits of _gc_prev is used for _PyGC_PREV_MASK_* flags.
-#define _PyGCHead_PREV(g) ((PyGC_Head*)((g)->_gc_prev & _PyGC_PREV_MASK))
-#define _PyGCHead_SET_PREV(g, p) do { \
- assert(((uintptr_t)p & ~_PyGC_PREV_MASK) == 0); \
- (g)->_gc_prev = ((g)->_gc_prev & ~_PyGC_PREV_MASK) \
- | ((uintptr_t)(p)); \
- } while (0)
-
-#define _PyGCHead_FINALIZED(g) \
- (((g)->_gc_prev & _PyGC_PREV_MASK_FINALIZED) != 0)
-#define _PyGCHead_SET_FINALIZED(g) \
- _Py_RVALUE((g)->_gc_prev |= _PyGC_PREV_MASK_FINALIZED)
-
-#define _PyGC_FINALIZED(o) \
- _PyGCHead_FINALIZED(_Py_AS_GC(o))
-#define _PyGC_SET_FINALIZED(o) \
- _PyGCHead_SET_FINALIZED(_Py_AS_GC(o))
+static inline PyGC_Head* _PyGCHead_PREV(PyGC_Head *gc) {
+ uintptr_t prev = (gc->_gc_prev & _PyGC_PREV_MASK);
+ return _Py_CAST(PyGC_Head*, prev);
+}
+static inline void _PyGCHead_SET_PREV(PyGC_Head *gc, PyGC_Head *prev) {
+ uintptr_t uprev = _Py_CAST(uintptr_t, prev);
+ assert((uprev & ~_PyGC_PREV_MASK) == 0);
+ gc->_gc_prev = ((gc->_gc_prev & ~_PyGC_PREV_MASK) | uprev);
+}
+
+static inline int _PyGCHead_FINALIZED(PyGC_Head *gc) {
+ return ((gc->_gc_prev & _PyGC_PREV_MASK_FINALIZED) != 0);
+}
+static inline void _PyGCHead_SET_FINALIZED(PyGC_Head *gc) {
+ gc->_gc_prev |= _PyGC_PREV_MASK_FINALIZED;
+}
+
+static inline int _PyGC_FINALIZED(PyObject *op) {
+ PyGC_Head *gc = _Py_AS_GC(op);
+ return _PyGCHead_FINALIZED(gc);
+}
+static inline void _PyGC_SET_FINALIZED(PyObject *op) {
+ PyGC_Head *gc = _Py_AS_GC(op);
+ _PyGCHead_SET_FINALIZED(gc);
+}
/* GC runtime state */
diff --git a/Objects/object.c b/Objects/object.c
index d5f21b7..8339ab3 100644
--- a/Objects/object.c
+++ b/Objects/object.c
@@ -2228,7 +2228,7 @@ _PyTrash_thread_deposit_object(PyObject *op)
_PyObject_ASSERT(op, _PyObject_IS_GC(op));
_PyObject_ASSERT(op, !_PyObject_GC_IS_TRACKED(op));
_PyObject_ASSERT(op, Py_REFCNT(op) == 0);
- _PyGCHead_SET_PREV(_Py_AS_GC(op), tstate->trash_delete_later);
+ _PyGCHead_SET_PREV(_Py_AS_GC(op), (PyGC_Head*)tstate->trash_delete_later);
tstate->trash_delete_later = op;
}