| | #ifndef Py_INTERNAL_OBJECT_H |
| | #define Py_INTERNAL_OBJECT_H |
| | #ifdef __cplusplus |
| | extern "C" { |
| | #endif |
| |
|
| | #ifndef Py_BUILD_CORE |
| | # error "this header requires Py_BUILD_CORE define" |
| | #endif |
| |
|
| | #include "pycore_gc.h" |
| | #include "pycore_interp.h" |
| | #include "pycore_pystate.h" |
| |
|
| | PyAPI_FUNC(int) _PyType_CheckConsistency(PyTypeObject *type); |
| | PyAPI_FUNC(int) _PyDict_CheckConsistency(PyObject *mp, int check_content); |
| |
|
| | |
| | extern PyObject *_PyType_GetQualName(PyTypeObject *type); |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | static inline void _PyObject_GC_TRACK_impl(const char *filename, int lineno, |
| | PyObject *op) |
| | { |
| | _PyObject_ASSERT_FROM(op, !_PyObject_GC_IS_TRACKED(op), |
| | "object already tracked by the garbage collector", |
| | filename, lineno, "_PyObject_GC_TRACK"); |
| |
|
| | PyGC_Head *gc = _Py_AS_GC(op); |
| | _PyObject_ASSERT_FROM(op, |
| | (gc->_gc_prev & _PyGC_PREV_MASK_COLLECTING) == 0, |
| | "object is in generation which is garbage collected", |
| | filename, lineno, "_PyObject_GC_TRACK"); |
| |
|
| | PyThreadState *tstate = _PyThreadState_GET(); |
| | PyGC_Head *generation0 = tstate->interp->gc.generation0; |
| | PyGC_Head *last = (PyGC_Head*)(generation0->_gc_prev); |
| | _PyGCHead_SET_NEXT(last, gc); |
| | _PyGCHead_SET_PREV(gc, last); |
| | _PyGCHead_SET_NEXT(gc, generation0); |
| | generation0->_gc_prev = (uintptr_t)gc; |
| | } |
| |
|
| | #define _PyObject_GC_TRACK(op) \ |
| | _PyObject_GC_TRACK_impl(__FILE__, __LINE__, _PyObject_CAST(op)) |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | static inline void _PyObject_GC_UNTRACK_impl(const char *filename, int lineno, |
| | PyObject *op) |
| | { |
| | _PyObject_ASSERT_FROM(op, _PyObject_GC_IS_TRACKED(op), |
| | "object not tracked by the garbage collector", |
| | filename, lineno, "_PyObject_GC_UNTRACK"); |
| |
|
| | PyGC_Head *gc = _Py_AS_GC(op); |
| | PyGC_Head *prev = _PyGCHead_PREV(gc); |
| | PyGC_Head *next = _PyGCHead_NEXT(gc); |
| | _PyGCHead_SET_NEXT(prev, next); |
| | _PyGCHead_SET_PREV(next, prev); |
| | gc->_gc_next = 0; |
| | gc->_gc_prev &= _PyGC_PREV_MASK_FINALIZED; |
| | } |
| |
|
| | #define _PyObject_GC_UNTRACK(op) \ |
| | _PyObject_GC_UNTRACK_impl(__FILE__, __LINE__, _PyObject_CAST(op)) |
| |
|
| | #ifdef Py_REF_DEBUG |
| | extern void _PyDebug_PrintTotalRefs(void); |
| | #endif |
| |
|
| | #ifdef Py_TRACE_REFS |
| | extern void _Py_AddToAllObjects(PyObject *op, int force); |
| | extern void _Py_PrintReferences(FILE *); |
| | extern void _Py_PrintReferenceAddresses(FILE *); |
| | #endif |
| |
|
| | static inline PyObject ** |
| | _PyObject_GET_WEAKREFS_LISTPTR(PyObject *op) |
| | { |
| | Py_ssize_t offset = Py_TYPE(op)->tp_weaklistoffset; |
| | return (PyObject **)((char *)op + offset); |
| | } |
| |
|
| | |
| | static inline int |
| | _PyType_HasFeature(PyTypeObject *type, unsigned long feature) { |
| | return ((type->tp_flags & feature) != 0); |
| | } |
| |
|
| | |
| | static inline int |
| | _PyObject_IS_GC(PyObject *obj) |
| | { |
| | return (PyType_IS_GC(Py_TYPE(obj)) |
| | && (Py_TYPE(obj)->tp_is_gc == NULL |
| | || Py_TYPE(obj)->tp_is_gc(obj))); |
| | } |
| |
|
| | |
| | #define _PyType_IS_GC(t) _PyType_HasFeature((t), Py_TPFLAGS_HAVE_GC) |
| |
|
| | #ifdef __cplusplus |
| | } |
| | #endif |
| | #endif |
| |
|