@@ -182,6 +182,7 @@ _PyGC_Init(PyInterpreterState *interp)
182
182
if (gcstate->callbacks == NULL) {
183
183
return _PyStatus_NO_MEMORY();
184
184
}
185
+
gcstate->heap_size = 0;
185
186
186
187
return _PyStatus_OK();
187
188
}
@@ -1232,7 +1233,7 @@ gc_collect_region(PyThreadState *tstate,
1232
1233
struct gc_collection_stats *stats);
1233
1234
1234
1235
static inline Py_ssize_t
1235
-
gc_list_set_space(PyGC_Head *list, uintptr_t space)
1236
+
gc_list_set_space(PyGC_Head *list, int space)
1236
1237
{
1237
1238
Py_ssize_t size = 0;
1238
1239
PyGC_Head *gc;
@@ -1258,9 +1259,9 @@ gc_list_set_space(PyGC_Head *list, uintptr_t space)
1258
1259
* N == 1.4 (1 + 4/threshold)
1259
1260
*/
1260
1261
1261
-
/* Multiply by 4 so that the default incremental threshold of 10
1262
-
* scans objects at 20% the rate of object creation */
1263
-
#define SCAN_RATE_MULTIPLIER 2
1262
+
/* Divide by 10, so that the default incremental threshold of 10
1263
+
* scans objects at 1% of the heap size */
1264
+
#define SCAN_RATE_DIVISOR 10
1264
1265
1265
1266
static void
1266
1267
add_stats(GCState *gcstate, int gen, struct gc_collection_stats *stats)
@@ -1313,7 +1314,7 @@ gc_collect_young(PyThreadState *tstate,
1313
1314
if (scale_factor < 1) {
1314
1315
scale_factor = 1;
1315
1316
}
1316
-
gcstate->work_to_do += survivor_count + survivor_count * SCAN_RATE_MULTIPLIER / scale_factor;
1317
+
gcstate->work_to_do += gcstate->heap_size / SCAN_RATE_DIVISOR / scale_factor;
1317
1318
add_stats(gcstate, 0, stats);
1318
1319
}
1319
1320
@@ -1384,12 +1385,12 @@ expand_region_transitively_reachable(PyGC_Head *container, PyGC_Head *gc, GCStat
1384
1385
static void
1385
1386
completed_cycle(GCState *gcstate)
1386
1387
{
1388
+
#ifdef Py_DEBUG
1387
1389
PyGC_Head *not_visited = &gcstate->old[gcstate->visited_space^1].head;
1388
1390
assert(gc_list_is_empty(not_visited));
1391
+
#endif
1389
1392
gcstate->visited_space = flip_old_space(gcstate->visited_space);
1390
-
if (gcstate->work_to_do > 0) {
1391
-
gcstate->work_to_do = 0;
1392
-
}
1393
+
gcstate->work_to_do = 0;
1393
1394
}
1394
1395
1395
1396
static void
@@ -1404,13 +1405,13 @@ gc_collect_increment(PyThreadState *tstate, struct gc_collection_stats *stats)
1404
1405
if (scale_factor < 1) {
1405
1406
scale_factor = 1;
1406
1407
}
1407
-
Py_ssize_t increment_size = 0;
1408
1408
gc_list_merge(&gcstate->young.head, &increment);
1409
1409
gcstate->young.count = 0;
1410
1410
if (gcstate->visited_space) {
1411
1411
/* objects in visited space have bit set, so we set it here */
1412
1412
gc_list_set_space(&increment, 1);
1413
1413
}
1414
+
Py_ssize_t increment_size = 0;
1414
1415
while (increment_size < gcstate->work_to_do) {
1415
1416
if (gc_list_is_empty(not_visited)) {
1416
1417
break;
@@ -1425,14 +1426,11 @@ gc_collect_increment(PyThreadState *tstate, struct gc_collection_stats *stats)
1425
1426
PyGC_Head survivors;
1426
1427
gc_list_init(&survivors);
1427
1428
gc_collect_region(tstate, &increment, &survivors, UNTRACK_TUPLES, stats);
1428
-
Py_ssize_t survivor_count = gc_list_size(&survivors);
1429
1429
gc_list_merge(&survivors, visited);
1430
1430
assert(gc_list_is_empty(&increment));
1431
-
gcstate->work_to_do += survivor_count + survivor_count * SCAN_RATE_MULTIPLIER / scale_factor;
1431
+
gcstate->work_to_do += gcstate->heap_size / SCAN_RATE_DIVISOR / scale_factor;
1432
1432
gcstate->work_to_do -= increment_size;
1433
-
if (gcstate->work_to_do < 0) {
1434
-
gcstate->work_to_do = 0;
1435
-
}
1433
+
1436
1434
validate_old(gcstate);
1437
1435
add_stats(gcstate, 1, stats);
1438
1436
if (gc_list_is_empty(not_visited)) {
@@ -1678,7 +1676,7 @@ _PyGC_GetReferrers(PyInterpreterState *interp, PyObject *objs)
1678
1676
}
1679
1677
1680
1678
PyObject *
1681
-
_PyGC_GetObjects(PyInterpreterState *interp, Py_ssize_t generation)
1679
+
_PyGC_GetObjects(PyInterpreterState *interp, int generation)
1682
1680
{
1683
1681
assert(generation >= -1 && generation < NUM_GENERATIONS);
1684
1682
GCState *gcstate = &interp->gc;
@@ -1974,6 +1972,7 @@ _PyObject_GC_Link(PyObject *op)
1974
1972
gc->_gc_next = 0;
1975
1973
gc->_gc_prev = 0;
1976
1974
gcstate->young.count++; /* number of allocated GC objects */
1975
+
gcstate->heap_size++;
1977
1976
if (gcstate->young.count > gcstate->young.threshold &&
1978
1977
gcstate->enabled &&
1979
1978
gcstate->young.threshold &&
@@ -2095,6 +2094,7 @@ PyObject_GC_Del(void *op)
2095
2094
if (gcstate->young.count > 0) {
2096
2095
gcstate->young.count--;
2097
2096
}
2097
+
gcstate->heap_size--;
2098
2098
PyObject_Free(((char *)op)-presize);
2099
2099
}
2100
2100
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