| LEFT | RIGHT |
| 1 /* | 1 /* |
| 2 | 2 |
| 3 Reference Cycle Garbage Collection | 3 Reference Cycle Garbage Collection |
| 4 ================================== | 4 ================================== |
| 5 | 5 |
| 6 Neil Schemenauer <nas@arctrix.com> | 6 Neil Schemenauer <nas@arctrix.com> |
| 7 | 7 |
| 8 Based on a post on the python-dev list. Ideas from Guido van Rossum, | 8 Based on a post on the python-dev list. Ideas from Guido van Rossum, |
| 9 Eric Tiedemann, and various others. | 9 Eric Tiedemann, and various others. |
| 10 | 10 |
| (...skipping 445 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 456 gc = next; | 456 gc = next; |
| 457 } | 457 } |
| 458 } | 458 } |
| 459 | 459 |
| 460 /* Return true if object has a finalization method, or signals | 460 /* Return true if object has a finalization method, or signals |
| 461 * itself as not being collectable at this time | 461 * itself as not being collectable at this time |
| 462 */ | 462 */ |
| 463 static int | 463 static int |
| 464 has_finalizer(PyObject *op) | 464 has_finalizer(PyObject *op) |
| 465 { | 465 { |
| 466 if (Py_TYPE(op)->tp_is_gc != NULL && \ | 466 if (Py_TYPE(op)->tp_is_gc != NULL) { |
| 467 (Py_TYPE(op)->tp_is_gc(op) & PyGC_UNCOLLECTABLE)) | 467 /* the flags returned by tp_is_gc override the simple |
| 468 { | 468 * method of detecting a finalizer, based on the |
| 469 return 1; | 469 * current state of the instance |
| 470 */ |
| 471 int flag = Py_TYPE(op)->tp_is_gc(op); |
| 472 if (flag & PyGC_CANNOT_COLLECT) |
| 473 return 1; /* even if no tp_del */ |
| 474 if (flag & PyGC_CAN_COLLECT) |
| 475 return 0; /* even if there is a tp_del */ |
| 470 } | 476 } |
| 471 return op->ob_type->tp_del != NULL; | 477 return op->ob_type->tp_del != NULL; |
| 472 } | 478 } |
| 473 | 479 |
| 474 /* Move the objects in unreachable with __del__ methods into `finalizers`. | 480 /* Move the objects in unreachable with __del__ methods into `finalizers`. |
| 475 * Objects moved into `finalizers` have gc_refs set to GC_REACHABLE; the | 481 * Objects moved into `finalizers` have gc_refs set to GC_REACHABLE; the |
| 476 * objects remaining in unreachable are left at GC_TENTATIVELY_UNREACHABLE. | 482 * objects remaining in unreachable are left at GC_TENTATIVELY_UNREACHABLE. |
| 477 */ | 483 */ |
| 478 static void | 484 static void |
| 479 move_finalizers(PyGC_Head *unreachable, PyGC_Head *finalizers) | 485 move_finalizers(PyGC_Head *unreachable, PyGC_Head *finalizers) |
| (...skipping 1033 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1513 PyObject_GC_Del(void *op) | 1519 PyObject_GC_Del(void *op) |
| 1514 { | 1520 { |
| 1515 PyGC_Head *g = AS_GC(op); | 1521 PyGC_Head *g = AS_GC(op); |
| 1516 if (IS_TRACKED(op)) | 1522 if (IS_TRACKED(op)) |
| 1517 gc_list_remove(g); | 1523 gc_list_remove(g); |
| 1518 if (generations[0].count > 0) { | 1524 if (generations[0].count > 0) { |
| 1519 generations[0].count--; | 1525 generations[0].count--; |
| 1520 } | 1526 } |
| 1521 PyObject_FREE(g); | 1527 PyObject_FREE(g); |
| 1522 } | 1528 } |
| LEFT | RIGHT |