Fix a definition and add some clarifications

This commit is contained in:
Antoine Pitrou 2013-05-19 00:51:45 +02:00
parent b5146db1e9
commit 3feda9aad7
1 changed files with 28 additions and 13 deletions

View File

@ -41,9 +41,10 @@ Reference cycle
scheme.
Cyclic isolate (CI)
A reference cycle in which no object is referenced from outside the
cycle *and* whose objects are still in a usable, non-broken state:
they can access each other from their respective finalizers.
A standalone subgraph of objects in which no object is referenced
from the outside, containing one or several reference cycles, *and*
whose objects are still in a usable, non-broken state: they can
access each other from their respective finalizers.
Cyclic garbage collector (GC)
A device able to detect cyclic isolates and turn them into cyclic
@ -52,11 +53,10 @@ Cyclic garbage collector (GC)
reference counts dropping to zero.
Cyclic trash (CT)
A reference cycle, or former reference cycle, in which no object
is referenced from outside the cycle *and* whose objects have
started being cleared by the GC. Objects in cyclic trash are
potential zombies; if they are accessed by Python code, the symptoms
can vary from weird AttributeErrors to crashes.
A former cyclic isolate whose objects have started being cleared
by the GC. Objects in cyclic trash are potential zombies; if they
are accessed by Python code, the symptoms can vary from weird
AttributeErrors to crashes.
Zombie / broken object
An object part of cyclic trash. The term stresses that the object
@ -156,15 +156,21 @@ steps are in bold):
(as a side-effect of clearing references); this collection is
finished.
.. note::
The GC doesn't recalculate the CI after step 2 above, hence the need
for step 3 to check that the whole subgraph is still isolated.
C-level changes
===============
Type objects get a new ``tp_finalize`` slot to which ``__del__`` methods
are bound. Generators are also modified to use this slot, rather than
``tp_del``. At the C level, a ``tp_finalize`` function is a normal
function which will be called with a regular, alive object as its only
argument. It should not attempt to revive or collect the object.
are mapped (and reciprocally). Generators are modified to use this slot,
rather than ``tp_del``. A ``tp_finalize`` function is a normal C
function which will be called with a valid and alive ``PyObject`` as its
only argument. It doesn't need to manipulate the object's reference count,
as this will be done by the caller. However, it must ensure that the
original exception state is restored before returning to the caller.
For compatibility, ``tp_del`` is kept in the type structure. Handling
of objects with a non-NULL ``tp_del`` is unchanged: when part of a CI,
@ -172,11 +178,20 @@ they are not finalized and end up in ``gc.garbage``. However, a non-NULL
``tp_del`` is not encountered anymore in the CPython source tree (except
for testing purposes).
Two new C API functions are provided to ease calling of ``tp_finalize``,
especially from custom deallocators.
On the internal side, a bit is reserved in the GC header for GC-managed
objects to signal that they were finalized. This helps avoid finalizing
an object twice (and, especially, finalizing a CT object after it was
broken by the GC).
.. note::
Objects which are not GC-enabled can also have a ``tp_finalize`` slot.
They don't need the additional bit since their ``tp_finalize`` function
can only be called from the deallocator: it therefore cannot be called
twice, except when resurrected.
Discussion
==========
@ -186,7 +201,7 @@ Predictability
Following this scheme, an object's finalizer is always called exactly
once. The only exception is if an object is resurrected: the finalizer
will be called again later.
will be called again when the object becomes unreachable again.
For CI objects, the order in which finalizers are called (step 2 above)
is undefined.