void mp_thread_gc_others(void) { mp_thread_mutex_lock(&thread_mutex, 1); for (thread_t *th = thread; th != NULL; th = th->next) { gc_collect_root((void**)&th, 1); gc_collect_root(&th->arg, 1); // probably not needed if (th->id == xTaskGetCurrentTaskHandle()) { continue; } if (!th->ready) { continue; } gc_collect_root(th->stack, th->stack_len); // probably not needed } mp_thread_mutex_unlock(&thread_mutex); }
void gc_test(void) { machine_uint_t len = 500; machine_uint_t *heap = malloc(len); gc_init(heap, heap + len / sizeof(machine_uint_t)); void *ptrs[100]; { machine_uint_t **p = gc_alloc(16, false); p[0] = gc_alloc(64, false); p[1] = gc_alloc(1, false); p[2] = gc_alloc(1, false); p[3] = gc_alloc(1, false); machine_uint_t ***p2 = gc_alloc(16, false); p2[0] = p; p2[1] = p; ptrs[0] = p2; } for (int i = 0; i < 25; i+=2) { machine_uint_t *p = gc_alloc(i, false); printf("p=%p\n", p); if (i & 3) { //ptrs[i] = p; } } printf("Before GC:\n"); gc_dump_alloc_table(); printf("Starting GC...\n"); gc_collect_start(); gc_collect_root(ptrs, sizeof(ptrs) / sizeof(void*)); gc_collect_end(); printf("After GC:\n"); gc_dump_alloc_table(); }
void gc_collect(void) { // WARNING: This gc_collect implementation doesn't try to get root // pointers from CPU registers, and thus may function incorrectly. void *dummy; gc_collect_start(); gc_collect_root(&dummy, ((mp_uint_t)stack_top - (mp_uint_t)&dummy) / sizeof(mp_uint_t)); gc_collect_end(); }
void gc_collect(void) { // TODO possibly need to trace registers void *dummy; gc_collect_start(); // Node: stack is ascending gc_collect_root(&dummy, ((mp_uint_t)&dummy - (mp_uint_t)MP_STATE_THREAD(stack_top)) / sizeof(mp_uint_t)); gc_collect_end(); }
void gc_collect(void) { //gc_dump_info(); gc_collect_start(); // this traces .data and .bss sections extern char __bss_start, _end; //printf(".bss: %p-%p\n", &__bss_start, &_end); gc_collect_root((void**)&__bss_start, ((uint32_t)&_end - (uint32_t)&__bss_start) / sizeof(uint32_t)); regs_t regs; gc_helper_get_regs(regs); // GC stack (and regs because we captured them) gc_collect_root((void**)®s, ((uint32_t)stack_top - (uint32_t)®s) / sizeof(uint32_t)); gc_collect_end(); //printf("-----\n"); //gc_dump_info(); }
void esp_native_code_gc_collect(void) { void *src; if (esp_native_code_location == ESP_NATIVE_CODE_IRAM1) { src = (void*)esp_native_code_start; } else { src = (void*)(FLASH_START + esp_native_code_start); } gc_collect_root(src, (esp_native_code_end - esp_native_code_start) / sizeof(uint32_t)); }
void gc_collect_start(void) { gc_lock(); MP_STATE_MEM(gc_stack_overflow) = 0; MP_STATE_MEM(gc_sp) = MP_STATE_MEM(gc_stack); // Trace root pointers. This relies on the root pointers being organised // correctly in the mp_state_ctx structure. We scan nlr_top, dict_locals, // dict_globals, then the root pointer section of mp_state_vm. void **ptrs = (void**)(void*)&mp_state_ctx; gc_collect_root(ptrs, offsetof(mp_state_ctx_t, vm.stack_top) / sizeof(void*)); }
void gc_collect(void) { // WARNING: This gc_collect implementation doesn't try to get root // pointers from CPU registers, and thus may function incorrectly. jmp_buf dummy; if (setjmp(dummy) == 0) { longjmp(dummy, 1); } gc_collect_start(); gc_collect_root((void*)stack_top, ((mp_uint_t)(void*)(&dummy + 1) - (mp_uint_t)stack_top) / sizeof(mp_uint_t)); gc_collect_end(); }
void gc_collect_start(void) { GC_ENTER(); MP_STATE_MEM(gc_lock_depth)++; #if MICROPY_GC_ALLOC_THRESHOLD MP_STATE_MEM(gc_alloc_amount) = 0; #endif MP_STATE_MEM(gc_stack_overflow) = 0; // Trace root pointers. This relies on the root pointers being organised // correctly in the mp_state_ctx structure. We scan nlr_top, dict_locals, // dict_globals, then the root pointer section of mp_state_vm. void **ptrs = (void**)(void*)&mp_state_ctx; gc_collect_root(ptrs, offsetof(mp_state_ctx_t, vm.qstr_last_chunk) / sizeof(void*)); #if MICROPY_ENABLE_PYSTACK // Trace root pointers from the Python stack. ptrs = (void**)(void*)MP_STATE_THREAD(pystack_start); gc_collect_root(ptrs, (MP_STATE_THREAD(pystack_cur) - MP_STATE_THREAD(pystack_start)) / sizeof(void*)); #endif }
int mp_thread_gc_others(void) { /* mp_thread_mutex_lock(&thread_mutex, 1); for (thread_t *th = thread; th != NULL; th = th->next) { gc_collect_root((void**)&th, 1); gc_collect_root(&th->arg, 1); // probably not needed if (th->id == xTaskGetCurrentTaskHandle()) { continue; } if (!th->ready) { continue; } gc_collect_root(th->stack, th->stack_len); // probably not needed } mp_thread_mutex_unlock(&thread_mutex); */ int n_th = 0; void **ptrs; mp_state_thread_t *state; mp_thread_mutex_lock(&thread_mutex, 1); for (thread_t *th = thread; th != NULL; th = th->next) { if (!th->ready) continue; // thread not ready //if (th->type == THREAD_TYPE_SERVICE) continue; // Only scan PYTHON threads if (th->id == xTaskGetCurrentTaskHandle()) continue; // Do not process the running thread //state = (mp_state_thread_t *)th->state_thread; n_th++; // Mark the root pointers on thread //gc_collect_root((void **)state->dict_locals, 1); if (th->arg) { // Mark the pointers on thread arguments ptrs = (void**)(void*)&th->arg; gc_collect_root(ptrs, 1); } #if MICROPY_ENABLE_PYSTACK // Mark the pointers on thread pystack //ptrs = (void**)(void*)state->pystack_start; //gc_collect_root(ptrs, (state->pystack_cur - state->pystack_start) / sizeof(void*)); #endif // If PyStack is used, no pointers to MPy heap are placed on tasks stack #if !MICROPY_ENABLE_PYSTACK // Mark the pointers on thread stack //gc_collect_root(th->curr_sp, ((void *)state->stack_top - th->curr_sp) / sizeof(void*)); // probably not needed #endif } mp_thread_mutex_unlock(&thread_mutex); return n_th; }
void gc_collect(void) { gc_collect_start(); // get the registers and the sp uint32_t regs[10]; uint32_t sp = gc_helper_get_regs_and_sp(regs); // trace the stack, including the registers (since they live on the stack in this function) gc_collect_root((void**)sp, ((uint32_t)MP_STATE_THREAD(stack_top) - sp) / sizeof(uint32_t)); gc_collect_end(); }
void gc_collect(void) { gc_collect_start(); // get the registers and the sp jmp_buf env; setjmp(env); volatile mp_uint_t dummy; void *sp = (void*)&dummy; // trace the stack, including the registers (since they live on the stack in this function) gc_collect_root((void**)sp, ((uint32_t)MP_STATE_VM(stack_top) - (uint32_t)sp) / sizeof(uint32_t)); gc_collect_end(); }
void gc_collect(void) { // start the GC gc_collect_start(); // get the registers and the sp mp_uint_t regs[10]; mp_uint_t sp = gc_helper_get_regs_and_sp(regs); // trace the stack, including the registers (since they live on the stack in this function) gc_collect_root((void**)sp, (stackend - sp) / sizeof(uint32_t)); // end the GC gc_collect_end(); }
void gc_collect(void) { /* Start the GC. */ gc_collect_start(); /* Get the registers and the sp */ mp_uint_t regs[8]; mp_uint_t sp = gc_helper_get_regs_and_sp(regs); /* Trace the stack, including the registers (since they live on the stack in this function). */ gc_collect_root((void**)sp, ((uint32_t)stack_top_p - sp) / sizeof(uint32_t)); /* End the GC. */ gc_collect_end(); }
void gc_collect(void) { // start the GC gc_collect_start(); // get the registers and the sp mp_uint_t regs[10]; mp_uint_t sp = gc_helper_get_regs_and_sp(regs); // trace the stack, including the registers (since they live on the stack in this function) gc_collect_root((void**)sp, ((mp_uint_t)MP_STATE_THREAD(stack_top) - sp) / sizeof(uint32_t)); // trace root pointers from any threads #if MICROPY_PY_THREAD mp_thread_gc_others(); #endif // end the GC gc_collect_end(); }
void gc_collect(void) { // start the GC gc_collect_start(); // get the registers and the sp mp_uint_t regs[8]; mp_uint_t sp = gc_helper_get_regs_and_sp(regs); // trace the stack, including the registers (since they live on the stack in this function) gc_collect_root((void**)sp, (STACK_END - sp) / sizeof(uint32_t)); #if MICROPY_EMIT_XTENSA || MICROPY_EMIT_INLINE_XTENSA // trace any native code because it can contain pointers to the heap esp_native_code_gc_collect(); #endif // end the GC gc_collect_end(); }
void mp_unix_mark_exec(void) { for (mmap_region_t *rg = MP_STATE_VM(mmap_region_head); rg != NULL; rg = rg->next) { gc_collect_root(rg->ptr, rg->len / sizeof(mp_uint_t)); } }