Branch data Line data Source code
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 : 0 : gc_enable(PyObject *module, PyObject *Py_UNUSED(ignored))
25 : : {
26 : 0 : 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 : 0 : gc_disable(PyObject *module, PyObject *Py_UNUSED(ignored))
43 : : {
44 : 0 : 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 : 0 : gc_isenabled(PyObject *module, PyObject *Py_UNUSED(ignored))
61 : : {
62 : 0 : PyObject *return_value = NULL;
63 : : int _return_value;
64 : :
65 : 0 : _return_value = gc_isenabled_impl(module);
66 [ # # # # ]: 0 : if ((_return_value == -1) && PyErr_Occurred()) {
67 : 0 : goto exit;
68 : : }
69 : 0 : return_value = PyBool_FromLong((long)_return_value);
70 : :
71 : 0 : exit:
72 : 0 : 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 : 12 : gc_collect(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
95 : : {
96 : 12 : 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 [ - + ]: 12 : Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0;
124 : 12 : int generation = NUM_GENERATIONS - 1;
125 : : Py_ssize_t _return_value;
126 : :
127 [ + - + - : 12 : args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf);
+ - - + ]
128 [ - + ]: 12 : if (!args) {
129 : 0 : goto exit;
130 : : }
131 [ + - ]: 12 : if (!noptargs) {
132 : 12 : goto skip_optional_pos;
133 : : }
134 : 0 : generation = _PyLong_AsInt(args[0]);
135 [ # # # # ]: 0 : if (generation == -1 && PyErr_Occurred()) {
136 : 0 : goto exit;
137 : : }
138 : 0 : skip_optional_pos:
139 : 12 : _return_value = gc_collect_impl(module, generation);
140 [ - + - - ]: 12 : if ((_return_value == -1) && PyErr_Occurred()) {
141 : 0 : goto exit;
142 : : }
143 : 12 : return_value = PyLong_FromSsize_t(_return_value);
144 : :
145 : 12 : exit:
146 : 12 : 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 : 0 : gc_set_debug(PyObject *module, PyObject *arg)
174 : : {
175 : 0 : PyObject *return_value = NULL;
176 : : int flags;
177 : :
178 : 0 : flags = _PyLong_AsInt(arg);
179 [ # # # # ]: 0 : if (flags == -1 && PyErr_Occurred()) {
180 : 0 : goto exit;
181 : : }
182 : 0 : return_value = gc_set_debug_impl(module, flags);
183 : :
184 : 0 : exit:
185 : 0 : 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 : 0 : gc_get_debug(PyObject *module, PyObject *Py_UNUSED(ignored))
202 : : {
203 : 0 : PyObject *return_value = NULL;
204 : : int _return_value;
205 : :
206 : 0 : _return_value = gc_get_debug_impl(module);
207 [ # # # # ]: 0 : if ((_return_value == -1) && PyErr_Occurred()) {
208 : 0 : goto exit;
209 : : }
210 : 0 : return_value = PyLong_FromLong((long)_return_value);
211 : :
212 : 0 : exit:
213 : 0 : 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 : 0 : gc_get_threshold(PyObject *module, PyObject *Py_UNUSED(ignored))
230 : : {
231 : 0 : 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 : 0 : gc_get_count(PyObject *module, PyObject *Py_UNUSED(ignored))
248 : : {
249 : 0 : 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 : 0 : gc_get_objects(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
272 : : {
273 : 0 : 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 [ # # ]: 0 : Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0;
301 : 0 : Py_ssize_t generation = -1;
302 : :
303 [ # # # # : 0 : args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf);
# # # # ]
304 [ # # ]: 0 : if (!args) {
305 : 0 : goto exit;
306 : : }
307 [ # # ]: 0 : if (!noptargs) {
308 : 0 : goto skip_optional_pos;
309 : : }
310 [ # # ]: 0 : if (!_Py_convert_optional_to_ssize_t(args[0], &generation)) {
311 : 0 : goto exit;
312 : : }
313 : 0 : skip_optional_pos:
314 : 0 : return_value = gc_get_objects_impl(module, generation);
315 : :
316 : 0 : exit:
317 : 0 : 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 : 0 : gc_get_stats(PyObject *module, PyObject *Py_UNUSED(ignored))
334 : : {
335 : 0 : 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 : 0 : gc_freeze(PyObject *module, PyObject *Py_UNUSED(ignored))
376 : : {
377 : 0 : 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 : 0 : gc_unfreeze(PyObject *module, PyObject *Py_UNUSED(ignored))
396 : : {
397 : 0 : 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 : 0 : gc_get_freeze_count(PyObject *module, PyObject *Py_UNUSED(ignored))
414 : : {
415 : 0 : PyObject *return_value = NULL;
416 : : Py_ssize_t _return_value;
417 : :
418 : 0 : _return_value = gc_get_freeze_count_impl(module);
419 [ # # # # ]: 0 : if ((_return_value == -1) && PyErr_Occurred()) {
420 : 0 : goto exit;
421 : : }
422 : 0 : return_value = PyLong_FromSsize_t(_return_value);
423 : :
424 : 0 : exit:
425 : 0 : return return_value;
426 : : }
427 : : /*[clinic end generated code: output=66432ac0e17fd04f input=a9049054013a1b77]*/
|