1 /*[clinic input]
2 preserve
3 [clinic start generated code]*/
4
5 #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
6 # include "pycore_gc.h" // PyGC_Head
7 # include "pycore_runtime.h" // _Py_ID()
8 #endif
9
10
11 PyDoc_STRVAR(gc_enable__doc__,
12 "enable($module, /)\n"
13 "--\n"
14 "\n"
15 "Enable automatic garbage collection.");
16
17 #define GC_ENABLE_METHODDEF \
18 {"enable", (PyCFunction)gc_enable, METH_NOARGS, gc_enable__doc__},
19
20 static PyObject *
21 gc_enable_impl(PyObject *module);
22
23 static PyObject *
24 gc_enable(PyObject *module, PyObject *Py_UNUSED(ignored))
25 {
26 return gc_enable_impl(module);
27 }
28
29 PyDoc_STRVAR(gc_disable__doc__,
30 "disable($module, /)\n"
31 "--\n"
32 "\n"
33 "Disable automatic garbage collection.");
34
35 #define GC_DISABLE_METHODDEF \
36 {"disable", (PyCFunction)gc_disable, METH_NOARGS, gc_disable__doc__},
37
38 static PyObject *
39 gc_disable_impl(PyObject *module);
40
41 static PyObject *
42 gc_disable(PyObject *module, PyObject *Py_UNUSED(ignored))
43 {
44 return gc_disable_impl(module);
45 }
46
47 PyDoc_STRVAR(gc_isenabled__doc__,
48 "isenabled($module, /)\n"
49 "--\n"
50 "\n"
51 "Returns true if automatic garbage collection is enabled.");
52
53 #define GC_ISENABLED_METHODDEF \
54 {"isenabled", (PyCFunction)gc_isenabled, METH_NOARGS, gc_isenabled__doc__},
55
56 static int
57 gc_isenabled_impl(PyObject *module);
58
59 static PyObject *
60 gc_isenabled(PyObject *module, PyObject *Py_UNUSED(ignored))
61 {
62 PyObject *return_value = NULL;
63 int _return_value;
64
65 _return_value = gc_isenabled_impl(module);
66 if ((_return_value == -1) && PyErr_Occurred()) {
67 goto exit;
68 }
69 return_value = PyBool_FromLong((long)_return_value);
70
71 exit:
72 return return_value;
73 }
74
75 PyDoc_STRVAR(gc_collect__doc__,
76 "collect($module, /, generation=2)\n"
77 "--\n"
78 "\n"
79 "Run the garbage collector.\n"
80 "\n"
81 "With no arguments, run a full collection. The optional argument\n"
82 "may be an integer specifying which generation to collect. A ValueError\n"
83 "is raised if the generation number is invalid.\n"
84 "\n"
85 "The number of unreachable objects is returned.");
86
87 #define GC_COLLECT_METHODDEF \
88 {"collect", _PyCFunction_CAST(gc_collect), METH_FASTCALL|METH_KEYWORDS, gc_collect__doc__},
89
90 static Py_ssize_t
91 gc_collect_impl(PyObject *module, int generation);
92
93 static PyObject *
94 gc_collect(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
95 {
96 PyObject *return_value = NULL;
97 #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
98
99 #define NUM_KEYWORDS 1
100 static struct {
101 PyGC_Head _this_is_not_used;
102 PyObject_VAR_HEAD
103 PyObject *ob_item[NUM_KEYWORDS];
104 } _kwtuple = {
105 .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS)
106 .ob_item = { &_Py_ID(generation), },
107 };
108 #undef NUM_KEYWORDS
109 #define KWTUPLE (&_kwtuple.ob_base.ob_base)
110
111 #else // !Py_BUILD_CORE
112 # define KWTUPLE NULL
113 #endif // !Py_BUILD_CORE
114
115 static const char * const _keywords[] = {"generation", NULL};
116 static _PyArg_Parser _parser = {
117 .keywords = _keywords,
118 .fname = "collect",
119 .kwtuple = KWTUPLE,
120 };
121 #undef KWTUPLE
122 PyObject *argsbuf[1];
123 Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0;
124 int generation = NUM_GENERATIONS - 1;
125 Py_ssize_t _return_value;
126
127 args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf);
128 if (!args) {
129 goto exit;
130 }
131 if (!noptargs) {
132 goto skip_optional_pos;
133 }
134 generation = _PyLong_AsInt(args[0]);
135 if (generation == -1 && PyErr_Occurred()) {
136 goto exit;
137 }
138 skip_optional_pos:
139 _return_value = gc_collect_impl(module, generation);
140 if ((_return_value == -1) && PyErr_Occurred()) {
141 goto exit;
142 }
143 return_value = PyLong_FromSsize_t(_return_value);
144
145 exit:
146 return return_value;
147 }
148
149 PyDoc_STRVAR(gc_set_debug__doc__,
150 "set_debug($module, flags, /)\n"
151 "--\n"
152 "\n"
153 "Set the garbage collection debugging flags.\n"
154 "\n"
155 " flags\n"
156 " An integer that can have the following bits turned on:\n"
157 " DEBUG_STATS - Print statistics during collection.\n"
158 " DEBUG_COLLECTABLE - Print collectable objects found.\n"
159 " DEBUG_UNCOLLECTABLE - Print unreachable but uncollectable objects\n"
160 " found.\n"
161 " DEBUG_SAVEALL - Save objects to gc.garbage rather than freeing them.\n"
162 " DEBUG_LEAK - Debug leaking programs (everything but STATS).\n"
163 "\n"
164 "Debugging information is written to sys.stderr.");
165
166 #define GC_SET_DEBUG_METHODDEF \
167 {"set_debug", (PyCFunction)gc_set_debug, METH_O, gc_set_debug__doc__},
168
169 static PyObject *
170 gc_set_debug_impl(PyObject *module, int flags);
171
172 static PyObject *
173 gc_set_debug(PyObject *module, PyObject *arg)
174 {
175 PyObject *return_value = NULL;
176 int flags;
177
178 flags = _PyLong_AsInt(arg);
179 if (flags == -1 && PyErr_Occurred()) {
180 goto exit;
181 }
182 return_value = gc_set_debug_impl(module, flags);
183
184 exit:
185 return return_value;
186 }
187
188 PyDoc_STRVAR(gc_get_debug__doc__,
189 "get_debug($module, /)\n"
190 "--\n"
191 "\n"
192 "Get the garbage collection debugging flags.");
193
194 #define GC_GET_DEBUG_METHODDEF \
195 {"get_debug", (PyCFunction)gc_get_debug, METH_NOARGS, gc_get_debug__doc__},
196
197 static int
198 gc_get_debug_impl(PyObject *module);
199
200 static PyObject *
201 gc_get_debug(PyObject *module, PyObject *Py_UNUSED(ignored))
202 {
203 PyObject *return_value = NULL;
204 int _return_value;
205
206 _return_value = gc_get_debug_impl(module);
207 if ((_return_value == -1) && PyErr_Occurred()) {
208 goto exit;
209 }
210 return_value = PyLong_FromLong((long)_return_value);
211
212 exit:
213 return return_value;
214 }
215
216 PyDoc_STRVAR(gc_get_threshold__doc__,
217 "get_threshold($module, /)\n"
218 "--\n"
219 "\n"
220 "Return the current collection thresholds.");
221
222 #define GC_GET_THRESHOLD_METHODDEF \
223 {"get_threshold", (PyCFunction)gc_get_threshold, METH_NOARGS, gc_get_threshold__doc__},
224
225 static PyObject *
226 gc_get_threshold_impl(PyObject *module);
227
228 static PyObject *
229 gc_get_threshold(PyObject *module, PyObject *Py_UNUSED(ignored))
230 {
231 return gc_get_threshold_impl(module);
232 }
233
234 PyDoc_STRVAR(gc_get_count__doc__,
235 "get_count($module, /)\n"
236 "--\n"
237 "\n"
238 "Return a three-tuple of the current collection counts.");
239
240 #define GC_GET_COUNT_METHODDEF \
241 {"get_count", (PyCFunction)gc_get_count, METH_NOARGS, gc_get_count__doc__},
242
243 static PyObject *
244 gc_get_count_impl(PyObject *module);
245
246 static PyObject *
247 gc_get_count(PyObject *module, PyObject *Py_UNUSED(ignored))
248 {
249 return gc_get_count_impl(module);
250 }
251
252 PyDoc_STRVAR(gc_get_objects__doc__,
253 "get_objects($module, /, generation=None)\n"
254 "--\n"
255 "\n"
256 "Return a list of objects tracked by the collector (excluding the list returned).\n"
257 "\n"
258 " generation\n"
259 " Generation to extract the objects from.\n"
260 "\n"
261 "If generation is not None, return only the objects tracked by the collector\n"
262 "that are in that generation.");
263
264 #define GC_GET_OBJECTS_METHODDEF \
265 {"get_objects", _PyCFunction_CAST(gc_get_objects), METH_FASTCALL|METH_KEYWORDS, gc_get_objects__doc__},
266
267 static PyObject *
268 gc_get_objects_impl(PyObject *module, Py_ssize_t generation);
269
270 static PyObject *
271 gc_get_objects(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
272 {
273 PyObject *return_value = NULL;
274 #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
275
276 #define NUM_KEYWORDS 1
277 static struct {
278 PyGC_Head _this_is_not_used;
279 PyObject_VAR_HEAD
280 PyObject *ob_item[NUM_KEYWORDS];
281 } _kwtuple = {
282 .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS)
283 .ob_item = { &_Py_ID(generation), },
284 };
285 #undef NUM_KEYWORDS
286 #define KWTUPLE (&_kwtuple.ob_base.ob_base)
287
288 #else // !Py_BUILD_CORE
289 # define KWTUPLE NULL
290 #endif // !Py_BUILD_CORE
291
292 static const char * const _keywords[] = {"generation", NULL};
293 static _PyArg_Parser _parser = {
294 .keywords = _keywords,
295 .fname = "get_objects",
296 .kwtuple = KWTUPLE,
297 };
298 #undef KWTUPLE
299 PyObject *argsbuf[1];
300 Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0;
301 Py_ssize_t generation = -1;
302
303 args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf);
304 if (!args) {
305 goto exit;
306 }
307 if (!noptargs) {
308 goto skip_optional_pos;
309 }
310 if (!_Py_convert_optional_to_ssize_t(args[0], &generation)) {
311 goto exit;
312 }
313 skip_optional_pos:
314 return_value = gc_get_objects_impl(module, generation);
315
316 exit:
317 return return_value;
318 }
319
320 PyDoc_STRVAR(gc_get_stats__doc__,
321 "get_stats($module, /)\n"
322 "--\n"
323 "\n"
324 "Return a list of dictionaries containing per-generation statistics.");
325
326 #define GC_GET_STATS_METHODDEF \
327 {"get_stats", (PyCFunction)gc_get_stats, METH_NOARGS, gc_get_stats__doc__},
328
329 static PyObject *
330 gc_get_stats_impl(PyObject *module);
331
332 static PyObject *
333 gc_get_stats(PyObject *module, PyObject *Py_UNUSED(ignored))
334 {
335 return gc_get_stats_impl(module);
336 }
337
338 PyDoc_STRVAR(gc_is_tracked__doc__,
339 "is_tracked($module, obj, /)\n"
340 "--\n"
341 "\n"
342 "Returns true if the object is tracked by the garbage collector.\n"
343 "\n"
344 "Simple atomic objects will return false.");
345
346 #define GC_IS_TRACKED_METHODDEF \
347 {"is_tracked", (PyCFunction)gc_is_tracked, METH_O, gc_is_tracked__doc__},
348
349 PyDoc_STRVAR(gc_is_finalized__doc__,
350 "is_finalized($module, obj, /)\n"
351 "--\n"
352 "\n"
353 "Returns true if the object has been already finalized by the GC.");
354
355 #define GC_IS_FINALIZED_METHODDEF \
356 {"is_finalized", (PyCFunction)gc_is_finalized, METH_O, gc_is_finalized__doc__},
357
358 PyDoc_STRVAR(gc_freeze__doc__,
359 "freeze($module, /)\n"
360 "--\n"
361 "\n"
362 "Freeze all current tracked objects and ignore them for future collections.\n"
363 "\n"
364 "This can be used before a POSIX fork() call to make the gc copy-on-write friendly.\n"
365 "Note: collection before a POSIX fork() call may free pages for future allocation\n"
366 "which can cause copy-on-write.");
367
368 #define GC_FREEZE_METHODDEF \
369 {"freeze", (PyCFunction)gc_freeze, METH_NOARGS, gc_freeze__doc__},
370
371 static PyObject *
372 gc_freeze_impl(PyObject *module);
373
374 static PyObject *
375 gc_freeze(PyObject *module, PyObject *Py_UNUSED(ignored))
376 {
377 return gc_freeze_impl(module);
378 }
379
380 PyDoc_STRVAR(gc_unfreeze__doc__,
381 "unfreeze($module, /)\n"
382 "--\n"
383 "\n"
384 "Unfreeze all objects in the permanent generation.\n"
385 "\n"
386 "Put all objects in the permanent generation back into oldest generation.");
387
388 #define GC_UNFREEZE_METHODDEF \
389 {"unfreeze", (PyCFunction)gc_unfreeze, METH_NOARGS, gc_unfreeze__doc__},
390
391 static PyObject *
392 gc_unfreeze_impl(PyObject *module);
393
394 static PyObject *
395 gc_unfreeze(PyObject *module, PyObject *Py_UNUSED(ignored))
396 {
397 return gc_unfreeze_impl(module);
398 }
399
400 PyDoc_STRVAR(gc_get_freeze_count__doc__,
401 "get_freeze_count($module, /)\n"
402 "--\n"
403 "\n"
404 "Return the number of objects in the permanent generation.");
405
406 #define GC_GET_FREEZE_COUNT_METHODDEF \
407 {"get_freeze_count", (PyCFunction)gc_get_freeze_count, METH_NOARGS, gc_get_freeze_count__doc__},
408
409 static Py_ssize_t
410 gc_get_freeze_count_impl(PyObject *module);
411
412 static PyObject *
413 gc_get_freeze_count(PyObject *module, PyObject *Py_UNUSED(ignored))
414 {
415 PyObject *return_value = NULL;
416 Py_ssize_t _return_value;
417
418 _return_value = gc_get_freeze_count_impl(module);
419 if ((_return_value == -1) && PyErr_Occurred()) {
420 goto exit;
421 }
422 return_value = PyLong_FromSsize_t(_return_value);
423
424 exit:
425 return return_value;
426 }
427 /*[clinic end generated code: output=66432ac0e17fd04f input=a9049054013a1b77]*/