summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Include/internal/pycore_gc.h100
-rw-r--r--Include/internal/pycore_interp.h2
-rw-r--r--Include/internal/pycore_pymem.h101
-rw-r--r--Modules/_tracemalloc.c3
-rw-r--r--Objects/object.c1
-rw-r--r--Python/ceval.c5
6 files changed, 107 insertions, 105 deletions
diff --git a/Include/internal/pycore_gc.h b/Include/internal/pycore_gc.h
index 7309205..62b8800 100644
--- a/Include/internal/pycore_gc.h
+++ b/Include/internal/pycore_gc.h
@@ -63,6 +63,106 @@ typedef struct {
#define _PyGC_SET_FINALIZED(o) \
_PyGCHead_SET_FINALIZED(_Py_AS_GC(o))
+
+/* GC runtime state */
+
+/* If we change this, we need to change the default value in the
+ signature of gc.collect. */
+#define NUM_GENERATIONS 3
+/*
+ NOTE: about untracking of mutable objects.
+
+ Certain types of container cannot participate in a reference cycle, and
+ so do not need to be tracked by the garbage collector. Untracking these
+ objects reduces the cost of garbage collections. However, determining
+ which objects may be untracked is not free, and the costs must be
+ weighed against the benefits for garbage collection.
+
+ There are two possible strategies for when to untrack a container:
+
+ i) When the container is created.
+ ii) When the container is examined by the garbage collector.
+
+ Tuples containing only immutable objects (integers, strings etc, and
+ recursively, tuples of immutable objects) do not need to be tracked.
+ The interpreter creates a large number of tuples, many of which will
+ not survive until garbage collection. It is therefore not worthwhile
+ to untrack eligible tuples at creation time.
+
+ Instead, all tuples except the empty tuple are tracked when created.
+ During garbage collection it is determined whether any surviving tuples
+ can be untracked. A tuple can be untracked if all of its contents are
+ already not tracked. Tuples are examined for untracking in all garbage
+ collection cycles. It may take more than one cycle to untrack a tuple.
+
+ Dictionaries containing only immutable objects also do not need to be
+ tracked. Dictionaries are untracked when created. If a tracked item is
+ inserted into a dictionary (either as a key or value), the dictionary
+ becomes tracked. During a full garbage collection (all generations),
+ the collector will untrack any dictionaries whose contents are not
+ tracked.
+
+ The module provides the python function is_tracked(obj), which returns
+ the CURRENT tracking status of the object. Subsequent garbage
+ collections may change the tracking status of the object.
+
+ Untracking of certain containers was introduced in issue #4688, and
+ the algorithm was refined in response to issue #14775.
+*/
+
+struct gc_generation {
+ PyGC_Head head;
+ int threshold; /* collection threshold */
+ int count; /* count of allocations or collections of younger
+ generations */
+};
+
+/* Running stats per generation */
+struct gc_generation_stats {
+ /* total number of collections */
+ Py_ssize_t collections;
+ /* total number of collected objects */
+ Py_ssize_t collected;
+ /* total number of uncollectable objects (put into gc.garbage) */
+ Py_ssize_t uncollectable;
+};
+
+struct _gc_runtime_state {
+ /* List of objects that still need to be cleaned up, singly linked
+ * via their gc headers' gc_prev pointers. */
+ PyObject *trash_delete_later;
+ /* Current call-stack depth of tp_dealloc calls. */
+ int trash_delete_nesting;
+
+ int enabled;
+ int debug;
+ /* linked lists of container objects */
+ struct gc_generation generations[NUM_GENERATIONS];
+ PyGC_Head *generation0;
+ /* a permanent generation which won't be collected */
+ struct gc_generation permanent_generation;
+ struct gc_generation_stats generation_stats[NUM_GENERATIONS];
+ /* true if we are currently running the collector */
+ int collecting;
+ /* list of uncollectable objects */
+ PyObject *garbage;
+ /* a list of callbacks to be invoked when collection is performed */
+ PyObject *callbacks;
+ /* This is the number of objects that survived the last full
+ collection. It approximates the number of long lived objects
+ tracked by the GC.
+
+ (by "full collection", we mean a collection of the oldest
+ generation). */
+ Py_ssize_t long_lived_total;
+ /* This is the number of objects that survived all "non-full"
+ collections, and are awaiting to undergo a full collection for
+ the first time. */
+ Py_ssize_t long_lived_pending;
+};
+
+PyAPI_FUNC(void) _PyGC_InitState(struct _gc_runtime_state *);
+
#ifdef __cplusplus
}
#endif
diff --git a/Include/internal/pycore_interp.h b/Include/internal/pycore_interp.h
index d720829..c6fc6af 100644
--- a/Include/internal/pycore_interp.h
+++ b/Include/internal/pycore_interp.h
@@ -10,7 +10,7 @@ extern "C" {
#include "pycore_atomic.h" /* _Py_atomic_address */
#include "pycore_gil.h" /* struct _gil_runtime_state */
-#include "pycore_pymem.h" /* struct _gc_runtime_state */
+#include "pycore_gc.h" /* struct _gc_runtime_state */
#include "pycore_warnings.h" /* struct _warnings_runtime_state */
/* ceval state */
diff --git a/Include/internal/pycore_pymem.h b/Include/internal/pycore_pymem.h
index 34a17d5..18203e3 100644
--- a/Include/internal/pycore_pymem.h
+++ b/Include/internal/pycore_pymem.h
@@ -9,107 +9,6 @@ extern "C" {
#endif
#include "pymem.h" // PyMemAllocatorName
-#include "pycore_gc.h" // PyGC_Head
-
-
-/* GC runtime state */
-
-/* If we change this, we need to change the default value in the
- signature of gc.collect. */
-#define NUM_GENERATIONS 3
-/*
- NOTE: about untracking of mutable objects.
-
- Certain types of container cannot participate in a reference cycle, and
- so do not need to be tracked by the garbage collector. Untracking these
- objects reduces the cost of garbage collections. However, determining
- which objects may be untracked is not free, and the costs must be
- weighed against the benefits for garbage collection.
-
- There are two possible strategies for when to untrack a container:
-
- i) When the container is created.
- ii) When the container is examined by the garbage collector.
-
- Tuples containing only immutable objects (integers, strings etc, and
- recursively, tuples of immutable objects) do not need to be tracked.
- The interpreter creates a large number of tuples, many of which will
- not survive until garbage collection. It is therefore not worthwhile
- to untrack eligible tuples at creation time.
-
- Instead, all tuples except the empty tuple are tracked when created.
- During garbage collection it is determined whether any surviving tuples
- can be untracked. A tuple can be untracked if all of its contents are
- already not tracked. Tuples are examined for untracking in all garbage
- collection cycles. It may take more than one cycle to untrack a tuple.
-
- Dictionaries containing only immutable objects also do not need to be
- tracked. Dictionaries are untracked when created. If a tracked item is
- inserted into a dictionary (either as a key or value), the dictionary
- becomes tracked. During a full garbage collection (all generations),
- the collector will untrack any dictionaries whose contents are not
- tracked.
-
- The module provides the python function is_tracked(obj), which returns
- the CURRENT tracking status of the object. Subsequent garbage
- collections may change the tracking status of the object.
-
- Untracking of certain containers was introduced in issue #4688, and
- the algorithm was refined in response to issue #14775.
-*/
-
-struct gc_generation {
- PyGC_Head head;
- int threshold; /* collection threshold */
- int count; /* count of allocations or collections of younger
- generations */
-};
-
-/* Running stats per generation */
-struct gc_generation_stats {
- /* total number of collections */
- Py_ssize_t collections;
- /* total number of collected objects */
- Py_ssize_t collected;
- /* total number of uncollectable objects (put into gc.garbage) */
- Py_ssize_t uncollectable;
-};
-
-struct _gc_runtime_state {
- /* List of objects that still need to be cleaned up, singly linked
- * via their gc headers' gc_prev pointers. */
- PyObject *trash_delete_later;
- /* Current call-stack depth of tp_dealloc calls. */
- int trash_delete_nesting;
-
- int enabled;
- int debug;
- /* linked lists of container objects */
- struct gc_generation generations[NUM_GENERATIONS];
- PyGC_Head *generation0;
- /* a permanent generation which won't be collected */
- struct gc_generation permanent_generation;
- struct gc_generation_stats generation_stats[NUM_GENERATIONS];
- /* true if we are currently running the collector */
- int collecting;
- /* list of uncollectable objects */
- PyObject *garbage;
- /* a list of callbacks to be invoked when collection is performed */
- PyObject *callbacks;
- /* This is the number of objects that survived the last full
- collection. It approximates the number of long lived objects
- tracked by the GC.
-
- (by "full collection", we mean a collection of the oldest
- generation). */
- Py_ssize_t long_lived_total;
- /* This is the number of objects that survived all "non-full"
- collections, and are awaiting to undergo a full collection for
- the first time. */
- Py_ssize_t long_lived_pending;
-};
-
-PyAPI_FUNC(void) _PyGC_InitState(struct _gc_runtime_state *);
/* Set the memory allocator of the specified domain to the default.
diff --git a/Modules/_tracemalloc.c b/Modules/_tracemalloc.c
index bef44db..6f3f31a 100644
--- a/Modules/_tracemalloc.c
+++ b/Modules/_tracemalloc.c
@@ -1,5 +1,6 @@
#include "Python.h"
-#include "pycore_pymem.h"
+#include "pycore_gc.h" // PyGC_Head
+#include "pycore_pymem.h" // _Py_tracemalloc_config
#include "pycore_traceback.h"
#include "hashtable.h"
#include "frameobject.h"
diff --git a/Objects/object.c b/Objects/object.c
index 4fa488e..c759ccc 100644
--- a/Objects/object.c
+++ b/Objects/object.c
@@ -8,6 +8,7 @@
#include "pycore_object.h"
#include "pycore_pyerrors.h"
#include "pycore_pylifecycle.h"
+#include "pycore_pymem.h" // _PyMem_IsPtrFreed()
#include "pycore_pystate.h" // _PyThreadState_GET()
#include "frameobject.h"
#include "interpreteridobject.h"
diff --git a/Python/ceval.c b/Python/ceval.c
index 77b7a83..505f05c 100644
--- a/Python/ceval.c
+++ b/Python/ceval.c
@@ -10,7 +10,7 @@
#define PY_LOCAL_AGGRESSIVE
#include "Python.h"
-#include "pycore_abstract.h" // _PyIndex_Check()
+#include "pycore_abstract.h" // _PyIndex_Check()
#include "pycore_call.h"
#include "pycore_ceval.h"
#include "pycore_code.h"
@@ -18,7 +18,8 @@
#include "pycore_object.h"
#include "pycore_pyerrors.h"
#include "pycore_pylifecycle.h"
-#include "pycore_pystate.h" // _PyInterpreterState_GET()
+#include "pycore_pymem.h" // _PyMem_IsPtrFreed()
+#include "pycore_pystate.h" // _PyInterpreterState_GET()
#include "pycore_sysmodule.h"
#include "pycore_tupleobject.h"