blob: 4d55a08e88d17b445b2c7bc64cc8115df27f75da [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 */
42static int threshold0 = 100; /* net new containers before collection */
43static int threshold1 = 10; /* generation0 collections before collecting 1 */
44static int threshold2 = 10; /* generation1 collections before collecting 2 */
45
46/* net new objects allocated since last collection */
47static int allocated;
48
49/* set for debugging information */
50#define DEBUG_STATS (1<<0) /* print collection statistics */
51#define DEBUG_COLLECTABLE (1<<1) /* print collectable objects */
52#define DEBUG_UNCOLLECTABLE (1<<2) /* print uncollectable objects */
53#define DEBUG_INSTANCES (1<<3) /* print instances */
54#define DEBUG_OBJECTS (1<<4) /* print other objects */
55#define DEBUG_LEAK DEBUG_COLLECTABLE | \
56 DEBUG_UNCOLLECTABLE | \
57 DEBUG_INSTANCES | \
58 DEBUG_OBJECTS
59static int debug;
60
61/* list of uncollectable objects */
62static PyObject *garbage;
63
64
65/*** list functions ***/
66
67static void
68gc_list_init(PyGC_Head *list)
69{
70 list->gc_prev = list;
71 list->gc_next = list;
72}
73
74static void
75gc_list_append(PyGC_Head *node, PyGC_Head *list)
76{
77 node->gc_next = list;
78 node->gc_prev = list->gc_prev;
79 node->gc_prev->gc_next = node;
80 list->gc_prev = node;
81}
82
83static void
84gc_list_remove(PyGC_Head *node)
85{
86 node->gc_prev->gc_next = node->gc_next;
87 node->gc_next->gc_prev = node->gc_prev;
88#ifdef Py_DEBUG
89 node->gc_prev = NULL;
90 node->gc_next = NULL;
91#endif
92}
93
94static void
95gc_list_move(PyGC_Head *from, PyGC_Head *to)
96{
97 if (from->gc_next == from) {
98 /* empty from list */
99 gc_list_init(to);
100 } else {
101 to->gc_next = from->gc_next;
102 to->gc_next->gc_prev = to;
103 to->gc_prev = from->gc_prev;
104 to->gc_prev->gc_next = to;
105 }
106 gc_list_init(from);
107}
108
109/* append a list onto another list, from becomes an empty list */
110static void
111gc_list_merge(PyGC_Head *from, PyGC_Head *to)
112{
113 PyGC_Head *tail;
114 if (from->gc_next != from) {
115 tail = to->gc_prev;
116 tail->gc_next = from->gc_next;
117 tail->gc_next->gc_prev = tail;
118 to->gc_prev = from->gc_prev;
119 to->gc_prev->gc_next = to;
120 }
121 gc_list_init(from);
122}
123
124static long
125gc_list_size(PyGC_Head *list)
126{
127 PyGC_Head *gc;
128 long n = 0;
129 for (gc = list->gc_next; gc != list; gc = gc->gc_next) {
130 n++;
131 }
132 return n;
133}
134
135/*** end of list stuff ***/
136
137
138/* Set all gc_refs = ob_refcnt */
139static void
140update_refs(PyGC_Head *containers)
141{
142 PyGC_Head *gc = containers->gc_next;
143 for (; gc != containers; gc=gc->gc_next) {
144 gc->gc_refs = PyObject_FROM_GC(gc)->ob_refcnt;
145 }
146}
147
148static int
149visit_decref(PyObject *op, void *data)
150{
151 if (op && PyObject_IS_GC(op)) {
152 PyObject_AS_GC(op)->gc_refs--;
153 }
154 return 0;
155}
156
157/* Subtract internal references from gc_refs */
158static void
159subtract_refs(PyGC_Head *containers)
160{
161 traverseproc traverse;
162 PyGC_Head *gc = containers->gc_next;
163 for (; gc != containers; gc=gc->gc_next) {
164 traverse = PyObject_FROM_GC(gc)->ob_type->tp_traverse;
165 (void) traverse(PyObject_FROM_GC(gc),
166 (visitproc)visit_decref,
167 NULL);
168 }
169}
170
171/* Append objects with gc_refs > 0 to roots list */
172static void
173move_roots(PyGC_Head *containers, PyGC_Head *roots)
174{
175 PyGC_Head *next;
176 PyGC_Head *gc = containers->gc_next;
177 while (gc != containers) {
178 next = gc->gc_next;
179 if (gc->gc_refs > 0) {
180 gc_list_remove(gc);
181 gc_list_append(gc, roots);
182 gc->gc_refs = GC_MOVED;
183 }
184 gc = next;
185 }
186}
187
188static int
189visit_reachable(PyObject *op, PyGC_Head *roots)
190{
191 if (PyObject_IS_GC(op)) {
192 PyGC_Head *gc = PyObject_AS_GC(op);
193 if (gc && gc->gc_refs != GC_MOVED) {
194 gc_list_remove(gc);
195 gc_list_append(gc, roots);
196 gc->gc_refs = GC_MOVED;
197 }
198 }
199 return 0;
200}
201
202/* Move objects referenced from reachable to reachable set. */
203static void
204move_root_reachable(PyGC_Head *reachable)
205{
206 traverseproc traverse;
207 PyGC_Head *gc = reachable->gc_next;
208 for (; gc != reachable; gc=gc->gc_next) {
209 /* careful, reachable list is growing here */
210 PyObject *op = PyObject_FROM_GC(gc);
211 traverse = op->ob_type->tp_traverse;
212 (void) traverse(op,
213 (visitproc)visit_reachable,
214 (void *)reachable);
215 }
216}
217
218/* move all objects with finalizers (instances with __del__) */
219static void
220move_finalizers(PyGC_Head *unreachable, PyGC_Head *finalizers)
221{
222 PyGC_Head *next;
223 PyGC_Head *gc = unreachable->gc_next;
224 static PyObject *delstr;
225 if (delstr == NULL) {
226 delstr = PyString_InternFromString("__del__");
227 }
228 for (; gc != unreachable; gc=next) {
229 PyObject *op = PyObject_FROM_GC(gc);
230 next = gc->gc_next;
231 if (PyInstance_Check(op) && PyObject_HasAttr(op, delstr)) {
232 gc_list_remove(gc);
233 gc_list_append(gc, finalizers);
234 }
235 }
236}
237
238
239/* called by tp_traverse */
240static int
241visit_finalizer_reachable(PyObject *op, PyGC_Head *finalizers)
242{
243 if (PyObject_IS_GC(op)) {
244 PyGC_Head *gc = PyObject_AS_GC(op);
245 if (gc && gc->gc_refs != GC_MOVED) {
246 gc_list_remove(gc);
247 gc_list_append(gc, finalizers);
248 gc->gc_refs = GC_MOVED;
249 }
250 }
251 return 0;
252}
253
254/* Move objects referenced from roots to roots */
255static void
256move_finalizer_reachable(PyGC_Head *finalizers)
257{
258 traverseproc traverse;
259 PyGC_Head *gc = finalizers->gc_next;
260 for (; gc != finalizers; gc=gc->gc_next) {
261 /* careful, finalizers list is growing here */
262 traverse = PyObject_FROM_GC(gc)->ob_type->tp_traverse;
263 (void) traverse(PyObject_FROM_GC(gc),
264 (visitproc)visit_finalizer_reachable,
265 (void *)finalizers);
266 }
267}
268
269static void
270debug_instance(PyObject *output, char *msg, PyInstanceObject *inst)
271{
272 char buf[200];
273 char *cname;
274 /* be careful not to create new dictionaries */
275 PyObject *classname = inst->in_class->cl_name;
276 if (classname != NULL && PyString_Check(classname))
277 cname = PyString_AsString(classname);
278 else
279 cname = "?";
280 sprintf(buf, "gc: %s<%.100s instance at %lx>\n",
281 msg, cname, (long)inst);
282 PyFile_WriteString(buf, output);
283}
284
285static void
286debug_cycle(PyObject *output, char *msg, PyObject *op)
287{
288 if ((debug & DEBUG_INSTANCES) && PyInstance_Check(op)) {
289 debug_instance(output, msg, (PyInstanceObject *)op);
290 } else if (debug & DEBUG_OBJECTS) {
291 char buf[200];
Fred Drakeb35de5b2000-07-11 14:37:41 +0000292 sprintf(buf, "gc: %s<%.100s 0x%p>\n",
Jeremy Hyltonc5007aa2000-06-30 05:02:53 +0000293 msg,
294 op->ob_type->tp_name,
Fred Drakeb35de5b2000-07-11 14:37:41 +0000295 op);
Jeremy Hyltonc5007aa2000-06-30 05:02:53 +0000296 PyFile_WriteString(buf, output);
297 }
298}
299
300/* Handle uncollectable garbage (cycles with finalizers). */
301static void
302handle_finalizers(PyGC_Head *finalizers, PyGC_Head *old)
303{
304 PyGC_Head *gc;
305 if (garbage == NULL) {
306 garbage = PyList_New(0);
307 }
308 for (gc = finalizers->gc_next; gc != finalizers;
309 gc = finalizers->gc_next) {
310 PyObject *op = PyObject_FROM_GC(gc);
311 /* Add all instances to a Python accessible list of garbage */
312 if (PyInstance_Check(op)) {
313 PyList_Append(garbage, op);
314 }
315 /* We assume that all objects in finalizers are reachable from
316 * instances. Once we add the instances to the garbage list
317 * everything is reachable from Python again. */
318 gc_list_remove(gc);
319 gc_list_append(gc, old);
320 }
321}
322
323/* Break reference cycles by clearing the containers involved. This is
324 * 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);
334 /*
335 PyList_Append(garbage, op);
336 */
337 if ((clear = op->ob_type->tp_clear) != NULL) {
338 Py_INCREF(op);
339 clear((PyObject *)op);
340 Py_DECREF(op);
341 }
342 /* only try to call tp_clear once for each object */
343 if (unreachable->gc_next == gc) {
344 /* still alive, move it, it may die later */
345 gc_list_remove(gc);
346 gc_list_append(gc, old);
347 }
348 }
349}
350
351/* This is the main function. Read this to understand how the
352 * collection process works. */
353static long
354collect(PyGC_Head *young, PyGC_Head *old)
355{
356 long n = 0;
357 long m = 0;
358 PyGC_Head reachable;
359 PyGC_Head unreachable;
360 PyGC_Head finalizers;
361 PyGC_Head *gc;
362 PyObject *output = NULL;
363
364 if (debug) {
365 output = PySys_GetObject("stderr");
366 }
367 if (debug & DEBUG_STATS) {
368 char buf[100];
369 sprintf(buf, "gc: collecting generation %d...\n", generation);
370 PyFile_WriteString(buf,output);
Fred Drakeb35de5b2000-07-11 14:37:41 +0000371 sprintf(buf, "gc: objects in each generation: %ld %ld %ld\n",
Jeremy Hyltonc5007aa2000-06-30 05:02:53 +0000372 gc_list_size(&generation0),
373 gc_list_size(&generation1),
374 gc_list_size(&generation2));
375 PyFile_WriteString(buf,output);
376 }
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++;
413 if (output != NULL && (debug & DEBUG_COLLECTABLE)) {
414 debug_cycle(output, "collectable ", PyObject_FROM_GC(gc));
415 }
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++;
427 if (output != NULL && (debug & DEBUG_UNCOLLECTABLE)) {
428 debug_cycle(output, "uncollectable ", PyObject_FROM_GC(gc));
429 }
430 }
431 if (output != NULL && (debug & DEBUG_STATS)) {
432 if (m == 0 && n == 0) {
433 PyFile_WriteString("gc: done.\n", output);
434 } else {
435 char buf[200];
436 sprintf(buf,
Fred Drakeb35de5b2000-07-11 14:37:41 +0000437 "gc: done, %ld unreachable, %ld uncollectable.\n",
Jeremy Hyltonc5007aa2000-06-30 05:02:53 +0000438 n+m, n);
439 PyFile_WriteString(buf, output);
440 }
441 }
442
443 /* Append instances in the uncollectable set to a Python
444 * reachable list of garbage. The programmer has to deal with
445 * this if they insist on creating this type of structure. */
446 handle_finalizers(&finalizers, old);
447
448 allocated = 0;
449 PyErr_Clear(); /* in case writing to sys.stderr failed */
450 return n+m;
451}
452
453static long
454collect_generations(void)
455{
456 static long collections0 = 0;
457 static long collections1 = 0;
Vladimir Marangozovb16714b2000-07-10 05:37:39 +0000458 long n = 0;
Jeremy Hyltonc5007aa2000-06-30 05:02:53 +0000459
460
461 if (collections1 > threshold2) {
462 generation = 2;
463 gc_list_merge(&generation0, &generation2);
464 gc_list_merge(&generation1, &generation2);
465 if (generation2.gc_next != &generation2) {
466 n = collect(&generation2, &generation2);
467 }
468 collections1 = 0;
469 } else if (collections0 > threshold1) {
470 generation = 1;
471 collections1++;
472 gc_list_merge(&generation0, &generation1);
473 if (generation1.gc_next != &generation1) {
474 n = collect(&generation1, &generation2);
475 }
476 collections0 = 0;
477 } else {
478 generation = 0;
479 collections0++;
480 if (generation0.gc_next != &generation0) {
481 n = collect(&generation0, &generation1);
482 }
483 }
484 return n;
485}
486
487void
488_PyGC_Insert(PyObject *op)
489{
490 /* collection lock since collecting may cause allocations */
491 static int collecting = 0;
492
493#ifdef Py_DEBUG
494 if (!PyObject_IS_GC(op)) {
495 abort();
496 }
497#endif
498 if (threshold0 && allocated > threshold0 && !collecting) {
499 collecting++;
500 collect_generations();
501 collecting--;
502 }
503 allocated++;
504 gc_list_append(PyObject_AS_GC(op), &generation0);
505}
506
507void
508_PyGC_Remove(PyObject *op)
509{
510 PyGC_Head *g = PyObject_AS_GC(op);
511#ifdef Py_DEBUG
512 if (!PyObject_IS_GC(op)) {
513 abort();
514 }
515#endif
516 gc_list_remove(g);
517 if (allocated > 0) {
518 allocated--;
519 }
520}
521
522
523static char collect__doc__[] =
524"collect() -> n\n"
525"\n"
526"Run a full collection. The number of unreachable objects is returned.\n"
527;
528
529static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000530Py_collect(PyObject *self, PyObject *args)
Jeremy Hyltonc5007aa2000-06-30 05:02:53 +0000531{
532 long n;
533
Fred Drakecc1be242000-07-12 04:42:23 +0000534 if (!PyArg_ParseTuple(args, ":collect")) /* check no args */
Jeremy Hyltonc5007aa2000-06-30 05:02:53 +0000535 return NULL;
536
537 generation = 2;
538 gc_list_merge(&generation0, &generation2);
539 gc_list_merge(&generation1, &generation2);
540 n = collect(&generation2, &generation2);
541
542 return Py_BuildValue("i", n);
543}
544
545static char set_debug__doc__[] =
546"set_debug(flags) -> None\n"
547"\n"
548"Set the garbage collection debugging flags. Debugging information is\n"
549"written to sys.stderr.\n"
550"\n"
551"flags is an integer and can have the following bits turned on:\n"
552"\n"
553" DEBUG_STATS - Print statistics during collection.\n"
554" DEBUG_COLLECTABLE - Print collectable objects found.\n"
555" DEBUG_UNCOLLECTABLE - Print unreachable but uncollectable objects found.\n"
556" DEBUG_INSTANCES - Print instance objects.\n"
557" DEBUG_OBJECTS - Print objects other than instances.\n"
558" DEBUG_LEAK - Debug leaking programs (everything but STATS).\n"
559;
560
561static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000562Py_set_debug(PyObject *self, PyObject *args)
Jeremy Hyltonc5007aa2000-06-30 05:02:53 +0000563{
Fred Drakecc1be242000-07-12 04:42:23 +0000564 if (!PyArg_ParseTuple(args, "l:get_debug", &debug))
Jeremy Hyltonc5007aa2000-06-30 05:02:53 +0000565 return NULL;
566
567 Py_INCREF(Py_None);
568 return Py_None;
569}
570
571static char get_debug__doc__[] =
572"get_debug() -> flags\n"
573"\n"
574"Get the garbage collection debugging flags.\n"
575;
576
577static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000578Py_get_debug(PyObject *self, PyObject *args)
Jeremy Hyltonc5007aa2000-06-30 05:02:53 +0000579{
Fred Drakecc1be242000-07-12 04:42:23 +0000580 if (!PyArg_ParseTuple(args, ":get_debug")) /* no args */
Jeremy Hyltonc5007aa2000-06-30 05:02:53 +0000581 return NULL;
582
583 return Py_BuildValue("i", debug);
584}
585
586static char set_thresh__doc__[] =
587"set_threshold(threshold0, [threhold1, threshold2]) -> None\n"
588"\n"
589"Sets the collection thresholds. Setting threshold0 to zero disables\n"
590"collection.\n"
591;
592
593static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000594Py_set_thresh(PyObject *self, PyObject *args)
Jeremy Hyltonc5007aa2000-06-30 05:02:53 +0000595{
Fred Drakecc1be242000-07-12 04:42:23 +0000596 if (!PyArg_ParseTuple(args, "i|ii:set_threshold", &threshold0,
Jeremy Hyltonc5007aa2000-06-30 05:02:53 +0000597 &threshold1, &threshold2))
598 return NULL;
599
600 Py_INCREF(Py_None);
601 return Py_None;
602}
603
604static char get_thresh__doc__[] =
605"get_threshold() -> (threshold0, threshold1, threshold2)\n"
606"\n"
607"Return the current collection thresholds\n"
608;
609
610static PyObject *
Peter Schneider-Kamp8bc8f0d2000-07-10 17:15:07 +0000611Py_get_thresh(PyObject *self, PyObject *args)
Jeremy Hyltonc5007aa2000-06-30 05:02:53 +0000612{
Fred Drakecc1be242000-07-12 04:42:23 +0000613 if (!PyArg_ParseTuple(args, ":get_threshold")) /* no args */
Jeremy Hyltonc5007aa2000-06-30 05:02:53 +0000614 return NULL;
615
616 return Py_BuildValue("(iii)", threshold0, threshold1, threshold2);
617}
618
619
620static char gc__doc__ [] =
621"This module provides access to the garbage collector for reference cycles.\n"
622"\n"
623"collect() -- Do a full collection right now.\n"
624"set_debug() -- Set debugging flags.\n"
625"get_debug() -- Get debugging flags.\n"
626"set_threshold() -- Set the collection thresholds.\n"
627"get_threshold() -- Return the current the collection thresholds.\n"
628;
629
630static PyMethodDef GcMethods[] = {
631 {"set_debug", Py_set_debug, METH_VARARGS, set_debug__doc__},
632 {"get_debug", Py_get_debug, METH_VARARGS, get_debug__doc__},
633 {"set_threshold", Py_set_thresh, METH_VARARGS, set_thresh__doc__},
634 {"get_threshold", Py_get_thresh, METH_VARARGS, get_thresh__doc__},
635 {"collect", Py_collect, METH_VARARGS, collect__doc__},
636 {NULL, NULL} /* Sentinel */
637};
638
639void
640initgc(void)
641{
642 PyObject *m;
643 PyObject *d;
644
645 m = Py_InitModule4("gc",
646 GcMethods,
647 gc__doc__,
648 NULL,
649 PYTHON_API_VERSION);
650 d = PyModule_GetDict(m);
651 if (garbage == NULL) {
652 garbage = PyList_New(0);
653 }
654 PyDict_SetItemString(d, "garbage", garbage);
655 PyDict_SetItemString(d, "DEBUG_STATS",
656 PyInt_FromLong(DEBUG_STATS));
657 PyDict_SetItemString(d, "DEBUG_COLLECTABLE",
658 PyInt_FromLong(DEBUG_COLLECTABLE));
659 PyDict_SetItemString(d, "DEBUG_UNCOLLECTABLE",
660 PyInt_FromLong(DEBUG_UNCOLLECTABLE));
661 PyDict_SetItemString(d, "DEBUG_INSTANCES",
662 PyInt_FromLong(DEBUG_INSTANCES));
663 PyDict_SetItemString(d, "DEBUG_OBJECTS",
664 PyInt_FromLong(DEBUG_OBJECTS));
665 PyDict_SetItemString(d, "DEBUG_LEAK",
666 PyInt_FromLong(DEBUG_LEAK));
667}
668
669#endif /* WITH_CYCLE_GC */