|
33 | 33 |
|
34 | 34 | #define GC_DEBUG (0) /* More asserts */
|
35 | 35 |
|
36 |
| -// Bit 0 is used for _PyGC_PREV_MASK_FINALIZED in objimpl.h |
| 36 | +// Bit 0 of gc_prev is used for _PyGC_PREV_MASK_FINALIZED in objimpl.h |
37 | 37 | #define MASK_COLLECTING (1 << 1)
|
38 | 38 | #define MASK_TENTATIVELY_UNREACHABLE (1 << 2)
|
39 | 39 |
|
@@ -130,44 +130,35 @@ _PyGC_Initialize(struct _gc_runtime_state *state)
|
130 | 130 | }
|
131 | 131 |
|
132 | 132 | /*--------------------------------------------------------------------------
|
133 |
| -TODO: Rewrite this section. |
| 133 | +gc_prev values. |
134 | 134 |
|
135 |
| -gc_refs values. |
| 135 | +Between collections, gc_prev is used for doubly linked list. |
136 | 136 |
|
137 |
| -Between collections, every gc'ed object has one of two gc_refs values: |
| 137 | +Lowest three bits of gc_prev are used for flags. |
| 138 | +MASK_COLLECTING and MASK_TENTATIVELY_UNREACHABLE are used only while collecting. |
138 | 139 |
|
139 |
| -GC_UNTRACKED |
140 |
| - The initial state; objects returned by PyObject_GC_Malloc are in this |
141 |
| - state. The object doesn't live in any generation list, and its |
142 |
| - tp_traverse slot must not be called. |
| 140 | +During a collection, gc_prev is temporary used for gc_refs, and the gc list |
| 141 | +is singly linked until gc_prev is restored. |
143 | 142 |
|
144 |
| -GC_REACHABLE |
145 |
| - The object lives in some generation list, and its tp_traverse is safe to |
146 |
| - call. An object transitions to GC_REACHABLE when PyObject_GC_Track |
147 |
| - is called. |
148 |
| -
|
149 |
| -During a collection, gc_refs can temporarily take on other states: |
150 |
| -
|
151 |
| ->= 0 |
| 143 | +gc_refs |
152 | 144 | At the start of a collection, update_refs() copies the true refcount
|
153 | 145 | to gc_refs, for each object in the generation being collected.
|
154 | 146 | subtract_refs() then adjusts gc_refs so that it equals the number of
|
155 | 147 | times an object is referenced directly from outside the generation
|
156 | 148 | being collected.
|
157 | 149 | gc_refs remains >= 0 throughout these steps.
|
158 | 150 |
|
159 |
| -GC_TENTATIVELY_UNREACHABLE |
| 151 | +MASK_TENTATIVELY_UNREACHABLE |
160 | 152 | move_unreachable() then moves objects not reachable (whether directly or
|
161 |
| - indirectly) from outside the generation into an "unreachable" set. |
162 |
| - Objects that are found to be reachable have gc_refs set to GC_REACHABLE |
163 |
| - again. Objects that are found to be unreachable have gc_refs set to |
164 |
| - GC_TENTATIVELY_UNREACHABLE. It's "tentatively" because the pass doing |
165 |
| - this can't be sure until it ends, and GC_TENTATIVELY_UNREACHABLE may |
166 |
| - transition back to GC_REACHABLE. |
167 |
| -
|
168 |
| - Only objects with GC_TENTATIVELY_UNREACHABLE still set are candidates |
169 |
| - for collection. If it's decided not to collect such an object (e.g., |
170 |
| - it has a __del__ method), its gc_refs is restored to GC_REACHABLE again. |
| 153 | + indirectly) from outside the generation into an "unreachable" set and |
| 154 | + set MASK_TENTATIVELY_UNREACHABLE flag. |
| 155 | +
|
| 156 | + Objects that are found to be reachable have gc_refs set to 1. |
| 157 | + When MASK_TENTATIVELY_UNREACHABLE flag is set for the reachable object, |
| 158 | + the flag is unset and the object is moved back to "reachable" set. |
| 159 | +
|
| 160 | + Only objects with MASK_TENTATIVELY_UNREACHABLE still set are candidates |
| 161 | + for collection. |
171 | 162 | ----------------------------------------------------------------------------
|
172 | 163 | */
|
173 | 164 |
|
@@ -992,7 +983,7 @@ collect(int generation, Py_ssize_t *n_collected, Py_ssize_t *n_uncollectable,
|
992 | 983 | }
|
993 | 984 |
|
994 | 985 | /* Clear weakrefs and invoke callbacks as necessary. */
|
995 |
| - m += handle_weakrefs(&unreachable, old); // clears masks |
| 986 | + m += handle_weakrefs(&unreachable, old); |
996 | 987 |
|
997 | 988 | validate_list(old, 0);
|
998 | 989 | validate_list(&unreachable, MASK_COLLECTING | MASK_TENTATIVELY_UNREACHABLE);
|
|
0 commit comments