Branch data Line data Source code
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 <stdbool.h>
12 : : #include "pycore_gc.h" // _PyObject_GC_IS_TRACKED()
13 : : #include "pycore_interp.h" // PyInterpreterState.gc
14 : : #include "pycore_pystate.h" // _PyInterpreterState_GET()
15 : : #include "pycore_runtime.h" // _PyRuntime
16 : :
17 : : #define _PyObject_IMMORTAL_INIT(type) \
18 : : { \
19 : : .ob_refcnt = 999999999, \
20 : : .ob_type = (type), \
21 : : }
22 : : #define _PyVarObject_IMMORTAL_INIT(type, size) \
23 : : { \
24 : : .ob_base = _PyObject_IMMORTAL_INIT(type), \
25 : : .ob_size = size, \
26 : : }
27 : :
28 : : PyAPI_FUNC(void) _Py_NO_RETURN _Py_FatalRefcountErrorFunc(
29 : : const char *func,
30 : : const char *message);
31 : :
32 : : #define _Py_FatalRefcountError(message) \
33 : : _Py_FatalRefcountErrorFunc(__func__, (message))
34 : :
35 : : static inline void
36 : 10128997 : _Py_DECREF_SPECIALIZED(PyObject *op, const destructor destruct)
37 : : {
38 : : _Py_DECREF_STAT_INC();
39 : : #ifdef Py_REF_DEBUG
40 : : _Py_RefTotal--;
41 : : #endif
42 [ + + ]: 10128997 : if (--op->ob_refcnt != 0) {
43 : : assert(op->ob_refcnt > 0);
44 : : }
45 : : else {
46 : : #ifdef Py_TRACE_REFS
47 : : _Py_ForgetReference(op);
48 : : #endif
49 : 10119199 : destruct(op);
50 : : }
51 : 10128997 : }
52 : :
53 : : static inline void
54 : 309769543 : _Py_DECREF_NO_DEALLOC(PyObject *op)
55 : : {
56 : : _Py_DECREF_STAT_INC();
57 : : #ifdef Py_REF_DEBUG
58 : : _Py_RefTotal--;
59 : : #endif
60 : 309769543 : op->ob_refcnt--;
61 : : #ifdef Py_DEBUG
62 : : if (op->ob_refcnt <= 0) {
63 : : _Py_FatalRefcountError("Expected a positive remaining refcount");
64 : : }
65 : : #endif
66 : 309769543 : }
67 : :
68 : : PyAPI_FUNC(int) _PyType_CheckConsistency(PyTypeObject *type);
69 : : PyAPI_FUNC(int) _PyDict_CheckConsistency(PyObject *mp, int check_content);
70 : :
71 : : /* Update the Python traceback of an object. This function must be called
72 : : when a memory block is reused from a free list.
73 : :
74 : : Internal function called by _Py_NewReference(). */
75 : : extern int _PyTraceMalloc_NewReference(PyObject *op);
76 : :
77 : : // Fast inlined version of PyType_HasFeature()
78 : : static inline int
79 : 2518012457 : _PyType_HasFeature(PyTypeObject *type, unsigned long feature) {
80 : 2518012457 : return ((type->tp_flags & feature) != 0);
81 : : }
82 : :
83 : : extern void _PyType_InitCache(PyInterpreterState *interp);
84 : :
85 : :
86 : : /* Inline functions trading binary compatibility for speed:
87 : : _PyObject_Init() is the fast version of PyObject_Init(), and
88 : : _PyObject_InitVar() is the fast version of PyObject_InitVar().
89 : :
90 : : These inline functions must not be called with op=NULL. */
91 : : static inline void
92 : 889173207 : _PyObject_Init(PyObject *op, PyTypeObject *typeobj)
93 : : {
94 : : assert(op != NULL);
95 : 889173207 : Py_SET_TYPE(op, typeobj);
96 [ + + ]: 889173207 : if (_PyType_HasFeature(typeobj, Py_TPFLAGS_HEAPTYPE)) {
97 : 42983880 : Py_INCREF(typeobj);
98 : : }
99 : 889173207 : _Py_NewReference(op);
100 : 889173207 : }
101 : :
102 : : static inline void
103 : 307829448 : _PyObject_InitVar(PyVarObject *op, PyTypeObject *typeobj, Py_ssize_t size)
104 : : {
105 : : assert(op != NULL);
106 : 307829448 : Py_SET_SIZE(op, size);
107 : 307829448 : _PyObject_Init((PyObject *)op, typeobj);
108 : 307829448 : }
109 : :
110 : :
111 : : /* Tell the GC to track this object.
112 : : *
113 : : * The object must not be tracked by the GC.
114 : : *
115 : : * NB: While the object is tracked by the collector, it must be safe to call the
116 : : * ob_traverse method.
117 : : *
118 : : * Internal note: interp->gc.generation0->_gc_prev doesn't have any bit flags
119 : : * because it's not object header. So we don't use _PyGCHead_PREV() and
120 : : * _PyGCHead_SET_PREV() for it to avoid unnecessary bitwise operations.
121 : : *
122 : : * See also the public PyObject_GC_Track() function.
123 : : */
124 : 675536062 : static inline void _PyObject_GC_TRACK(
125 : : // The preprocessor removes _PyObject_ASSERT_FROM() calls if NDEBUG is defined
126 : : #ifndef NDEBUG
127 : : const char *filename, int lineno,
128 : : #endif
129 : : PyObject *op)
130 : : {
131 : : _PyObject_ASSERT_FROM(op, !_PyObject_GC_IS_TRACKED(op),
132 : : "object already tracked by the garbage collector",
133 : : filename, lineno, __func__);
134 : :
135 : 675536062 : PyGC_Head *gc = _Py_AS_GC(op);
136 : : _PyObject_ASSERT_FROM(op,
137 : : (gc->_gc_prev & _PyGC_PREV_MASK_COLLECTING) == 0,
138 : : "object is in generation which is garbage collected",
139 : : filename, lineno, __func__);
140 : :
141 : 675536062 : PyInterpreterState *interp = _PyInterpreterState_GET();
142 : 675536062 : PyGC_Head *generation0 = interp->gc.generation0;
143 : 675536062 : PyGC_Head *last = (PyGC_Head*)(generation0->_gc_prev);
144 : 675536062 : _PyGCHead_SET_NEXT(last, gc);
145 : 675536062 : _PyGCHead_SET_PREV(gc, last);
146 : 675536062 : _PyGCHead_SET_NEXT(gc, generation0);
147 : 675536062 : generation0->_gc_prev = (uintptr_t)gc;
148 : 675536062 : }
149 : :
150 : : /* Tell the GC to stop tracking this object.
151 : : *
152 : : * Internal note: This may be called while GC. So _PyGC_PREV_MASK_COLLECTING
153 : : * must be cleared. But _PyGC_PREV_MASK_FINALIZED bit is kept.
154 : : *
155 : : * The object must be tracked by the GC.
156 : : *
157 : : * See also the public PyObject_GC_UnTrack() which accept an object which is
158 : : * not tracked.
159 : : */
160 : 673285221 : static inline void _PyObject_GC_UNTRACK(
161 : : // The preprocessor removes _PyObject_ASSERT_FROM() calls if NDEBUG is defined
162 : : #ifndef NDEBUG
163 : : const char *filename, int lineno,
164 : : #endif
165 : : PyObject *op)
166 : : {
167 : : _PyObject_ASSERT_FROM(op, _PyObject_GC_IS_TRACKED(op),
168 : : "object not tracked by the garbage collector",
169 : : filename, lineno, __func__);
170 : :
171 : 673285221 : PyGC_Head *gc = _Py_AS_GC(op);
172 : 673285221 : PyGC_Head *prev = _PyGCHead_PREV(gc);
173 : 673285221 : PyGC_Head *next = _PyGCHead_NEXT(gc);
174 : 673285221 : _PyGCHead_SET_NEXT(prev, next);
175 : 673285221 : _PyGCHead_SET_PREV(next, prev);
176 : 673285221 : gc->_gc_next = 0;
177 : 673285221 : gc->_gc_prev &= _PyGC_PREV_MASK_FINALIZED;
178 : 673285221 : }
179 : :
180 : : // Macros to accept any type for the parameter, and to automatically pass
181 : : // the filename and the filename (if NDEBUG is not defined) where the macro
182 : : // is called.
183 : : #ifdef NDEBUG
184 : : # define _PyObject_GC_TRACK(op) \
185 : : _PyObject_GC_TRACK(_PyObject_CAST(op))
186 : : # define _PyObject_GC_UNTRACK(op) \
187 : : _PyObject_GC_UNTRACK(_PyObject_CAST(op))
188 : : #else
189 : : # define _PyObject_GC_TRACK(op) \
190 : : _PyObject_GC_TRACK(__FILE__, __LINE__, _PyObject_CAST(op))
191 : : # define _PyObject_GC_UNTRACK(op) \
192 : : _PyObject_GC_UNTRACK(__FILE__, __LINE__, _PyObject_CAST(op))
193 : : #endif
194 : :
195 : : #ifdef Py_REF_DEBUG
196 : : extern void _PyDebug_PrintTotalRefs(void);
197 : : #endif
198 : :
199 : : #ifdef Py_TRACE_REFS
200 : : extern void _Py_AddToAllObjects(PyObject *op, int force);
201 : : extern void _Py_PrintReferences(FILE *);
202 : : extern void _Py_PrintReferenceAddresses(FILE *);
203 : : #endif
204 : :
205 : : static inline PyObject **
206 : 45224634 : _PyObject_GET_WEAKREFS_LISTPTR(PyObject *op)
207 : : {
208 : 45224634 : Py_ssize_t offset = Py_TYPE(op)->tp_weaklistoffset;
209 : 45224634 : return (PyObject **)((char *)op + offset);
210 : : }
211 : :
212 : : // Fast inlined version of PyObject_IS_GC()
213 : : static inline int
214 : 5687375176 : _PyObject_IS_GC(PyObject *obj)
215 : : {
216 : 5687375176 : return (PyType_IS_GC(Py_TYPE(obj))
217 [ + + + + ]: 6386574231 : && (Py_TYPE(obj)->tp_is_gc == NULL
218 [ + + ]: 699199055 : || Py_TYPE(obj)->tp_is_gc(obj)));
219 : : }
220 : :
221 : : // Fast inlined version of PyType_IS_GC()
222 : : #define _PyType_IS_GC(t) _PyType_HasFeature((t), Py_TPFLAGS_HAVE_GC)
223 : :
224 : : static inline size_t
225 : 634172532 : _PyType_PreHeaderSize(PyTypeObject *tp)
226 : : {
227 : 634172532 : return _PyType_IS_GC(tp) * sizeof(PyGC_Head) +
228 : 634172532 : _PyType_HasFeature(tp, Py_TPFLAGS_MANAGED_DICT) * 2 * sizeof(PyObject *);
229 : : }
230 : :
231 : : void _PyObject_GC_Link(PyObject *op);
232 : :
233 : : // Usage: assert(_Py_CheckSlotResult(obj, "__getitem__", result != NULL));
234 : : extern int _Py_CheckSlotResult(
235 : : PyObject *obj,
236 : : const char *slot_name,
237 : : int success);
238 : :
239 : : // PyType_Ready() must be called if _PyType_IsReady() is false.
240 : : // See also the Py_TPFLAGS_READY flag.
241 : : #define _PyType_IsReady(type) ((type)->tp_dict != NULL)
242 : :
243 : : // Test if a type supports weak references
244 : 47747567 : static inline int _PyType_SUPPORTS_WEAKREFS(PyTypeObject *type) {
245 : 47747567 : return (type->tp_weaklistoffset > 0);
246 : : }
247 : :
248 : : extern PyObject* _PyType_AllocNoTrack(PyTypeObject *type, Py_ssize_t nitems);
249 : :
250 : : extern int _PyObject_InitializeDict(PyObject *obj);
251 : : extern int _PyObject_StoreInstanceAttribute(PyObject *obj, PyDictValues *values,
252 : : PyObject *name, PyObject *value);
253 : : PyObject * _PyObject_GetInstanceAttribute(PyObject *obj, PyDictValues *values,
254 : : PyObject *name);
255 : :
256 : 528790963 : static inline PyDictValues **_PyObject_ValuesPointer(PyObject *obj)
257 : : {
258 : : assert(Py_TYPE(obj)->tp_flags & Py_TPFLAGS_MANAGED_DICT);
259 : 528790963 : return ((PyDictValues **)obj)-4;
260 : : }
261 : :
262 : 226774640 : static inline PyObject **_PyObject_ManagedDictPointer(PyObject *obj)
263 : : {
264 : : assert(Py_TYPE(obj)->tp_flags & Py_TPFLAGS_MANAGED_DICT);
265 : 226774640 : return ((PyObject **)obj)-3;
266 : : }
267 : :
268 : : #define MANAGED_DICT_OFFSET (((int)sizeof(PyObject *))*-3)
269 : :
270 : : extern PyObject ** _PyObject_DictPointer(PyObject *);
271 : : extern int _PyObject_VisitInstanceAttributes(PyObject *self, visitproc visit, void *arg);
272 : : extern void _PyObject_ClearInstanceAttributes(PyObject *self);
273 : : extern void _PyObject_FreeInstanceAttributes(PyObject *self);
274 : : extern int _PyObject_IsInstanceDictEmpty(PyObject *);
275 : : extern PyObject* _PyType_GetSubclasses(PyTypeObject *);
276 : :
277 : : // Access macro to the members which are floating "behind" the object
278 : : #define _PyHeapType_GET_MEMBERS(etype) \
279 : : ((PyMemberDef *)(((char *)(etype)) + Py_TYPE(etype)->tp_basicsize))
280 : :
281 : : PyAPI_FUNC(PyObject *) _PyObject_LookupSpecial(PyObject *, PyObject *);
282 : :
283 : : /* C function call trampolines to mitigate bad function pointer casts.
284 : : *
285 : : * Typical native ABIs ignore additional arguments or fill in missing
286 : : * values with 0/NULL in function pointer cast. Compilers do not show
287 : : * warnings when a function pointer is explicitly casted to an
288 : : * incompatible type.
289 : : *
290 : : * Bad fpcasts are an issue in WebAssembly. WASM's indirect_call has strict
291 : : * function signature checks. Argument count, types, and return type must
292 : : * match.
293 : : *
294 : : * Third party code unintentionally rely on problematic fpcasts. The call
295 : : * trampoline mitigates common occurences of bad fpcasts on Emscripten.
296 : : */
297 : : #if defined(__EMSCRIPTEN__) && defined(PY_CALL_TRAMPOLINE)
298 : : #define _PyCFunction_TrampolineCall(meth, self, args) \
299 : : _PyCFunctionWithKeywords_TrampolineCall( \
300 : : (*(PyCFunctionWithKeywords)(void(*)(void))(meth)), (self), (args), NULL)
301 : : extern PyObject* _PyCFunctionWithKeywords_TrampolineCall(
302 : : PyCFunctionWithKeywords meth, PyObject *, PyObject *, PyObject *);
303 : : #else
304 : : #define _PyCFunction_TrampolineCall(meth, self, args) \
305 : : (meth)((self), (args))
306 : : #define _PyCFunctionWithKeywords_TrampolineCall(meth, self, args, kw) \
307 : : (meth)((self), (args), (kw))
308 : : #endif // __EMSCRIPTEN__ && PY_CALL_TRAMPOLINE
309 : :
310 : : #ifdef __cplusplus
311 : : }
312 : : #endif
313 : : #endif /* !Py_INTERNAL_OBJECT_H */
|