@@ -19,17 +19,29 @@ typedef struct {
19
19
uintptr_t _gc_prev ;
20
20
} PyGC_Head ;
21
21
22
- #define _Py_AS_GC (o ) ((PyGC_Head *)(o)-1)
22
+ static inline PyGC_Head * _Py_AS_GC (PyObject * op ) {
23
+ return (_Py_CAST (PyGC_Head * , op ) - 1 );
24
+ }
23
25
#define _PyGC_Head_UNUSED PyGC_Head
24
26
25
27
/* True if the object is currently tracked by the GC. */
26
- #define _PyObject_GC_IS_TRACKED (o ) (_Py_AS_GC(o)->_gc_next != 0)
28
+ static inline int _PyObject_GC_IS_TRACKED (PyObject * op ) {
29
+ PyGC_Head * gc = _Py_AS_GC (op );
30
+ return (gc -> _gc_next != 0 );
31
+ }
32
+ #define _PyObject_GC_IS_TRACKED (op ) _PyObject_GC_IS_TRACKED(_Py_CAST(PyObject*, op))
27
33
28
34
/* True if the object may be tracked by the GC in the future, or already is.
29
35
This can be useful to implement some optimizations. */
30
- #define _PyObject_GC_MAY_BE_TRACKED (obj ) \
31
- (PyObject_IS_GC(obj) && \
32
- (!PyTuple_CheckExact(obj) || _PyObject_GC_IS_TRACKED(obj)))
36
+ static inline int _PyObject_GC_MAY_BE_TRACKED (PyObject * obj ) {
37
+ if (!PyObject_IS_GC (obj )) {
38
+ return 0 ;
39
+ }
40
+ if (PyTuple_CheckExact (obj )) {
41
+ return _PyObject_GC_IS_TRACKED (obj );
42
+ }
43
+ return 1 ;
44
+ }
33
45
34
46
35
47
/* Bit flags for _gc_prev */
@@ -43,26 +55,40 @@ typedef struct {
43
55
44
56
// Lowest bit of _gc_next is used for flags only in GC.
45
57
// But it is always 0 for normal code.
46
- #define _PyGCHead_NEXT (g ) ((PyGC_Head*)(g)->_gc_next)
47
- #define _PyGCHead_SET_NEXT (g , p ) _Py_RVALUE((g)->_gc_next = (uintptr_t)(p))
58
+ static inline PyGC_Head * _PyGCHead_NEXT (PyGC_Head * gc ) {
59
+ uintptr_t next = gc -> _gc_next ;
60
+ return _Py_CAST (PyGC_Head * , next );
61
+ }
62
+ static inline void _PyGCHead_SET_NEXT (PyGC_Head * gc , PyGC_Head * next ) {
63
+ gc -> _gc_next = _Py_CAST (uintptr_t , next );
64
+ }
48
65
49
66
// Lowest two bits of _gc_prev is used for _PyGC_PREV_MASK_* flags.
50
- #define _PyGCHead_PREV (g ) ((PyGC_Head*)((g)->_gc_prev & _PyGC_PREV_MASK))
51
- #define _PyGCHead_SET_PREV (g , p ) do { \
52
- assert(((uintptr_t)p & ~_PyGC_PREV_MASK) == 0); \
53
- (g)->_gc_prev = ((g)->_gc_prev & ~_PyGC_PREV_MASK) \
54
- | ((uintptr_t)(p)); \
55
- } while (0)
56
-
57
- #define _PyGCHead_FINALIZED (g ) \
58
- (((g)->_gc_prev & _PyGC_PREV_MASK_FINALIZED) != 0)
59
- #define _PyGCHead_SET_FINALIZED (g ) \
60
- _Py_RVALUE((g)->_gc_prev |= _PyGC_PREV_MASK_FINALIZED)
61
-
62
- #define _PyGC_FINALIZED (o ) \
63
- _PyGCHead_FINALIZED(_Py_AS_GC(o))
64
- #define _PyGC_SET_FINALIZED (o ) \
65
- _PyGCHead_SET_FINALIZED(_Py_AS_GC(o))
67
+ static inline PyGC_Head * _PyGCHead_PREV (PyGC_Head * gc ) {
68
+ uintptr_t prev = (gc -> _gc_prev & _PyGC_PREV_MASK );
69
+ return _Py_CAST (PyGC_Head * , prev );
70
+ }
71
+ static inline void _PyGCHead_SET_PREV (PyGC_Head * gc , PyGC_Head * prev ) {
72
+ uintptr_t uprev = _Py_CAST (uintptr_t , prev );
73
+ assert ((uprev & ~_PyGC_PREV_MASK ) == 0 );
74
+ gc -> _gc_prev = ((gc -> _gc_prev & ~_PyGC_PREV_MASK ) | uprev );
75
+ }
76
+
77
+ static inline int _PyGCHead_FINALIZED (PyGC_Head * gc ) {
78
+ return ((gc -> _gc_prev & _PyGC_PREV_MASK_FINALIZED ) != 0 );
79
+ }
80
+ static inline void _PyGCHead_SET_FINALIZED (PyGC_Head * gc ) {
81
+ gc -> _gc_prev |= _PyGC_PREV_MASK_FINALIZED ;
82
+ }
83
+
84
+ static inline int _PyGC_FINALIZED (PyObject * op ) {
85
+ PyGC_Head * gc = _Py_AS_GC (op );
86
+ return _PyGCHead_FINALIZED (gc );
87
+ }
88
+ static inline void _PyGC_SET_FINALIZED (PyObject * op ) {
89
+ PyGC_Head * gc = _Py_AS_GC (op );
90
+ _PyGCHead_SET_FINALIZED (gc );
91
+ }
66
92
67
93
68
94
/* GC runtime state */
0 commit comments