bpo-40241: Add pycore_gc.h header file (GH-19494) · python/cpython@0135598 (original) (raw)

`@@ -125,61 +125,12 @@ PyAPI_FUNC(Py_ssize_t) _PyGC_CollectIfEnabled(void);

`

125

125

` (PyType_IS_GC(Py_TYPE(o)) \

`

126

126

` && (Py_TYPE(o)->tp_is_gc == NULL || Py_TYPE(o)->tp_is_gc(o)))

`

127

127

``

128

``

`-

/* GC information is stored BEFORE the object structure. */

`

129

``

`-

typedef struct {

`

130

``

`-

// Pointer to next object in the list.

`

131

``

`-

// 0 means the object is not tracked

`

132

``

`-

uintptr_t _gc_next;

`

133

``

-

134

``

`-

// Pointer to previous object in the list.

`

135

``

`-

// Lowest two bits are used for flags documented later.

`

136

``

`-

uintptr_t _gc_prev;

`

137

``

`-

} PyGC_Head;

`

138

``

-

139

``

`-

#define _Py_AS_GC(o) ((PyGC_Head *)(o)-1)

`

140

``

-

141

``

`-

/* True if the object is currently tracked by the GC. */

`

142

``

`-

#define _PyObject_GC_IS_TRACKED(o) (_Py_AS_GC(o)->_gc_next != 0)

`

143

``

-

144

``

`-

/* True if the object may be tracked by the GC in the future, or already is.

`

145

``

`-

This can be useful to implement some optimizations. */

`

146

``

`-

#define _PyObject_GC_MAY_BE_TRACKED(obj) \

`

147

``

`-

(PyObject_IS_GC(obj) && \

`

148

``

`-

(!PyTuple_CheckExact(obj) || _PyObject_GC_IS_TRACKED(obj)))

`

149

``

-

150

``

-

151

``

`-

/* Bit flags for _gc_prev */

`

152

``

`-

/* Bit 0 is set when tp_finalize is called */

`

153

``

`-

#define _PyGC_PREV_MASK_FINALIZED (1)

`

154

``

`-

/* Bit 1 is set when the object is in generation which is GCed currently. */

`

155

``

`-

#define _PyGC_PREV_MASK_COLLECTING (2)

`

156

``

`-

/* The (N-2) most significant bits contain the real address. */

`

157

``

`-

#define _PyGC_PREV_SHIFT (2)

`

158

``

`-

#define _PyGC_PREV_MASK (((uintptr_t) -1) << _PyGC_PREV_SHIFT)

`

159

``

-

160

``

`-

// Lowest bit of _gc_next is used for flags only in GC.

`

161

``

`-

// But it is always 0 for normal code.

`

162

``

`-

#define _PyGCHead_NEXT(g) ((PyGC_Head*)(g)->_gc_next)

`

163

``

`-

#define _PyGCHead_SET_NEXT(g, p) ((g)->_gc_next = (uintptr_t)(p))

`

164

``

-

165

``

`-

// Lowest two bits of _gc_prev is used for PyGC_PREV_MASK* flags.

`

166

``

`-

#define _PyGCHead_PREV(g) ((PyGC_Head*)((g)->_gc_prev & _PyGC_PREV_MASK))

`

167

``

`-

#define _PyGCHead_SET_PREV(g, p) do { \

`

168

``

`-

assert(((uintptr_t)p & ~_PyGC_PREV_MASK) == 0); \

`

169

``

`-

(g)->_gc_prev = ((g)->_gc_prev & ~_PyGC_PREV_MASK) \

`

170

``

`-

| ((uintptr_t)(p)); \

`

171

``

`-

} while (0)

`

172

``

-

173

``

`-

#define _PyGCHead_FINALIZED(g) \

`

174

``

`-

(((g)->_gc_prev & _PyGC_PREV_MASK_FINALIZED) != 0)

`

175

``

`-

#define _PyGCHead_SET_FINALIZED(g) \

`

176

``

`-

((g)->_gc_prev |= _PyGC_PREV_MASK_FINALIZED)

`

177

``

-

178

``

`-

#define _PyGC_FINALIZED(o) \

`

179

``

`-

_PyGCHead_FINALIZED(_Py_AS_GC(o))

`

180

``

`-

#define _PyGC_SET_FINALIZED(o) \

`

181

``

`-

_PyGCHead_SET_FINALIZED(_Py_AS_GC(o))

`

182

``

-

``

128

`+

/* Code built with Py_BUILD_CORE must include pycore_gc.h instead which

`

``

129

`+

defines a different _PyGC_FINALIZED() macro. */

`

``

130

`+

#ifndef Py_BUILD_CORE

`

``

131

`+

// Kept for backward compatibility with Python 3.8

`

``

132

`+

define _PyGC_FINALIZED(o) PyObject_GC_IsFinalized(o)

`

``

133

`+

#endif

`

183

134

``

184

135

`PyAPI_FUNC(PyObject *) _PyObject_GC_Malloc(size_t size);

`

185

136

`PyAPI_FUNC(PyObject *) _PyObject_GC_Calloc(size_t size);

`