|
|
|
@ -176,6 +176,8 @@ void gc_init(void *start, void *end) {
|
|
|
|
|
mp_thread_mutex_init(&MP_STATE_MEM(gc_mutex));
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
MP_STATE_MEM(permanent_pointers) = NULL;
|
|
|
|
|
|
|
|
|
|
DEBUG_printf("GC layout:\n");
|
|
|
|
|
DEBUG_printf(" alloc table at %p, length " UINT_FMT " bytes, " UINT_FMT " blocks\n", MP_STATE_MEM(gc_alloc_table_start), MP_STATE_MEM(gc_alloc_table_byte_len), MP_STATE_MEM(gc_alloc_table_byte_len) * BLOCKS_PER_ATB);
|
|
|
|
|
#if MICROPY_ENABLE_FINALISER
|
|
|
|
@ -359,6 +361,10 @@ void gc_collect_start(void) {
|
|
|
|
|
size_t root_end = offsetof(mp_state_ctx_t, vm.qstr_last_chunk);
|
|
|
|
|
gc_collect_root(ptrs + root_start / sizeof(void*), (root_end - root_start) / sizeof(void*));
|
|
|
|
|
|
|
|
|
|
if (MP_STATE_MEM(permanent_pointers) != NULL) {
|
|
|
|
|
gc_collect_root(MP_STATE_MEM(permanent_pointers), BYTES_PER_BLOCK / sizeof(void*));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#if MICROPY_ENABLE_PYSTACK
|
|
|
|
|
// Trace root pointers from the Python stack.
|
|
|
|
|
ptrs = (void**)(void*)MP_STATE_THREAD(pystack_start);
|
|
|
|
@ -938,6 +944,32 @@ void *gc_realloc(void *ptr_in, size_t n_bytes, bool allow_move) {
|
|
|
|
|
}
|
|
|
|
|
#endif // Alternative gc_realloc impl
|
|
|
|
|
|
|
|
|
|
bool gc_never_free(void *ptr) {
|
|
|
|
|
// Pointers are stored in a linked list where each block is BYTES_PER_BLOCK long and the first
|
|
|
|
|
// pointer is the next block of pointers.
|
|
|
|
|
void ** current_reference_block = MP_STATE_MEM(permanent_pointers);
|
|
|
|
|
while (current_reference_block != NULL) {
|
|
|
|
|
for (size_t i = 1; i < BYTES_PER_BLOCK / sizeof(void*); i++) {
|
|
|
|
|
if (current_reference_block[i] == NULL) {
|
|
|
|
|
current_reference_block[i] = ptr;
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
current_reference_block = current_reference_block[0];
|
|
|
|
|
}
|
|
|
|
|
void** next_block = gc_alloc(BYTES_PER_BLOCK, false, true);
|
|
|
|
|
if (next_block == NULL) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
if (MP_STATE_MEM(permanent_pointers) == NULL) {
|
|
|
|
|
MP_STATE_MEM(permanent_pointers) = next_block;
|
|
|
|
|
} else {
|
|
|
|
|
current_reference_block[0] = next_block;
|
|
|
|
|
}
|
|
|
|
|
next_block[1] = ptr;
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void gc_dump_info(void) {
|
|
|
|
|
gc_info_t info;
|
|
|
|
|
gc_info(&info);
|
|
|
|
|