Skip to content

Commit b796e3d

Browse files
committed
py: Reduce fragmentation of GC heap.
Recent speed up of GC allocation made the GC have a fragmented heap. This patch restores "original fragmentation behaviour" whilst still retaining relatively fast allocation. This patch works because there is always going to be a single block allocated now and then, which advances the gc_last_free_atb_index pointer often enough so that the whole heap doesn't need scanning. Should address issue adafruit#836.
1 parent a97e091 commit b796e3d

File tree

1 file changed

+7
-9
lines changed

1 file changed

+7
-9
lines changed

py/gc.c

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -386,13 +386,6 @@ void *gc_alloc(mp_uint_t n_bytes, bool has_finaliser) {
386386
if (ATB_2_IS_FREE(a)) { if (++n_free >= n_blocks) { i = i * BLOCKS_PER_ATB + 2; goto found; } } else { n_free = 0; }
387387
if (ATB_3_IS_FREE(a)) { if (++n_free >= n_blocks) { i = i * BLOCKS_PER_ATB + 3; goto found; } } else { n_free = 0; }
388388
}
389-
for (i = 0; i < gc_last_free_atb_index; i++) {
390-
byte a = gc_alloc_table_start[i];
391-
if (ATB_0_IS_FREE(a)) { if (++n_free >= n_blocks) { i = i * BLOCKS_PER_ATB + 0; goto found; } } else { n_free = 0; }
392-
if (ATB_1_IS_FREE(a)) { if (++n_free >= n_blocks) { i = i * BLOCKS_PER_ATB + 1; goto found; } } else { n_free = 0; }
393-
if (ATB_2_IS_FREE(a)) { if (++n_free >= n_blocks) { i = i * BLOCKS_PER_ATB + 2; goto found; } } else { n_free = 0; }
394-
if (ATB_3_IS_FREE(a)) { if (++n_free >= n_blocks) { i = i * BLOCKS_PER_ATB + 3; goto found; } } else { n_free = 0; }
395-
}
396389

397390
// nothing found!
398391
if (collected) {
@@ -409,8 +402,13 @@ void *gc_alloc(mp_uint_t n_bytes, bool has_finaliser) {
409402
end_block = i;
410403
start_block = i - n_free + 1;
411404

412-
// set last free ATB index to last block we found, for start of next scan
413-
gc_last_free_atb_index = i / BLOCKS_PER_ATB;
405+
// Set last free ATB index to block after last block we found, for start of
406+
// next scan. To reduce fragmentation, we only do this if we were looking
407+
// for a single free block, which guarantees that there are no free blocks
408+
// before this one.
409+
if (n_free == 1) {
410+
gc_last_free_atb_index = (i + 1) / BLOCKS_PER_ATB;
411+
}
414412

415413
// mark first block as used head
416414
ATB_FREE_TO_HEAD(start_block);

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy