@@ -109,11 +109,14 @@ static inline void _PyObject_GC_SET_SHARED_INLINE(PyObject *op) {
109
109
110
110
/* Bit flags for _gc_prev */
111
111
/* Bit 0 is set when tp_finalize is called */
112
-
#define _PyGC_PREV_MASK_FINALIZED (1)
112
+
#define _PyGC_PREV_MASK_FINALIZED 1
113
113
/* Bit 1 is set when the object is in generation which is GCed currently. */
114
-
#define _PyGC_PREV_MASK_COLLECTING (2)
115
-
/* The (N-2) most significant bits contain the real address. */
116
-
#define _PyGC_PREV_SHIFT (2)
114
+
#define _PyGC_PREV_MASK_COLLECTING 2
115
+
116
+
/* Bit 0 is set if the object belongs to old space 1 */
117
+
#define _PyGC_NEXT_MASK_OLD_SPACE_1 1
118
+
119
+
#define _PyGC_PREV_SHIFT 2
117
120
#define _PyGC_PREV_MASK (((uintptr_t) -1) << _PyGC_PREV_SHIFT)
118
121
119
122
/* set for debugging information */
@@ -139,18 +142,21 @@ typedef enum {
139
142
// Lowest bit of _gc_next is used for flags only in GC.
140
143
// But it is always 0 for normal code.
141
144
static inline PyGC_Head* _PyGCHead_NEXT(PyGC_Head *gc) {
142
-
uintptr_t next = gc->_gc_next;
145
+
uintptr_t next = gc->_gc_next & _PyGC_PREV_MASK;
143
146
return (PyGC_Head*)next;
144
147
}
145
148
static inline void _PyGCHead_SET_NEXT(PyGC_Head *gc, PyGC_Head *next) {
146
-
gc->_gc_next = (uintptr_t)next;
149
+
uintptr_t unext = (uintptr_t)next;
150
+
assert((unext & ~_PyGC_PREV_MASK) == 0);
151
+
gc->_gc_next = (gc->_gc_next & ~_PyGC_PREV_MASK) | unext;
147
152
}
148
153
149
154
// Lowest two bits of _gc_prev is used for _PyGC_PREV_MASK_* flags.
150
155
static inline PyGC_Head* _PyGCHead_PREV(PyGC_Head *gc) {
151
156
uintptr_t prev = (gc->_gc_prev & _PyGC_PREV_MASK);
152
157
return (PyGC_Head*)prev;
153
158
}
159
+
154
160
static inline void _PyGCHead_SET_PREV(PyGC_Head *gc, PyGC_Head *prev) {
155
161
uintptr_t uprev = (uintptr_t)prev;
156
162
assert((uprev & ~_PyGC_PREV_MASK) == 0);
@@ -236,6 +242,13 @@ struct gc_generation {
236
242
generations */
237
243
};
238
244
245
+
struct gc_collection_stats {
246
+
/* number of collected objects */
247
+
Py_ssize_t collected;
248
+
/* total number of uncollectable objects (put into gc.garbage) */
249
+
Py_ssize_t uncollectable;
250
+
};
251
+
239
252
/* Running stats per generation */
240
253
struct gc_generation_stats {
241
254
/* total number of collections */
@@ -257,8 +270,8 @@ struct _gc_runtime_state {
257
270
int enabled;
258
271
int debug;
259
272
/* linked lists of container objects */
260
-
struct gc_generation generations[NUM_GENERATIONS];
261
-
PyGC_Head *generation0;
273
+
struct gc_generation young;
274
+
struct gc_generation old[2];
262
275
/* a permanent generation which won't be collected */
263
276
struct gc_generation permanent_generation;
264
277
struct gc_generation_stats generation_stats[NUM_GENERATIONS];
@@ -268,6 +281,12 @@ struct _gc_runtime_state {
268
281
PyObject *garbage;
269
282
/* a list of callbacks to be invoked when collection is performed */
270
283
PyObject *callbacks;
284
+
285
+
Py_ssize_t work_to_do;
286
+
/* Which of the old spaces is the visited space */
287
+
int visited_space;
288
+
289
+
#ifdef Py_GIL_DISABLED
271
290
/* This is the number of objects that survived the last full
272
291
collection. It approximates the number of long lived objects
273
292
tracked by the GC.
@@ -279,6 +298,7 @@ struct _gc_runtime_state {
279
298
collections, and are awaiting to undergo a full collection for
280
299
the first time. */
281
300
Py_ssize_t long_lived_pending;
301
+
#endif
282
302
};
283
303
284
304
#ifdef Py_GIL_DISABLED
@@ -291,9 +311,8 @@ struct _gc_thread_state {
291
311
292
312
extern void _PyGC_InitState(struct _gc_runtime_state *);
293
313
294
-
extern Py_ssize_t _PyGC_Collect(PyThreadState *tstate, int generation,
295
-
_PyGC_Reason reason);
296
-
extern Py_ssize_t _PyGC_CollectNoFail(PyThreadState *tstate);
314
+
extern Py_ssize_t _PyGC_Collect(PyThreadState *tstate, int generation, _PyGC_Reason reason);
315
+
extern void _PyGC_CollectNoFail(PyThreadState *tstate);
297
316
298
317
/* Freeze objects tracked by the GC and ignore them in future collections. */
299
318
extern void _PyGC_Freeze(PyInterpreterState *interp);
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4