blob: cf884814d2309220e82a0041f66a8eb04d2efd0a [file] [log] [blame]
Jeremy Hyltonc5007aa2000-06-30 05:02:53 +00001/*
2
3 Reference Cycle Garbage Collection
4 ==================================
5
6 Neil Schemenauer <nascheme@enme.ucalgary.ca>
7
8 Based on a post on the python-dev list. Ideas from Guido van Rossum,
9 Eric Tiedemann, and various others.
10
11 http://www.enme.calgary.ca/~nascheme/python/gc.html
12 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
19 TODO:
20 use a different interface for set_debug() (keywords)?
21 tune parameters
22
23*/
24
25
26#include "Python.h"
27
28#ifdef WITH_CYCLE_GC
29
30/* magic gc_refs value */
31#define GC_MOVED -1
32
33/*** Global GC state ***/
34
35/* linked lists of container objects */
36static PyGC_Head generation0 = {&generation0, &generation0, 0};
37static PyGC_Head generation1 = {&generation1, &generation1, 0};
38static PyGC_Head generation2 = {&generation2, &generation2, 0};
39static int generation = 0; /* current generation being collected */
40
41/* collection frequencies, XXX tune these */
Vladimir Marangozovf9d20c32000-08-06 22:45:31 +000042static int enabled = 1; /* automatic collection enabled? */
Jeremy Hylton3263dc2b2000-09-05 15:44:50 +000043static int threshold0 = 700; /* net new containers before collection */
Jeremy Hyltonc5007aa2000-06-30 05:02:53 +000044static int threshold1 = 10; /* generation0 collections before collecting 1 */
45static int threshold2 = 10; /* generation1 collections before collecting 2 */
46
47/* net new objects allocated since last collection */
48static int allocated;
49
50/* set for debugging information */
51#define DEBUG_STATS (1<<0) /* print collection statistics */
52#define DEBUG_COLLECTABLE (1<<1) /* print collectable objects */
53#define DEBUG_UNCOLLECTABLE (1<<2) /* print uncollectable objects */
54#define DEBUG_INSTANCES (1<<3) /* print instances */
55#define DEBUG_OBJECTS (1<<4) /* print other objects */
Neil Schemenauer544de1e2000-09-22 15:22:38 +000056#define DEBUG_SAVEALL (1<<5) /* save all garbage in gc.garbage */
Jeremy Hyltonc5007aa2000-06-30 05:02:53 +000057#define DEBUG_LEAK DEBUG_COLLECTABLE | \
58 DEBUG_UNCOLLECTABLE | \
59 DEBUG_INSTANCES | \
Neil Schemenauer544de1e2000-09-22 15:22:38 +000060 DEBUG_OBJECTS | \
61 DEBUG_SAVEALL
Jeremy Hyltonb709df32000-09-01 02:47:25 +000062static int debug;
Jeremy Hyltonc5007aa2000-06-30 05:02:53 +000063
64/* list of uncollectable objects */
65static PyObject *garbage;
66
Jeremy Hyltonb709df32000-09-01 02:47:25 +000067/* Python string to use if unhandled exception occurs */
68static PyObject *gc_str;
Jeremy Hyltonc5007aa2000-06-30 05:02:53 +000069
70/*** list functions ***/
71
72static void
73gc_list_init(PyGC_Head *list)
74{
75 list->gc_prev = list;
76 list->gc_next = list;
77}
78
79static void
80gc_list_append(PyGC_Head *node, PyGC_Head *list)
81{
82 node->gc_next = list;
83 node->gc_prev = list->gc_prev;
84 node->gc_prev->gc_next = node;
85 list->gc_prev = node;
86}
87
88static void
89gc_list_remove(PyGC_Head *node)
90{
91 node->gc_prev->gc_next = node->gc_next;
92 node->gc_next->gc_prev = node->gc_prev;
93#ifdef Py_DEBUG
94 node->gc_prev = NULL;
95 node->gc_next = NULL;
96#endif
97}
98
99static void
100gc_list_move(PyGC_Head *from, PyGC_Head *to)
101{
102 if (from->gc_next == from) {
103 /* empty from list */
104 gc_list_init(to);
Neil Schemenauer544de1e2000-09-22 15:22:38 +0000105 }
106 else {
Jeremy Hyltonc5007aa2000-06-30 05:02:53 +0000107 to->gc_next = from->gc_next;
108 to->gc_next->gc_prev = to;
109 to->gc_prev = from->gc_prev;
110 to->gc_prev->gc_next = to;
111 }
112 gc_list_init(from);
113}
114
115/* append a list onto another list, from becomes an empty list */
116static void
117gc_list_merge(PyGC_Head *from, PyGC_Head *to)
118{
119 PyGC_Head *tail;
120 if (from->gc_next != from) {
121 tail = to->gc_prev;
122 tail->gc_next = from->gc_next;
123 tail->gc_next->gc_prev = tail;
124 to->gc_prev = from->gc_prev;
125 to->gc_prev->gc_next = to;
126 }
127 gc_list_init(from);
128}
129
130static long
131gc_list_size(PyGC_Head *list)
132{
133 PyGC_Head *gc;
134 long n = 0;
135 for (gc = list->gc_next; gc != list; gc = gc->gc_next) {
136 n++;
137 }
138 return n;
139}
140
141/*** end of list stuff ***/
142
143
144/* Set all gc_refs = ob_refcnt */
145static void
146update_refs(PyGC_Head *containers)
147{
148 PyGC_Head *gc = containers->gc_next;
149 for (; gc != containers; gc=gc->gc_next) {
150 gc->gc_refs = PyObject_FROM_GC(gc)->ob_refcnt;
151 }
152}
153
154static int
155visit_decref(PyObject *op, void *data)
156{
157 if (op && PyObject_IS_GC(op)) {
158 PyObject_AS_GC(op)->gc_refs--;
159 }
160 return 0;
161}
162
163/* Subtract internal references from gc_refs */
164static void
165subtract_refs(PyGC_Head *containers)
166{
167 traverseproc traverse;
168 PyGC_Head *gc = containers->gc_next;
169 for (; gc != containers; gc=gc->gc_next) {
170 traverse = PyObject_FROM_GC(gc)->ob_type->tp_traverse;
171 (void) traverse(PyObject_FROM_GC(gc),
172 (visitproc)visit_decref,
173 NULL);
174 }
175}
176
177/* Append objects with gc_refs > 0 to roots list */
178static void
179move_roots(PyGC_Head *containers, PyGC_Head *roots)
180{
181 PyGC_Head *next;
182 PyGC_Head *gc = containers->gc_next;
183 while (gc != containers) {
184 next = gc->gc_next;
185 if (gc->gc_refs > 0) {
186 gc_list_remove(gc);
187 gc_list_append(gc, roots);
188 gc->gc_refs = GC_MOVED;
189 }
190 gc = next;
191 }
192}
193
194static int
195visit_reachable(PyObject *op, PyGC_Head *roots)
196{
197 if (PyObject_IS_GC(op)) {
198 PyGC_Head *gc = PyObject_AS_GC(op);
199 if (gc && gc->gc_refs != GC_MOVED) {
200 gc_list_remove(gc);
201 gc_list_append(gc, roots);
202 gc->gc_refs = GC_MOVED;
203 }
204 }
205 return 0;
206}
207
208/* Move objects referenced from reachable to reachable set. */
209static void
210move_root_reachable(PyGC_Head *reachable)
211{
212 traverseproc traverse;
213 PyGC_Head *gc = reachable->gc_next;
214 for (; gc != reachable; gc=gc->gc_next) {
215 /* careful, reachable list is growing here */
216 PyObject *op = PyObject_FROM_GC(gc);
217 traverse = op->ob_type->tp_traverse;
218 (void) traverse(op,
219 (visitproc)visit_reachable,
220 (void *)reachable);
221 }
222}
223
224/* move all objects with finalizers (instances with __del__) */
225static void
226move_finalizers(PyGC_Head *unreachable, PyGC_Head *finalizers)
227{
228 PyGC_Head *next;
229 PyGC_Head *gc = unreachable->gc_next;
Jeremy Hylton06257772000-08-31 15:10:24 +0000230 static PyObject *delstr = NULL;
Jeremy Hyltonc5007aa2000-06-30 05:02:53 +0000231 if (delstr == NULL) {
232 delstr = PyString_InternFromString("__del__");
Jeremy Hylton06257772000-08-31 15:10:24 +0000233 if (delstr == NULL)
234 Py_FatalError("PyGC: can't initialize __del__ string");
Jeremy Hyltonc5007aa2000-06-30 05:02:53 +0000235 }
236 for (; gc != unreachable; gc=next) {
237 PyObject *op = PyObject_FROM_GC(gc);
238 next = gc->gc_next;
239 if (PyInstance_Check(op) && PyObject_HasAttr(op, delstr)) {
240 gc_list_remove(gc);
241 gc_list_append(gc, finalizers);
242 }
243 }
244}
245
246
247/* called by tp_traverse */
248static int
249visit_finalizer_reachable(PyObject *op, PyGC_Head *finalizers)
250{
251 if (PyObject_IS_GC(op)) {
252 PyGC_Head *gc = PyObject_AS_GC(op);
253 if (gc && gc->gc_refs != GC_MOVED) {
254 gc_list_remove(gc);
255 gc_list_append(gc, finalizers);
256 gc->gc_refs = GC_MOVED;
257 }
258 }
259 return 0;
260}
261
262/* Move objects referenced from roots to roots */
263static void
264move_finalizer_reachable(PyGC_Head *finalizers)
265{
266 traverseproc traverse;
267 PyGC_Head *gc = finalizers->gc_next;
268 for (; gc != finalizers; gc=gc->gc_next) {
269 /* careful, finalizers list is growing here */
270 traverse = PyObject_FROM_GC(gc)->ob_type->tp_traverse;
271 (void) traverse(PyObject_FROM_GC(gc),
272 (visitproc)visit_finalizer_reachable,
273 (void *)finalizers);
274 }
275}
276
277static void
Jeremy Hylton06257772000-08-31 15:10:24 +0000278debug_instance(char *msg, PyInstanceObject *inst)
Jeremy Hyltonc5007aa2000-06-30 05:02:53 +0000279{
Jeremy Hyltonc5007aa2000-06-30 05:02:53 +0000280 char *cname;
281 /* be careful not to create new dictionaries */
282 PyObject *classname = inst->in_class->cl_name;
283 if (classname != NULL && PyString_Check(classname))
284 cname = PyString_AsString(classname);
285 else
286 cname = "?";
Jeremy Hylton06257772000-08-31 15:10:24 +0000287 PySys_WriteStderr("gc: %.100s <%.100s instance at %p>\n",
288 msg, cname, inst);
Jeremy Hyltonc5007aa2000-06-30 05:02:53 +0000289}
290
291static void
Jeremy Hylton06257772000-08-31 15:10:24 +0000292debug_cycle(char *msg, PyObject *op)
Jeremy Hyltonc5007aa2000-06-30 05:02:53 +0000293{
294 if ((debug & DEBUG_INSTANCES) && PyInstance_Check(op)) {
Jeremy Hylton06257772000-08-31 15:10:24 +0000295 debug_instance(msg, (PyInstanceObject *)op);
Neil Schemenauer544de1e2000-09-22 15:22:38 +0000296 }
297 else if (debug & DEBUG_OBJECTS) {
Jeremy Hylton06257772000-08-31 15:10:24 +0000298 PySys_WriteStderr("gc: %.100s <%.100s %p>\n",
299 msg, op->ob_type->tp_name, op);
Jeremy Hyltonc5007aa2000-06-30 05:02:53 +0000300 }
301}
302
303/* Handle uncollectable garbage (cycles with finalizers). */
304static void
305handle_finalizers(PyGC_Head *finalizers, PyGC_Head *old)
306{
307 PyGC_Head *gc;
308 if (garbage == NULL) {
309 garbage = PyList_New(0);
310 }
311 for (gc = finalizers->gc_next; gc != finalizers;
312 gc = finalizers->gc_next) {
313 PyObject *op = PyObject_FROM_GC(gc);
Neil Schemenauer544de1e2000-09-22 15:22:38 +0000314 if ((debug & DEBUG_SAVEALL) || PyInstance_Check(op)) {
315 /* If SAVEALL is not set then just append
316 * instances to the list of garbage. We assume
317 * that all objects in the finalizers list are
318 * reachable from instances. */
Jeremy Hyltonc5007aa2000-06-30 05:02:53 +0000319 PyList_Append(garbage, op);
320 }
Neil Schemenauer544de1e2000-09-22 15:22:38 +0000321 /* object is now reachable again */
Jeremy Hyltonc5007aa2000-06-30 05:02:53 +0000322 gc_list_remove(gc);
323 gc_list_append(gc, old);
324 }
325}
326
Neil Schemenauer544de1e2000-09-22 15:22:38 +0000327/* Break reference cycles by clearing the containers involved. This is
Jeremy Hyltonc5007aa2000-06-30 05:02:53 +0000328 * tricky business as the lists can be changing and we don't know which
329 * objects may be freed. It is possible I screwed something up here. */
330static void
331delete_garbage(PyGC_Head *unreachable, PyGC_Head *old)
332{
333 inquiry clear;
334
335 while (unreachable->gc_next != unreachable) {
336 PyGC_Head *gc = unreachable->gc_next;
337 PyObject *op = PyObject_FROM_GC(gc);
Neil Schemenauer544de1e2000-09-22 15:22:38 +0000338 if (debug & DEBUG_SAVEALL) {
339 PyList_Append(garbage, op);
Jeremy Hyltonc5007aa2000-06-30 05:02:53 +0000340 }
Neil Schemenauer544de1e2000-09-22 15:22:38 +0000341 else {
342 if ((clear = op->ob_type->tp_clear) != NULL) {
343 Py_INCREF(op);
344 clear((PyObject *)op);
345 Py_DECREF(op);
346 }
347 }
Jeremy Hyltonc5007aa2000-06-30 05:02:53 +0000348 if (unreachable->gc_next == gc) {
Neil Schemenauer544de1e2000-09-22 15:22:38 +0000349 /* object is still alive, move it, it may die later */
Jeremy Hyltonc5007aa2000-06-30 05:02:53 +0000350 gc_list_remove(gc);
351 gc_list_append(gc, old);
352 }
353 }
354}
355
356/* This is the main function. Read this to understand how the
357 * collection process works. */
358static long
359collect(PyGC_Head *young, PyGC_Head *old)
360{
361 long n = 0;
362 long m = 0;
363 PyGC_Head reachable;
364 PyGC_Head unreachable;
365 PyGC_Head finalizers;
366 PyGC_Head *gc;
Jeremy Hyltonc5007aa2000-06-30 05:02:53 +0000367
Jeremy Hyltonc5007aa2000-06-30 05:02:53 +0000368 if (debug & DEBUG_STATS) {
Jeremy Hylton06257772000-08-31 15:10:24 +0000369 PySys_WriteStderr(
370 "gc: collecting generation %d...\n"
371 "gc: objects in each generation: %ld %ld %ld\n",
372 generation,
Jeremy Hyltonc5007aa2000-06-30 05:02:53 +0000373 gc_list_size(&generation0),
374 gc_list_size(&generation1),
375 gc_list_size(&generation2));
Jeremy Hyltonc5007aa2000-06-30 05:02:53 +0000376 }
377
378 /* Using ob_refcnt and gc_refs, calculate which objects in the
379 * container set are reachable from outside the set (ie. have a
380 * refcount greater than 0 when all the references within the
381 * set are taken into account */
382 update_refs(young);
383 subtract_refs(young);
384
385 /* Move everything reachable from outside the set into the
386 * reachable set (ie. gc_refs > 0). Next, move everything
387 * reachable from objects in the reachable set. */
388 gc_list_init(&reachable);
389 move_roots(young, &reachable);
390 move_root_reachable(&reachable);
391
392 /* move unreachable objects to a temporary list, new objects can be
393 * allocated after this point */
394 gc_list_init(&unreachable);
395 gc_list_move(young, &unreachable);
396
397 /* move reachable objects to next generation */
398 gc_list_merge(&reachable, old);
399
400 /* Move objects reachable from finalizers, we can't safely delete
401 * them. Python programmers should take care not to create such
402 * things. For Python finalizers means instance objects with
403 * __del__ methods. */
404 gc_list_init(&finalizers);
405 move_finalizers(&unreachable, &finalizers);
406 move_finalizer_reachable(&finalizers);
407
408 /* Collect statistics on collectable objects found and print
409 * debugging information. */
410 for (gc = unreachable.gc_next; gc != &unreachable;
411 gc = gc->gc_next) {
412 m++;
Jeremy Hylton06257772000-08-31 15:10:24 +0000413 if (debug & DEBUG_COLLECTABLE) {
414 debug_cycle("collectable", PyObject_FROM_GC(gc));
Jeremy Hyltonc5007aa2000-06-30 05:02:53 +0000415 }
416 }
417 /* call tp_clear on objects in the collectable set. This will cause
418 * the reference cycles to be broken. It may also cause some objects in
419 * finalizers to be freed */
420 delete_garbage(&unreachable, old);
421
422 /* Collect statistics on uncollectable objects found and print
423 * debugging information. */
424 for (gc = finalizers.gc_next; gc != &finalizers;
425 gc = gc->gc_next) {
426 n++;
Jeremy Hylton06257772000-08-31 15:10:24 +0000427 if (debug & DEBUG_UNCOLLECTABLE) {
428 debug_cycle("uncollectable", PyObject_FROM_GC(gc));
Jeremy Hyltonc5007aa2000-06-30 05:02:53 +0000429 }
430 }
Jeremy Hylton06257772000-08-31 15:10:24 +0000431 if (debug & DEBUG_STATS) {
Jeremy Hyltonc5007aa2000-06-30 05:02:53 +0000432 if (m == 0 && n == 0) {
Jeremy Hylton06257772000-08-31 15:10:24 +0000433 PySys_WriteStderr("gc: done.\n");
Neil Schemenauer544de1e2000-09-22 15:22:38 +0000434 }
435 else {
Jeremy Hylton06257772000-08-31 15:10:24 +0000436 PySys_WriteStderr(
437 "gc: done, %ld unreachable, %ld uncollectable.\n",
438 n+m, n);
Jeremy Hyltonc5007aa2000-06-30 05:02:53 +0000439 }
440 }
441
442 /* Append instances in the uncollectable set to a Python
443 * reachable list of garbage. The programmer has to deal with
444 * this if they insist on creating this type of structure. */
445 handle_finalizers(&finalizers, old);
446
Jeremy Hyltonb709df32000-09-01 02:47:25 +0000447 if (PyErr_Occurred()) {
Neil Schemenauer544de1e2000-09-22 15:22:38 +0000448 if (gc_str == NULL) {
449 gc_str = PyString_FromString("garbage collection");
450 }
Jeremy Hyltonb709df32000-09-01 02:47:25 +0000451 PyErr_WriteUnraisable(gc_str);
452 Py_FatalError("unexpected exception during garbage collection");
453 }
Jeremy Hyltonc5007aa2000-06-30 05:02:53 +0000454 allocated = 0;
Jeremy Hyltonc5007aa2000-06-30 05:02:53 +0000455 return n+m;
456}
457
458static long
459collect_generations(void)
460{
461 static long collections0 = 0;
462 static long collections1 = 0;
Vladimir Marangozovb16714b2000-07-10 05:37:39 +0000463 long n = 0;
Jeremy Hyltonc5007aa2000-06-30 05:02:53 +0000464
465
466 if (collections1 > threshold2) {
467 generation = 2;
468 gc_list_merge(&generation0, &generation2);
469 gc_list_merge(&generation1, &generation2);
470 if (generation2.gc_next != &generation2) {
471 n = collect(&generation2, &generation2);
472 }
473 collections1 = 0;
Neil Schemenauer544de1e2000-09-22 15:22:38 +0000474 }
475 else if (collections0 > threshold1) {
Jeremy Hyltonc5007aa2000-06-30 05:02:53 +0000476 generation = 1;
477 collections1++;
478 gc_list_merge(&generation0, &generation1);
479 if (generation1.gc_next != &generation1) {
480 n = collect(&generation1, &generation2);
481 }
482 collections0 = 0;
Neil Schemenauer544de1e2000-09-22 15:22:38 +0000483 }
484 else {
Jeremy Hyltonc5007aa2000-06-30 05:02:53 +0000485 generation = 0;
486 collections0++;
487 if (generation0.gc_next != &generation0) {
488 n = collect(&generation0, &generation1);
489 }
490 }
491 return n;
492}
493
494void
495_PyGC_Insert(PyObject *op)
496{
497 /* collection lock since collecting may cause allocations */
498 static int collecting = 0;
499
500#ifdef Py_DEBUG
501 if (!PyObject_IS_GC(op)) {
502 abort();
503 }
504#endif
Vladimir Marangozovf9d20c32000-08-06 22:45:31 +0000505 if (allocated > threshold0 && enabled && threshold0 && !collecting) {
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 */