pycore_object.h 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. #ifndef Py_INTERNAL_OBJECT_H
  2. #define Py_INTERNAL_OBJECT_H
  3. #ifdef __cplusplus
  4. extern "C" {
  5. #endif
  6. #ifndef Py_BUILD_CORE
  7. # error "this header requires Py_BUILD_CORE define"
  8. #endif
  9. #include "pycore_pystate.h" /* _PyRuntime */
  10. PyAPI_FUNC(int) _PyType_CheckConsistency(PyTypeObject *type);
  11. PyAPI_FUNC(int) _PyDict_CheckConsistency(PyObject *mp, int check_content);
  12. /* Tell the GC to track this object.
  13. *
  14. * NB: While the object is tracked by the collector, it must be safe to call the
  15. * ob_traverse method.
  16. *
  17. * Internal note: _PyRuntime.gc.generation0->_gc_prev doesn't have any bit flags
  18. * because it's not object header. So we don't use _PyGCHead_PREV() and
  19. * _PyGCHead_SET_PREV() for it to avoid unnecessary bitwise operations.
  20. *
  21. * The PyObject_GC_Track() function is the public version of this macro.
  22. */
  23. static inline void _PyObject_GC_TRACK_impl(const char *filename, int lineno,
  24. PyObject *op)
  25. {
  26. _PyObject_ASSERT_FROM(op, !_PyObject_GC_IS_TRACKED(op),
  27. "object already tracked by the garbage collector",
  28. filename, lineno, "_PyObject_GC_TRACK");
  29. PyGC_Head *gc = _Py_AS_GC(op);
  30. _PyObject_ASSERT_FROM(op,
  31. (gc->_gc_prev & _PyGC_PREV_MASK_COLLECTING) == 0,
  32. "object is in generation which is garbage collected",
  33. filename, lineno, "_PyObject_GC_TRACK");
  34. PyGC_Head *last = (PyGC_Head*)(_PyRuntime.gc.generation0->_gc_prev);
  35. _PyGCHead_SET_NEXT(last, gc);
  36. _PyGCHead_SET_PREV(gc, last);
  37. _PyGCHead_SET_NEXT(gc, _PyRuntime.gc.generation0);
  38. _PyRuntime.gc.generation0->_gc_prev = (uintptr_t)gc;
  39. }
  40. #define _PyObject_GC_TRACK(op) \
  41. _PyObject_GC_TRACK_impl(__FILE__, __LINE__, _PyObject_CAST(op))
  42. /* Tell the GC to stop tracking this object.
  43. *
  44. * Internal note: This may be called while GC. So _PyGC_PREV_MASK_COLLECTING
  45. * must be cleared. But _PyGC_PREV_MASK_FINALIZED bit is kept.
  46. *
  47. * The object must be tracked by the GC.
  48. *
  49. * The PyObject_GC_UnTrack() function is the public version of this macro.
  50. */
  51. static inline void _PyObject_GC_UNTRACK_impl(const char *filename, int lineno,
  52. PyObject *op)
  53. {
  54. _PyObject_ASSERT_FROM(op, _PyObject_GC_IS_TRACKED(op),
  55. "object not tracked by the garbage collector",
  56. filename, lineno, "_PyObject_GC_UNTRACK");
  57. PyGC_Head *gc = _Py_AS_GC(op);
  58. PyGC_Head *prev = _PyGCHead_PREV(gc);
  59. PyGC_Head *next = _PyGCHead_NEXT(gc);
  60. _PyGCHead_SET_NEXT(prev, next);
  61. _PyGCHead_SET_PREV(next, prev);
  62. gc->_gc_next = 0;
  63. gc->_gc_prev &= _PyGC_PREV_MASK_FINALIZED;
  64. }
  65. #define _PyObject_GC_UNTRACK(op) \
  66. _PyObject_GC_UNTRACK_impl(__FILE__, __LINE__, _PyObject_CAST(op))
  67. #ifdef __cplusplus
  68. }
  69. #endif
  70. #endif /* !Py_INTERNAL_OBJECT_H */