pycore_pymem.h 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  1. #ifndef Py_INTERNAL_PYMEM_H
  2. #define Py_INTERNAL_PYMEM_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 "objimpl.h"
  10. #include "pymem.h"
  11. /* GC runtime state */
  12. /* If we change this, we need to change the default value in the
  13. signature of gc.collect. */
  14. #define NUM_GENERATIONS 3
  15. /*
  16. NOTE: about the counting of long-lived objects.
  17. To limit the cost of garbage collection, there are two strategies;
  18. - make each collection faster, e.g. by scanning fewer objects
  19. - do less collections
  20. This heuristic is about the latter strategy.
  21. In addition to the various configurable thresholds, we only trigger a
  22. full collection if the ratio
  23. long_lived_pending / long_lived_total
  24. is above a given value (hardwired to 25%).
  25. The reason is that, while "non-full" collections (i.e., collections of
  26. the young and middle generations) will always examine roughly the same
  27. number of objects -- determined by the aforementioned thresholds --,
  28. the cost of a full collection is proportional to the total number of
  29. long-lived objects, which is virtually unbounded.
  30. Indeed, it has been remarked that doing a full collection every
  31. <constant number> of object creations entails a dramatic performance
  32. degradation in workloads which consist in creating and storing lots of
  33. long-lived objects (e.g. building a large list of GC-tracked objects would
  34. show quadratic performance, instead of linear as expected: see issue #4074).
  35. Using the above ratio, instead, yields amortized linear performance in
  36. the total number of objects (the effect of which can be summarized
  37. thusly: "each full garbage collection is more and more costly as the
  38. number of objects grows, but we do fewer and fewer of them").
  39. This heuristic was suggested by Martin von Löwis on python-dev in
  40. June 2008. His original analysis and proposal can be found at:
  41. http://mail.python.org/pipermail/python-dev/2008-June/080579.html
  42. */
  43. /*
  44. NOTE: about untracking of mutable objects.
  45. Certain types of container cannot participate in a reference cycle, and
  46. so do not need to be tracked by the garbage collector. Untracking these
  47. objects reduces the cost of garbage collections. However, determining
  48. which objects may be untracked is not free, and the costs must be
  49. weighed against the benefits for garbage collection.
  50. There are two possible strategies for when to untrack a container:
  51. i) When the container is created.
  52. ii) When the container is examined by the garbage collector.
  53. Tuples containing only immutable objects (integers, strings etc, and
  54. recursively, tuples of immutable objects) do not need to be tracked.
  55. The interpreter creates a large number of tuples, many of which will
  56. not survive until garbage collection. It is therefore not worthwhile
  57. to untrack eligible tuples at creation time.
  58. Instead, all tuples except the empty tuple are tracked when created.
  59. During garbage collection it is determined whether any surviving tuples
  60. can be untracked. A tuple can be untracked if all of its contents are
  61. already not tracked. Tuples are examined for untracking in all garbage
  62. collection cycles. It may take more than one cycle to untrack a tuple.
  63. Dictionaries containing only immutable objects also do not need to be
  64. tracked. Dictionaries are untracked when created. If a tracked item is
  65. inserted into a dictionary (either as a key or value), the dictionary
  66. becomes tracked. During a full garbage collection (all generations),
  67. the collector will untrack any dictionaries whose contents are not
  68. tracked.
  69. The module provides the python function is_tracked(obj), which returns
  70. the CURRENT tracking status of the object. Subsequent garbage
  71. collections may change the tracking status of the object.
  72. Untracking of certain containers was introduced in issue #4688, and
  73. the algorithm was refined in response to issue #14775.
  74. */
  75. struct gc_generation {
  76. PyGC_Head head;
  77. int threshold; /* collection threshold */
  78. int count; /* count of allocations or collections of younger
  79. generations */
  80. };
  81. /* Running stats per generation */
  82. struct gc_generation_stats {
  83. /* total number of collections */
  84. Py_ssize_t collections;
  85. /* total number of collected objects */
  86. Py_ssize_t collected;
  87. /* total number of uncollectable objects (put into gc.garbage) */
  88. Py_ssize_t uncollectable;
  89. };
  90. struct _gc_runtime_state {
  91. /* List of objects that still need to be cleaned up, singly linked
  92. * via their gc headers' gc_prev pointers. */
  93. PyObject *trash_delete_later;
  94. /* Current call-stack depth of tp_dealloc calls. */
  95. int trash_delete_nesting;
  96. int enabled;
  97. int debug;
  98. /* linked lists of container objects */
  99. struct gc_generation generations[NUM_GENERATIONS];
  100. PyGC_Head *generation0;
  101. /* a permanent generation which won't be collected */
  102. struct gc_generation permanent_generation;
  103. struct gc_generation_stats generation_stats[NUM_GENERATIONS];
  104. /* true if we are currently running the collector */
  105. int collecting;
  106. /* list of uncollectable objects */
  107. PyObject *garbage;
  108. /* a list of callbacks to be invoked when collection is performed */
  109. PyObject *callbacks;
  110. /* This is the number of objects that survived the last full
  111. collection. It approximates the number of long lived objects
  112. tracked by the GC.
  113. (by "full collection", we mean a collection of the oldest
  114. generation). */
  115. Py_ssize_t long_lived_total;
  116. /* This is the number of objects that survived all "non-full"
  117. collections, and are awaiting to undergo a full collection for
  118. the first time. */
  119. Py_ssize_t long_lived_pending;
  120. };
  121. PyAPI_FUNC(void) _PyGC_Initialize(struct _gc_runtime_state *);
  122. /* Set the memory allocator of the specified domain to the default.
  123. Save the old allocator into *old_alloc if it's non-NULL.
  124. Return on success, or return -1 if the domain is unknown. */
  125. PyAPI_FUNC(int) _PyMem_SetDefaultAllocator(
  126. PyMemAllocatorDomain domain,
  127. PyMemAllocatorEx *old_alloc);
  128. /* Heuristic checking if a pointer value is newly allocated
  129. (uninitialized) or newly freed. The pointer is not dereferenced, only the
  130. pointer value is checked.
  131. The heuristic relies on the debug hooks on Python memory allocators which
  132. fills newly allocated memory with CLEANBYTE (0xCD) and newly freed memory
  133. with DEADBYTE (0xDD). Detect also "untouchable bytes" marked
  134. with FORBIDDENBYTE (0xFD). */
  135. static inline int _PyMem_IsPtrFreed(void *ptr)
  136. {
  137. uintptr_t value = (uintptr_t)ptr;
  138. #if SIZEOF_VOID_P == 8
  139. return (value == (uintptr_t)0xCDCDCDCDCDCDCDCD
  140. || value == (uintptr_t)0xDDDDDDDDDDDDDDDD
  141. || value == (uintptr_t)0xFDFDFDFDFDFDFDFD);
  142. #elif SIZEOF_VOID_P == 4
  143. return (value == (uintptr_t)0xCDCDCDCD
  144. || value == (uintptr_t)0xDDDDDDDD
  145. || value == (uintptr_t)0xFDFDFDFD);
  146. #else
  147. # error "unknown pointer size"
  148. #endif
  149. }
  150. PyAPI_FUNC(int) _PyMem_GetAllocatorName(
  151. const char *name,
  152. PyMemAllocatorName *allocator);
  153. /* Configure the Python memory allocators.
  154. Pass PYMEM_ALLOCATOR_DEFAULT to use default allocators.
  155. PYMEM_ALLOCATOR_NOT_SET does nothing. */
  156. PyAPI_FUNC(int) _PyMem_SetupAllocators(PyMemAllocatorName allocator);
  157. #ifdef __cplusplus
  158. }
  159. #endif
  160. #endif /* !Py_INTERNAL_PYMEM_H */