1 | #ifndef Py_INTERNAL_OBJECT_H |
2 | #define Py_INTERNAL_OBJECT_H |
3 | #ifdef __cplusplus |
4 | extern "C" { |
5 | #endif |
6 | |
7 | #ifndef Py_BUILD_CORE |
8 | # error "this header requires Py_BUILD_CORE define" |
9 | #endif |
10 | |
11 | #include "pycore_gc.h" // _PyObject_GC_IS_TRACKED() |
12 | #include "pycore_interp.h" // PyInterpreterState.gc |
13 | #include "pycore_pystate.h" // _PyInterpreterState_GET() |
14 | |
15 | PyAPI_FUNC(int) _PyType_CheckConsistency(PyTypeObject *type); |
16 | PyAPI_FUNC(int) _PyDict_CheckConsistency(PyObject *mp, int check_content); |
17 | |
18 | /* Update the Python traceback of an object. This function must be called |
19 | when a memory block is reused from a free list. |
20 | |
21 | Internal function called by _Py_NewReference(). */ |
22 | extern int _PyTraceMalloc_NewReference(PyObject *op); |
23 | |
24 | // Fast inlined version of PyType_HasFeature() |
25 | static inline int |
26 | _PyType_HasFeature(PyTypeObject *type, unsigned long feature) { |
27 | return ((type->tp_flags & feature) != 0); |
28 | } |
29 | |
30 | extern void _PyType_InitCache(PyInterpreterState *interp); |
31 | |
32 | /* Only private in Python 3.10 and 3.9.8+; public in 3.11 */ |
33 | extern PyObject *_PyType_GetQualName(PyTypeObject *type); |
34 | |
35 | /* Inline functions trading binary compatibility for speed: |
36 | _PyObject_Init() is the fast version of PyObject_Init(), and |
37 | _PyObject_InitVar() is the fast version of PyObject_InitVar(). |
38 | |
39 | These inline functions must not be called with op=NULL. */ |
40 | static inline void |
41 | _PyObject_Init(PyObject *op, PyTypeObject *typeobj) |
42 | { |
43 | assert(op != NULL); |
44 | Py_SET_TYPE(op, typeobj); |
45 | if (_PyType_HasFeature(typeobj, Py_TPFLAGS_HEAPTYPE)) { |
46 | Py_INCREF(typeobj); |
47 | } |
48 | _Py_NewReference(op); |
49 | } |
50 | |
51 | static inline void |
52 | _PyObject_InitVar(PyVarObject *op, PyTypeObject *typeobj, Py_ssize_t size) |
53 | { |
54 | assert(op != NULL); |
55 | Py_SET_SIZE(op, size); |
56 | _PyObject_Init((PyObject *)op, typeobj); |
57 | } |
58 | |
59 | |
60 | /* Tell the GC to track this object. |
61 | * |
62 | * The object must not be tracked by the GC. |
63 | * |
64 | * NB: While the object is tracked by the collector, it must be safe to call the |
65 | * ob_traverse method. |
66 | * |
67 | * Internal note: interp->gc.generation0->_gc_prev doesn't have any bit flags |
68 | * because it's not object header. So we don't use _PyGCHead_PREV() and |
69 | * _PyGCHead_SET_PREV() for it to avoid unnecessary bitwise operations. |
70 | * |
71 | * See also the public PyObject_GC_Track() function. |
72 | */ |
73 | static inline void _PyObject_GC_TRACK( |
74 | // The preprocessor removes _PyObject_ASSERT_FROM() calls if NDEBUG is defined |
75 | #ifndef NDEBUG |
76 | const char *filename, int lineno, |
77 | #endif |
78 | PyObject *op) |
79 | { |
80 | _PyObject_ASSERT_FROM(op, !_PyObject_GC_IS_TRACKED(op), |
81 | "object already tracked by the garbage collector" , |
82 | filename, lineno, __func__); |
83 | |
84 | PyGC_Head *gc = _Py_AS_GC(op); |
85 | _PyObject_ASSERT_FROM(op, |
86 | (gc->_gc_prev & _PyGC_PREV_MASK_COLLECTING) == 0, |
87 | "object is in generation which is garbage collected" , |
88 | filename, lineno, __func__); |
89 | |
90 | PyInterpreterState *interp = _PyInterpreterState_GET(); |
91 | PyGC_Head *generation0 = interp->gc.generation0; |
92 | PyGC_Head *last = (PyGC_Head*)(generation0->_gc_prev); |
93 | _PyGCHead_SET_NEXT(last, gc); |
94 | _PyGCHead_SET_PREV(gc, last); |
95 | _PyGCHead_SET_NEXT(gc, generation0); |
96 | generation0->_gc_prev = (uintptr_t)gc; |
97 | } |
98 | |
99 | /* Tell the GC to stop tracking this object. |
100 | * |
101 | * Internal note: This may be called while GC. So _PyGC_PREV_MASK_COLLECTING |
102 | * must be cleared. But _PyGC_PREV_MASK_FINALIZED bit is kept. |
103 | * |
104 | * The object must be tracked by the GC. |
105 | * |
106 | * See also the public PyObject_GC_UnTrack() which accept an object which is |
107 | * not tracked. |
108 | */ |
109 | static inline void _PyObject_GC_UNTRACK( |
110 | // The preprocessor removes _PyObject_ASSERT_FROM() calls if NDEBUG is defined |
111 | #ifndef NDEBUG |
112 | const char *filename, int lineno, |
113 | #endif |
114 | PyObject *op) |
115 | { |
116 | _PyObject_ASSERT_FROM(op, _PyObject_GC_IS_TRACKED(op), |
117 | "object not tracked by the garbage collector" , |
118 | filename, lineno, __func__); |
119 | |
120 | PyGC_Head *gc = _Py_AS_GC(op); |
121 | PyGC_Head *prev = _PyGCHead_PREV(gc); |
122 | PyGC_Head *next = _PyGCHead_NEXT(gc); |
123 | _PyGCHead_SET_NEXT(prev, next); |
124 | _PyGCHead_SET_PREV(next, prev); |
125 | gc->_gc_next = 0; |
126 | gc->_gc_prev &= _PyGC_PREV_MASK_FINALIZED; |
127 | } |
128 | |
129 | // Macros to accept any type for the parameter, and to automatically pass |
130 | // the filename and the filename (if NDEBUG is not defined) where the macro |
131 | // is called. |
132 | #ifdef NDEBUG |
133 | # define _PyObject_GC_TRACK(op) \ |
134 | _PyObject_GC_TRACK(_PyObject_CAST(op)) |
135 | # define _PyObject_GC_UNTRACK(op) \ |
136 | _PyObject_GC_UNTRACK(_PyObject_CAST(op)) |
137 | #else |
138 | # define _PyObject_GC_TRACK(op) \ |
139 | _PyObject_GC_TRACK(__FILE__, __LINE__, _PyObject_CAST(op)) |
140 | # define _PyObject_GC_UNTRACK(op) \ |
141 | _PyObject_GC_UNTRACK(__FILE__, __LINE__, _PyObject_CAST(op)) |
142 | #endif |
143 | |
144 | #ifdef Py_REF_DEBUG |
145 | extern void _PyDebug_PrintTotalRefs(void); |
146 | #endif |
147 | |
148 | #ifdef Py_TRACE_REFS |
149 | extern void _Py_AddToAllObjects(PyObject *op, int force); |
150 | extern void _Py_PrintReferences(FILE *); |
151 | extern void _Py_PrintReferenceAddresses(FILE *); |
152 | #endif |
153 | |
154 | static inline PyObject ** |
155 | _PyObject_GET_WEAKREFS_LISTPTR(PyObject *op) |
156 | { |
157 | Py_ssize_t offset = Py_TYPE(op)->tp_weaklistoffset; |
158 | return (PyObject **)((char *)op + offset); |
159 | } |
160 | |
161 | // Fast inlined version of PyObject_IS_GC() |
162 | static inline int |
163 | _PyObject_IS_GC(PyObject *obj) |
164 | { |
165 | return (PyType_IS_GC(Py_TYPE(obj)) |
166 | && (Py_TYPE(obj)->tp_is_gc == NULL |
167 | || Py_TYPE(obj)->tp_is_gc(obj))); |
168 | } |
169 | |
170 | // Fast inlined version of PyType_IS_GC() |
171 | #define _PyType_IS_GC(t) _PyType_HasFeature((t), Py_TPFLAGS_HAVE_GC) |
172 | |
173 | // Usage: assert(_Py_CheckSlotResult(obj, "__getitem__", result != NULL)); |
174 | extern int _Py_CheckSlotResult( |
175 | PyObject *obj, |
176 | const char *slot_name, |
177 | int success); |
178 | |
179 | // PyType_Ready() must be called if _PyType_IsReady() is false. |
180 | // See also the Py_TPFLAGS_READY flag. |
181 | #define _PyType_IsReady(type) ((type)->tp_dict != NULL) |
182 | |
183 | #ifdef __cplusplus |
184 | } |
185 | #endif |
186 | #endif /* !Py_INTERNAL_OBJECT_H */ |
187 | |