pycore_tracemalloc.h 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. #ifndef Py_INTERNAL_TRACEMALLOC_H
  2. #define Py_INTERNAL_TRACEMALLOC_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_hashtable.h" // _Py_hashtable_t
  10. /* Trace memory blocks allocated by PyMem_RawMalloc() */
  11. #define TRACE_RAW_MALLOC
  12. struct _PyTraceMalloc_Config {
  13. /* Module initialized?
  14. Variable protected by the GIL */
  15. enum {
  16. TRACEMALLOC_NOT_INITIALIZED,
  17. TRACEMALLOC_INITIALIZED,
  18. TRACEMALLOC_FINALIZED
  19. } initialized;
  20. /* Is tracemalloc tracing memory allocations?
  21. Variable protected by the GIL */
  22. int tracing;
  23. /* limit of the number of frames in a traceback, 1 by default.
  24. Variable protected by the GIL. */
  25. int max_nframe;
  26. };
  27. /* Pack the frame_t structure to reduce the memory footprint on 64-bit
  28. architectures: 12 bytes instead of 16. */
  29. #if defined(_MSC_VER)
  30. #pragma pack(push, 4)
  31. #endif
  32. struct
  33. #ifdef __GNUC__
  34. __attribute__((packed))
  35. #endif
  36. tracemalloc_frame {
  37. /* filename cannot be NULL: "<unknown>" is used if the Python frame
  38. filename is NULL */
  39. PyObject *filename;
  40. unsigned int lineno;
  41. };
  42. #ifdef _MSC_VER
  43. #pragma pack(pop)
  44. #endif
  45. struct tracemalloc_traceback {
  46. Py_uhash_t hash;
  47. /* Number of frames stored */
  48. uint16_t nframe;
  49. /* Total number of frames the traceback had */
  50. uint16_t total_nframe;
  51. struct tracemalloc_frame frames[1];
  52. };
  53. struct _tracemalloc_runtime_state {
  54. struct _PyTraceMalloc_Config config;
  55. /* Protected by the GIL */
  56. struct {
  57. PyMemAllocatorEx mem;
  58. PyMemAllocatorEx raw;
  59. PyMemAllocatorEx obj;
  60. } allocators;
  61. #if defined(TRACE_RAW_MALLOC)
  62. PyThread_type_lock tables_lock;
  63. #endif
  64. /* Size in bytes of currently traced memory.
  65. Protected by TABLES_LOCK(). */
  66. size_t traced_memory;
  67. /* Peak size in bytes of traced memory.
  68. Protected by TABLES_LOCK(). */
  69. size_t peak_traced_memory;
  70. /* Hash table used as a set to intern filenames:
  71. PyObject* => PyObject*.
  72. Protected by the GIL */
  73. _Py_hashtable_t *filenames;
  74. /* Buffer to store a new traceback in traceback_new().
  75. Protected by the GIL. */
  76. struct tracemalloc_traceback *traceback;
  77. /* Hash table used as a set to intern tracebacks:
  78. traceback_t* => traceback_t*
  79. Protected by the GIL */
  80. _Py_hashtable_t *tracebacks;
  81. /* pointer (void*) => trace (trace_t*).
  82. Protected by TABLES_LOCK(). */
  83. _Py_hashtable_t *traces;
  84. /* domain (unsigned int) => traces (_Py_hashtable_t).
  85. Protected by TABLES_LOCK(). */
  86. _Py_hashtable_t *domains;
  87. struct tracemalloc_traceback empty_traceback;
  88. Py_tss_t reentrant_key;
  89. };
  90. #define _tracemalloc_runtime_state_INIT \
  91. { \
  92. .config = { \
  93. .initialized = TRACEMALLOC_NOT_INITIALIZED, \
  94. .tracing = 0, \
  95. .max_nframe = 1, \
  96. }, \
  97. .reentrant_key = Py_tss_NEEDS_INIT, \
  98. }
  99. #ifdef __cplusplus
  100. }
  101. #endif
  102. #endif // !Py_INTERNAL_TRACEMALLOC_H