blob: a879ef6c2d0f9a153536958152ec5a574cb56a7d [file] [log] [blame]
Jeremy Hyltonc5007aa2000-06-30 05:02:53 +00001/*
2
3 Reference Cycle Garbage Collection
4 ==================================
5
Neil Schemenauerb2c2c9e2000-10-04 16:34:09 +00006 Neil Schemenauer <nas@arctrix.com>
Jeremy Hyltonc5007aa2000-06-30 05:02:53 +00007
8 Based on a post on the python-dev list. Ideas from Guido van Rossum,
9 Eric Tiedemann, and various others.
10
Neil Schemenauerb2c2c9e2000-10-04 16:34:09 +000011 http://www.arctrix.com/nas/python/gc.html
Jeremy Hyltonc5007aa2000-06-30 05:02:53 +000012 http://www.python.org/pipermail/python-dev/2000-March/003869.html
13 http://www.python.org/pipermail/python-dev/2000-March/004010.html
14 http://www.python.org/pipermail/python-dev/2000-March/004022.html
15
16 For a highlevel view of the collection process, read the collect
17 function.
18
Jeremy Hyltonc5007aa2000-06-30 05:02:53 +000019*/
20
21
22#include "Python.h"
23
24#ifdef WITH_CYCLE_GC
25
26/* magic gc_refs value */
27#define GC_MOVED -1
28
29/*** Global GC state ***/
30
31/* linked lists of container objects */
32static PyGC_Head generation0 = {&generation0, &generation0, 0};
33static PyGC_Head generation1 = {&generation1, &generation1, 0};
34static PyGC_Head generation2 = {&generation2, &generation2, 0};
35static int generation = 0; /* current generation being collected */
36
37/* collection frequencies, XXX tune these */
Vladimir Marangozovf9d20c32000-08-06 22:45:31 +000038static int enabled = 1; /* automatic collection enabled? */
Jeremy Hylton3263dc2b2000-09-05 15:44:50 +000039static int threshold0 = 700; /* net new containers before collection */
Jeremy Hyltonc5007aa2000-06-30 05:02:53 +000040static int threshold1 = 10; /* generation0 collections before collecting 1 */
41static int threshold2 = 10; /* generation1 collections before collecting 2 */
42
43/* net new objects allocated since last collection */
44static int allocated;
45
46/* set for debugging information */
47#define DEBUG_STATS (1<<0) /* print collection statistics */
48#define DEBUG_COLLECTABLE (1<<1) /* print collectable objects */
49#define DEBUG_UNCOLLECTABLE (1<<2) /* print uncollectable objects */
50#define DEBUG_INSTANCES (1<<3) /* print instances */
51#define DEBUG_OBJECTS (1<<4) /* print other objects */
Neil Schemenauer544de1e2000-09-22 15:22:38 +000052#define DEBUG_SAVEALL (1<<5) /* save all garbage in gc.garbage */
Jeremy Hyltonc5007aa2000-06-30 05:02:53 +000053#define DEBUG_LEAK DEBUG_COLLECTABLE | \
54 DEBUG_UNCOLLECTABLE | \
55 DEBUG_INSTANCES | \
Neil Schemenauer544de1e2000-09-22 15:22:38 +000056 DEBUG_OBJECTS | \
57 DEBUG_SAVEALL
Jeremy Hyltonb709df32000-09-01 02:47:25 +000058static int debug;
Jeremy Hyltonc5007aa2000-06-30 05:02:53 +000059
60/* list of uncollectable objects */
61static PyObject *garbage;
62
Jeremy Hyltonb709df32000-09-01 02:47:25 +000063/* Python string to use if unhandled exception occurs */
64static PyObject *gc_str;
Jeremy Hyltonc5007aa2000-06-30 05:02:53 +000065
66/*** list functions ***/
67
68static void
69gc_list_init(PyGC_Head *list)
70{
71 list->gc_prev = list;
72 list->gc_next = list;
73}
74
75static void
76gc_list_append(PyGC_Head *node, PyGC_Head *list)
77{
78 node->gc_next = list;
79 node->gc_prev = list->gc_prev;
80 node->gc_prev->gc_next = node;
81 list->gc_prev = node;
82}
83
84static void
85gc_list_remove(PyGC_Head *node)
86{
87 node->gc_prev->gc_next = node->gc_next;
88 node->gc_next->gc_prev = node->gc_prev;
89#ifdef Py_DEBUG
90 node->gc_prev = NULL;
91 node->gc_next = NULL;
92#endif
93}
94
95static void
96gc_list_move(PyGC_Head *from, PyGC_Head *to)
97{
98 if (from->gc_next == from) {
99 /* empty from list */
100 gc_list_init(to);
Neil Schemenauer544de1e2000-09-22 15:22:38 +0000101 }
102 else {
Jeremy Hyltonc5007aa2000-06-30 05:02:53 +0000103 to->gc_next = from->gc_next;
104 to->gc_next->gc_prev = to;
105 to->gc_prev = from->gc_prev;
106 to->gc_prev->gc_next = to;
107 }
108 gc_list_init(from);
109}
110
111/* append a list onto another list, from becomes an empty list */
112static void
113gc_list_merge(PyGC_Head *from, PyGC_Head *to)
114{
115 PyGC_Head *tail;
116 if (from->gc_next != from) {
117 tail = to->gc_prev;
118 tail->gc_next = from->gc_next;
119 tail->gc_next->gc_prev = tail;
120 to->gc_prev = from->gc_prev;
121 to->gc_prev->gc_next = to;
122 }
123 gc_list_init(from);
124}
125
126static long
127gc_list_size(PyGC_Head *list)
128{
129 PyGC_Head *gc;
130 long n = 0;
131 for (gc = list->gc_next; gc != list; gc = gc->gc_next) {
132 n++;
133 }
134 return n;
135}
136
137/*** end of list stuff ***/
138
139
140/* Set all gc_refs = ob_refcnt */
141static void
142update_refs(PyGC_Head *containers)
143{
144 PyGC_Head *gc = containers->gc_next;
145 for (; gc != containers; gc=gc->gc_next) {
146 gc->gc_refs = PyObject_FROM_GC(gc)->ob_refcnt;
147 }
148}
149
150static int
151visit_decref(PyObject *op, void *data)
152{
153 if (op && PyObject_IS_GC(op)) {
154 PyObject_AS_GC(op)->gc_refs--;
155 }
156 return 0;
157}
158
159/* Subtract internal references from gc_refs */
160static void
161subtract_refs(PyGC_Head *containers)
162{
163 traverseproc traverse;
164 PyGC_Head *gc = containers->gc_next;
165 for (; gc != containers; gc=gc->gc_next) {
166 traverse = PyObject_FROM_GC(gc)->ob_type->tp_traverse;
167 (void) traverse(PyObject_FROM_GC(gc),
168 (visitproc)visit_decref,
169 NULL);
170 }
171}
172
173/* Append objects with gc_refs > 0 to roots list */
174static void
175move_roots(PyGC_Head *containers, PyGC_Head *roots)
176{
177 PyGC_Head *next;
178 PyGC_Head *gc = containers->gc_next;
179 while (gc != containers) {
180 next = gc->gc_next;
181 if (gc->gc_refs > 0) {
182 gc_list_remove(gc);
183 gc_list_append(gc, roots);
184 gc->gc_refs = GC_MOVED;
185 }
186 gc = next;
187 }
188}
189
190static int
191visit_reachable(PyObject *op, PyGC_Head *roots)
192{
193 if (PyObject_IS_GC(op)) {
194 PyGC_Head *gc = PyObject_AS_GC(op);
195 if (gc && gc->gc_refs != GC_MOVED) {
196 gc_list_remove(gc);
197 gc_list_append(gc, roots);
198 gc->gc_refs = GC_MOVED;
199 }
200 }
201 return 0;
202}
203
204/* Move objects referenced from reachable to reachable set. */
205static void
206move_root_reachable(PyGC_Head *reachable)
207{
208 traverseproc traverse;
209 PyGC_Head *gc = reachable->gc_next;
210 for (; gc != reachable; gc=gc->gc_next) {
211 /* careful, reachable list is growing here */
212 PyObject *op = PyObject_FROM_GC(gc);
213 traverse = op->ob_type->tp_traverse;
214 (void) traverse(op,
215 (visitproc)visit_reachable,
216 (void *)reachable);
217 }
218}
219
220/* move all objects with finalizers (instances with __del__) */
221static void
222move_finalizers(PyGC_Head *unreachable, PyGC_Head *finalizers)
223{
224 PyGC_Head *next;
225 PyGC_Head *gc = unreachable->gc_next;
Jeremy Hylton06257772000-08-31 15:10:24 +0000226 static PyObject *delstr = NULL;
Jeremy Hyltonc5007aa2000-06-30 05:02:53 +0000227 if (delstr == NULL) {
228 delstr = PyString_InternFromString("__del__");
Jeremy Hylton06257772000-08-31 15:10:24 +0000229 if (delstr == NULL)
230 Py_FatalError("PyGC: can't initialize __del__ string");
Jeremy Hyltonc5007aa2000-06-30 05:02:53 +0000231 }
232 for (; gc != unreachable; gc=next) {
233 PyObject *op = PyObject_FROM_GC(gc);
234 next = gc->gc_next;
235 if (PyInstance_Check(op) && PyObject_HasAttr(op, delstr)) {
236 gc_list_remove(gc);
237 gc_list_append(gc, finalizers);
238 }
239 }
240}
241
242
243/* called by tp_traverse */
244static int
245visit_finalizer_reachable(PyObject *op, PyGC_Head *finalizers)
246{
247 if (PyObject_IS_GC(op)) {
248 PyGC_Head *gc = PyObject_AS_GC(op);
249 if (gc && gc->gc_refs != GC_MOVED) {
250 gc_list_remove(gc);
251 gc_list_append(gc, finalizers);
252 gc->gc_refs = GC_MOVED;
253 }
254 }
255 return 0;
256}
257
258/* Move objects referenced from roots to roots */
259static void
260move_finalizer_reachable(PyGC_Head *finalizers)
261{
262 traverseproc traverse;
263 PyGC_Head *gc = finalizers->gc_next;
264 for (; gc != finalizers; gc=gc->gc_next) {
265 /* careful, finalizers list is growing here */
266 traverse = PyObject_FROM_GC(gc)->ob_type->tp_traverse;
267 (void) traverse(PyObject_FROM_GC(gc),
268 (visitproc)visit_finalizer_reachable,
269 (void *)finalizers);
270 }
271}
272
273static void
Jeremy Hylton06257772000-08-31 15:10:24 +0000274debug_instance(char *msg, PyInstanceObject *inst)
Jeremy Hyltonc5007aa2000-06-30 05:02:53 +0000275{
Jeremy Hyltonc5007aa2000-06-30 05:02:53 +0000276 char *cname;
277 /* be careful not to create new dictionaries */
278 PyObject *classname = inst->in_class->cl_name;
279 if (classname != NULL && PyString_Check(classname))
280 cname = PyString_AsString(classname);
281 else
282 cname = "?";
Jeremy Hylton06257772000-08-31 15:10:24 +0000283 PySys_WriteStderr("gc: %.100s <%.100s instance at %p>\n",
284 msg, cname, inst);
Jeremy Hyltonc5007aa2000-06-30 05:02:53 +0000285}
286
287static void
Jeremy Hylton06257772000-08-31 15:10:24 +0000288debug_cycle(char *msg, PyObject *op)
Jeremy Hyltonc5007aa2000-06-30 05:02:53 +0000289{
290 if ((debug & DEBUG_INSTANCES) && PyInstance_Check(op)) {
Jeremy Hylton06257772000-08-31 15:10:24 +0000291 debug_instance(msg, (PyInstanceObject *)op);
Neil Schemenauer544de1e2000-09-22 15:22:38 +0000292 }
293 else if (debug & DEBUG_OBJECTS) {
Jeremy Hylton06257772000-08-31 15:10:24 +0000294 PySys_WriteStderr("gc: %.100s <%.100s %p>\n",
295 msg, op->ob_type->tp_name, op);
Jeremy Hyltonc5007aa2000-06-30 05:02:53 +0000296 }
297}
298
299/* Handle uncollectable garbage (cycles with finalizers). */
300static void
301handle_finalizers(PyGC_Head *finalizers, PyGC_Head *old)
302{
303 PyGC_Head *gc;
304 if (garbage == NULL) {
305 garbage = PyList_New(0);
306 }
307 for (gc = finalizers->gc_next; gc != finalizers;
308 gc = finalizers->gc_next) {
309 PyObject *op = PyObject_FROM_GC(gc);
Neil Schemenauer544de1e2000-09-22 15:22:38 +0000310 if ((debug & DEBUG_SAVEALL) || PyInstance_Check(op)) {
311 /* If SAVEALL is not set then just append
312 * instances to the list of garbage. We assume
313 * that all objects in the finalizers list are
314 * reachable from instances. */
Jeremy Hyltonc5007aa2000-06-30 05:02:53 +0000315 PyList_Append(garbage, op);
316 }
Neil Schemenauer544de1e2000-09-22 15:22:38 +0000317 /* object is now reachable again */
Jeremy Hyltonc5007aa2000-06-30 05:02:53 +0000318 gc_list_remove(gc);
319 gc_list_append(gc, old);
320 }
321}
322
Neil Schemenauer544de1e2000-09-22 15:22:38 +0000323/* Break reference cycles by clearing the containers involved. This is
Jeremy Hyltonc5007aa2000-06-30 05:02:53 +0000324 * tricky business as the lists can be changing and we don't know which
325 * objects may be freed. It is possible I screwed something up here. */
326static void
327delete_garbage(PyGC_Head *unreachable, PyGC_Head *old)
328{
329 inquiry clear;
330
331 while (unreachable->gc_next != unreachable) {
332 PyGC_Head *gc = unreachable->gc_next;
333 PyObject *op = PyObject_FROM_GC(gc);
Neil Schemenauer544de1e2000-09-22 15:22:38 +0000334 if (debug & DEBUG_SAVEALL) {
335 PyList_Append(garbage, op);
Jeremy Hyltonc5007aa2000-06-30 05:02:53 +0000336 }
Neil Schemenauer544de1e2000-09-22 15:22:38 +0000337 else {
338 if ((clear = op->ob_type->tp_clear) != NULL) {
339 Py_INCREF(op);
340 clear((PyObject *)op);
341 Py_DECREF(op);
342 }
343 }
Jeremy Hyltonc5007aa2000-06-30 05:02:53 +0000344 if (unreachable->gc_next == gc) {
Neil Schemenauer544de1e2000-09-22 15:22:38 +0000345 /* object is still alive, move it, it may die later */
Jeremy Hyltonc5007aa2000-06-30 05:02:53 +0000346 gc_list_remove(gc);
347 gc_list_append(gc, old);
348 }
349 }
350}
351
352/* This is the main function. Read this to understand how the
353 * collection process works. */
354static long
355collect(PyGC_Head *young, PyGC_Head *old)
356{
357 long n = 0;
358 long m = 0;
359 PyGC_Head reachable;
360 PyGC_Head unreachable;
361 PyGC_Head finalizers;
362 PyGC_Head *gc;
Jeremy Hyltonc5007aa2000-06-30 05:02:53 +0000363
Jeremy Hyltonc5007aa2000-06-30 05:02:53 +0000364 if (debug & DEBUG_STATS) {
Jeremy Hylton06257772000-08-31 15:10:24 +0000365 PySys_WriteStderr(
366 "gc: collecting generation %d...\n"
367 "gc: objects in each generation: %ld %ld %ld\n",
368 generation,
Jeremy Hyltonc5007aa2000-06-30 05:02:53 +0000369 gc_list_size(&generation0),
370 gc_list_size(&generation1),
371 gc_list_size(&generation2));
Jeremy Hyltonc5007aa2000-06-30 05:02:53 +0000372 }
373
374 /* Using ob_refcnt and gc_refs, calculate which objects in the
375 * container set are reachable from outside the set (ie. have a
376 * refcount greater than 0 when all the references within the
377 * set are taken into account */
378 update_refs(young);
379 subtract_refs(young);
380
381 /* Move everything reachable from outside the set into the
382 * reachable set (ie. gc_refs > 0). Next, move everything
383 * reachable from objects in the reachable set. */
384 gc_list_init(&reachable);
385 move_roots(young, &reachable);
386 move_root_reachable(&reachable);
387
388 /* move unreachable objects to a temporary list, new objects can be
389 * allocated after this point */
390 gc_list_init(&unreachable);
391 gc_list_move(young, &unreachable);
392
393 /* move reachable objects to next generation */
394 gc_list_merge(&reachable, old);
395
396 /* Move objects reachable from finalizers, we can't safely delete
397 * them. Python programmers should take care not to create such
398 * things. For Python finalizers means instance objects with
399 * __del__ methods. */
400 gc_list_init(&finalizers);
401 move_finalizers(&unreachable, &finalizers);
402 move_finalizer_reachable(&finalizers);
403
404 /* Collect statistics on collectable objects found and print
405 * debugging information. */
406 for (gc = unreachable.gc_next; gc != &unreachable;
407 gc = gc->gc_next) {
408 m++;
Jeremy Hylton06257772000-08-31 15:10:24 +0000409 if (debug & DEBUG_COLLECTABLE) {
410 debug_cycle("collectable", PyObject_FROM_GC(gc));
Jeremy Hyltonc5007aa2000-06-30 05:02:53 +0000411 }
412 }
413 /* call tp_clear on objects in the collectable set. This will cause
414 * the reference cycles to be broken. It may also cause some objects in
415 * finalizers to be freed */
416 delete_garbage(&unreachable, old);
417
418 /* Collect statistics on uncollectable objects found and print
419 * debugging information. */
420 for (gc = finalizers.gc_next; gc != &finalizers;
421 gc = gc->gc_next) {
422 n++;
Jeremy Hylton06257772000-08-31 15:10:24 +0000423 if (debug & DEBUG_UNCOLLECTABLE) {
424 debug_cycle("uncollectable", PyObject_FROM_GC(gc));
Jeremy Hyltonc5007aa2000-06-30 05:02:53 +0000425 }
426 }
Jeremy Hylton06257772000-08-31 15:10:24 +0000427 if (debug & DEBUG_STATS) {
Jeremy Hyltonc5007aa2000-06-30 05:02:53 +0000428 if (m == 0 && n == 0) {
Jeremy Hylton06257772000-08-31 15:10:24 +0000429 PySys_WriteStderr("gc: done.\n");
Neil Schemenauer544de1e2000-09-22 15:22:38 +0000430 }
431 else {
Jeremy Hylton06257772000-08-31 15:10:24 +0000432 PySys_WriteStderr(
433 "gc: done, %ld unreachable, %ld uncollectable.\n",
434 n+m, n);
Jeremy Hyltonc5007aa2000-06-30 05:02:53 +0000435 }
436 }
437
438 /* Append instances in the uncollectable set to a Python
439 * reachable list of garbage. The programmer has to deal with
440 * this if they insist on creating this type of structure. */
441 handle_finalizers(&finalizers, old);
442
Jeremy Hyltonb709df32000-09-01 02:47:25 +0000443 if (PyErr_Occurred()) {
Neil Schemenauer544de1e2000-09-22 15:22:38 +0000444 if (gc_str == NULL) {
445 gc_str = PyString_FromString("garbage collection");
446 }
Jeremy Hyltonb709df32000-09-01 02:47:25 +0000447 PyErr_WriteUnraisable(gc_str);
448 Py_FatalError("unexpected exception during garbage collection");
449 }
Jeremy Hyltonc5007aa2000-06-30 05:02:53 +0000450 allocated = 0;
Jeremy Hyltonc5007aa2000-06-30 05:02:53 +0000451 return n+m;
452}
453
454static long
455collect_generations(void)
456{
457 static long collections0 = 0;
458 static long collections1 = 0;
Vladimir Marangozovb16714b2000-07-10 05:37:39 +0000459 long n = 0;
Jeremy Hyltonc5007aa2000-06-30 05:02:53 +0000460
461
462 if (collections1 > threshold2) {
463 generation = 2;
464 gc_list_merge(&generation0, &generation2);
465 gc_list_merge(&generation1, &generation2);
466 if (generation2.gc_next != &generation2) {
467 n = collect(&generation2, &generation2);
468 }
469 collections1 = 0;
Neil Schemenauer544de1e2000-09-22 15:22:38 +0000470 }
471 else if (collections0 > threshold1) {
Jeremy Hyltonc5007aa2000-06-30 05:02:53 +0000472 generation = 1;
473 collections1++;
474 gc_list_merge(&generation0, &generation1);
475 if (generation1.gc_next != &generation1) {
476 n = collect(&generation1, &generation2);
477 }
478 collections0 = 0;
Neil Schemenauer544de1e2000-09-22 15:22:38 +0000479 }
480 else {
Jeremy Hyltonc5007aa2000-06-30 05:02:53 +0000481 generation = 0;
482 collections0++;
483 if (generation0.gc_next != &generation0) {
484 n = collect(&generation0, &generation1);
485 }
486 }
487 return n;
488}
489
490void
491_PyGC_Insert(PyObject *op)
492{
493 /* collection lock since collecting may cause allocations */
494 static int collecting = 0;
495
496#ifdef Py_DEBUG
497 if (!PyObject_IS_GC(op)) {
498 abort();
499 }
500#endif
Neil Schemenauer97d723b2000-10-04 16:25:07 +0000501 if (allocated > threshold0 &&
502 enabled &&
503 threshold0 &&
504 !collecting &&
505 !PyErr_Occurred()) {
Jeremy Hyltonc5007aa2000-06-30 05:02:53 +0000506 collecting++;
507 collect_generations();
508 collecting--;
509 }
510 allocated++;
511 gc_list_append(PyObject_AS_GC(op), &generation0);
512}
513
514void
515_PyGC_Remove(PyObject *op)
516{
517 PyGC_Head *g = PyObject_AS_GC(op);
518#ifdef Py_DEBUG
519 if (!PyObject_IS_GC(op)) {
520 abort();
521 }
522#endif
523 gc_list_remove(g);
524 if (allocated > 0) {
525 allocated--;
526 }
527}
528
Vladimir Marangozovf9d20c32000-08-06 22:45:31 +0000529static char gc_enable__doc__[] =
530"enable() -> None\n"
531"\n"
532"Enable automatic garbage collection.\n"
533;
Jeremy Hyltonc5007aa2000-06-30 05:02:53 +0000534
Vladimir Marangozovf9d20c32000-08-06 22:45:31 +0000535static PyObject *
536gc_enable(PyObject *self, PyObject *args)
537{
538
539 if (!PyArg_ParseTuple(args, ":enable")) /* check no args */
540 return NULL;
541
542 enabled = 1;
543
544 Py_INCREF(Py_None);
545 return Py_None;
546}
547
548static char gc_disable__doc__[] =
549"disable() -> None\n"
550"\n"
551"Disable automatic garbage collection.\n"
552;
553
554static PyObject *
555gc_disable(PyObject *self, PyObject *args)
556{
557
558 if (!PyArg_ParseTuple(args, ":disable")) /* check no args */
559 return NULL;
560
561 enabled = 0;
562
563 Py_INCREF(Py_None);
564 return Py_None;
565}
566
567static char gc_isenabled__doc__[] =
568"isenabled() -> status\n"
569"\n"
570"Returns true if automatic garbage collection is enabled.\n"
571;
572
573static PyObject *
574gc_isenabled(PyObject *self, PyObject *args)
575{
576
577 if (!PyArg_ParseTuple(args, ":isenabled")) /* check no args */
578 return NULL;
579
580 return Py_BuildValue("i", enabled);
581}
582
583static char gc_collect__doc__[] =
Jeremy Hyltonc5007aa2000-06-30 05:02:53 +0000584"collect() -> n\n"
585"\n"
586"Run a full collection. The number of unreachable objects is returned.\n"
587;
588
589static PyObject *
Vladimir Marangozovf9d20c32000-08-06 22:45:31 +0000590gc_collect(PyObject *self, PyObject *args)
Jeremy Hyltonc5007aa2000-06-30 05:02:53 +0000591{
592 long n;
593
Fred Drakecc1be242000-07-12 04:42:23 +0000594 if (!PyArg_ParseTuple(args, ":collect")) /* check no args */
Jeremy Hyltonc5007aa2000-06-30 05:02:53 +0000595 return NULL;
596
597 generation = 2;
598 gc_list_merge(&generation0, &generation2);
599 gc_list_merge(&generation1, &generation2);
600 n = collect(&generation2, &generation2);
601
Neil Schemenauer7760cff2000-09-22 22:35:36 +0000602 return Py_BuildValue("l", n);
Jeremy Hyltonc5007aa2000-06-30 05:02:53 +0000603}
604
Vladimir Marangozovf9d20c32000-08-06 22:45:31 +0000605static char gc_set_debug__doc__[] =
Jeremy Hyltonc5007aa2000-06-30 05:02:53 +0000606"set_debug(flags) -> None\n"
607"\n"
608"Set the garbage collection debugging flags. Debugging information is\n"
609"written to sys.stderr.\n"
610"\n"
611"flags is an integer and can have the following bits turned on:\n"
612"\n"
613" DEBUG_STATS - Print statistics during collection.\n"
614" DEBUG_COLLECTABLE - Print collectable objects found.\n"
615" DEBUG_UNCOLLECTABLE - Print unreachable but uncollectable objects found.\n"
616" DEBUG_INSTANCES - Print instance objects.\n"
617" DEBUG_OBJECTS - Print objects other than instances.\n"
Neil Schemenauer544de1e2000-09-22 15:22:38 +0000618" DEBUG_SAVEALL - Save objects to gc.garbage rather than freeing them.\n"
Jeremy Hyltonc5007aa2000-06-30 05:02:53 +0000619" DEBUG_LEAK - Debug leaking programs (everything but STATS).\n"
620;
621
622static PyObject *
Vladimir Marangozovf9d20c32000-08-06 22:45:31 +0000623gc_set_debug(PyObject *self, PyObject *args)
Jeremy Hyltonc5007aa2000-06-30 05:02:53 +0000624{
Neil Schemenauer7760cff2000-09-22 22:35:36 +0000625 if (!PyArg_ParseTuple(args, "i:set_debug", &debug))
Jeremy Hyltonc5007aa2000-06-30 05:02:53 +0000626 return NULL;
627
628 Py_INCREF(Py_None);
629 return Py_None;
630}
631
Vladimir Marangozovf9d20c32000-08-06 22:45:31 +0000632static char gc_get_debug__doc__[] =
Jeremy Hyltonc5007aa2000-06-30 05:02:53 +0000633"get_debug() -> flags\n"
634"\n"
635"Get the garbage collection debugging flags.\n"
636;
637
638static PyObject *
Vladimir Marangozovf9d20c32000-08-06 22:45:31 +0000639gc_get_debug(PyObject *self, PyObject *args)
Jeremy Hyltonc5007aa2000-06-30 05:02:53 +0000640{
Fred Drakecc1be242000-07-12 04:42:23 +0000641 if (!PyArg_ParseTuple(args, ":get_debug")) /* no args */
Jeremy Hyltonc5007aa2000-06-30 05:02:53 +0000642 return NULL;
643
644 return Py_BuildValue("i", debug);
645}
646
Vladimir Marangozovf9d20c32000-08-06 22:45:31 +0000647static char gc_set_thresh__doc__[] =
Jeremy Hyltonc5007aa2000-06-30 05:02:53 +0000648"set_threshold(threshold0, [threhold1, threshold2]) -> None\n"
649"\n"
650"Sets the collection thresholds. Setting threshold0 to zero disables\n"
651"collection.\n"
652;
653
654static PyObject *
Vladimir Marangozovf9d20c32000-08-06 22:45:31 +0000655gc_set_thresh(PyObject *self, PyObject *args)
Jeremy Hyltonc5007aa2000-06-30 05:02:53 +0000656{
Fred Drakecc1be242000-07-12 04:42:23 +0000657 if (!PyArg_ParseTuple(args, "i|ii:set_threshold", &threshold0,
Jeremy Hyltonc5007aa2000-06-30 05:02:53 +0000658 &threshold1, &threshold2))
659 return NULL;
660
661 Py_INCREF(Py_None);
662 return Py_None;
663}
664
Vladimir Marangozovf9d20c32000-08-06 22:45:31 +0000665static char gc_get_thresh__doc__[] =
Jeremy Hyltonc5007aa2000-06-30 05:02:53 +0000666"get_threshold() -> (threshold0, threshold1, threshold2)\n"
667"\n"
668"Return the current collection thresholds\n"
669;
670
671static PyObject *
Vladimir Marangozovf9d20c32000-08-06 22:45:31 +0000672gc_get_thresh(PyObject *self, PyObject *args)
Jeremy Hyltonc5007aa2000-06-30 05:02:53 +0000673{
Fred Drakecc1be242000-07-12 04:42:23 +0000674 if (!PyArg_ParseTuple(args, ":get_threshold")) /* no args */
Jeremy Hyltonc5007aa2000-06-30 05:02:53 +0000675 return NULL;
676
677 return Py_BuildValue("(iii)", threshold0, threshold1, threshold2);
678}
679
680
681static char gc__doc__ [] =
682"This module provides access to the garbage collector for reference cycles.\n"
683"\n"
Vladimir Marangozovf9d20c32000-08-06 22:45:31 +0000684"enable() -- Enable automatic garbage collection.\n"
685"disable() -- Disable automatic garbage collection.\n"
686"isenabled() -- Returns true if automatic collection is enabled.\n"
Jeremy Hyltonc5007aa2000-06-30 05:02:53 +0000687"collect() -- Do a full collection right now.\n"
688"set_debug() -- Set debugging flags.\n"
689"get_debug() -- Get debugging flags.\n"
690"set_threshold() -- Set the collection thresholds.\n"
691"get_threshold() -- Return the current the collection thresholds.\n"
692;
693
694static PyMethodDef GcMethods[] = {
Neil Schemenauer544de1e2000-09-22 15:22:38 +0000695 {"enable", gc_enable, METH_VARARGS, gc_enable__doc__},
696 {"disable", gc_disable, METH_VARARGS, gc_disable__doc__},
Vladimir Marangozovf9d20c32000-08-06 22:45:31 +0000697 {"isenabled", gc_isenabled, METH_VARARGS, gc_isenabled__doc__},
698 {"set_debug", gc_set_debug, METH_VARARGS, gc_set_debug__doc__},
699 {"get_debug", gc_get_debug, METH_VARARGS, gc_get_debug__doc__},
700 {"set_threshold", gc_set_thresh, METH_VARARGS, gc_set_thresh__doc__},
701 {"get_threshold", gc_get_thresh, METH_VARARGS, gc_get_thresh__doc__},
Neil Schemenauer544de1e2000-09-22 15:22:38 +0000702 {"collect", gc_collect, METH_VARARGS, gc_collect__doc__},
Jeremy Hyltonc5007aa2000-06-30 05:02:53 +0000703 {NULL, NULL} /* Sentinel */
704};
705
706void
707initgc(void)
708{
709 PyObject *m;
710 PyObject *d;
711
712 m = Py_InitModule4("gc",
713 GcMethods,
714 gc__doc__,
715 NULL,
716 PYTHON_API_VERSION);
717 d = PyModule_GetDict(m);
718 if (garbage == NULL) {
719 garbage = PyList_New(0);
720 }
Jeremy Hyltonc5007aa2000-06-30 05:02:53 +0000721 PyDict_SetItemString(d, "garbage", garbage);
722 PyDict_SetItemString(d, "DEBUG_STATS",
723 PyInt_FromLong(DEBUG_STATS));
724 PyDict_SetItemString(d, "DEBUG_COLLECTABLE",
725 PyInt_FromLong(DEBUG_COLLECTABLE));
726 PyDict_SetItemString(d, "DEBUG_UNCOLLECTABLE",
727 PyInt_FromLong(DEBUG_UNCOLLECTABLE));
728 PyDict_SetItemString(d, "DEBUG_INSTANCES",
729 PyInt_FromLong(DEBUG_INSTANCES));
730 PyDict_SetItemString(d, "DEBUG_OBJECTS",
731 PyInt_FromLong(DEBUG_OBJECTS));
Neil Schemenauer544de1e2000-09-22 15:22:38 +0000732 PyDict_SetItemString(d, "DEBUG_SAVEALL",
733 PyInt_FromLong(DEBUG_SAVEALL));
Jeremy Hyltonc5007aa2000-06-30 05:02:53 +0000734 PyDict_SetItemString(d, "DEBUG_LEAK",
735 PyInt_FromLong(DEBUG_LEAK));
736}
737
738#endif /* WITH_CYCLE_GC */