Skip to content

Commit

Permalink
unix/coverage: Add extra GC coverage test for ATB gap byte.
Browse files Browse the repository at this point in the history
The assertion that is added here (to gc.c) fails when running this new test
if ALLOC_TABLE_GAP_BYTE is set to 0.

Signed-off-by: Jeff Epler <jepler@gmail.com>
Signed-off-by: Damien George <damien@micropython.org>
  • Loading branch information
jepler authored and dpgeorge committed Dec 8, 2022
1 parent 9f434dd commit d75ff42
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 0 deletions.
37 changes: 37 additions & 0 deletions ports/unix/coverage.c
@@ -1,4 +1,5 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "py/obj.h"
Expand Down Expand Up @@ -224,6 +225,42 @@ STATIC mp_obj_t extra_coverage(void) {
mp_printf(&mp_plat_print, "%p\n", gc_nbytes(NULL));
}

// GC initialisation and allocation stress test, to check the logic behind ALLOC_TABLE_GAP_BYTE
// (the following test should fail when ALLOC_TABLE_GAP_BYTE=0)
{
mp_printf(&mp_plat_print, "# GC part 2\n");

// check the GC is unlocked and save its state
assert(MP_STATE_THREAD(gc_lock_depth) == 0);
mp_state_mem_t mp_state_mem_orig = mp_state_ctx.mem;

// perform the test
unsigned heap_size = 64 * MICROPY_BYTES_PER_GC_BLOCK;
for (unsigned j = 0; j < 256 * MP_BYTES_PER_OBJ_WORD; ++j) {
char *heap = calloc(heap_size, 1);
gc_init(heap, heap + heap_size);

m_malloc(MICROPY_BYTES_PER_GC_BLOCK);
void *o = gc_alloc(MICROPY_BYTES_PER_GC_BLOCK, GC_ALLOC_FLAG_HAS_FINALISER);
((mp_obj_base_t *)o)->type = NULL; // ensure type is cleared so GC doesn't look for finaliser
for (unsigned i = 0; i < heap_size / MICROPY_BYTES_PER_GC_BLOCK; ++i) {
void *p = m_malloc_maybe(MICROPY_BYTES_PER_GC_BLOCK);
if (!p) {
break;
}
*(void **)p = o;
o = p;
}
gc_collect();
free(heap);
heap_size += MICROPY_BYTES_PER_GC_BLOCK / 16;
}
mp_printf(&mp_plat_print, "pass\n");

// restore the GC state (the original heap)
mp_state_ctx.mem = mp_state_mem_orig;
}

// tracked allocation
{
#define NUM_PTRS (8)
Expand Down
3 changes: 3 additions & 0 deletions py/gc.c
Expand Up @@ -297,6 +297,9 @@ STATIC void gc_mark_subtree(size_t block)
n_blocks += 1;
} while (ATB_GET_KIND(area, block + n_blocks) == AT_TAIL);

// check that the consecutive blocks didn't overflow past the end of the area
assert(area->gc_pool_start + (block + n_blocks) * BYTES_PER_BLOCK <= area->gc_pool_end);

// check this block's children
void **ptrs = (void **)PTR_FROM_BLOCK(area, block);
for (size_t i = n_blocks * BYTES_PER_BLOCK / sizeof(void *); i > 0; i--, ptrs++) {
Expand Down
2 changes: 2 additions & 0 deletions tests/unix/extra_coverage.py.exp
Expand Up @@ -17,6 +17,8 @@ abc
# GC
0
0
# GC part 2
pass
# tracked allocation
m_tracked_head = 0
0 1
Expand Down

0 comments on commit d75ff42

Please sign in to comment.