From 7f3c0d1ea8fa21df3b2078c7189f2b26fe36da59 Mon Sep 17 00:00:00 2001 From: Dave Hylands Date: Fri, 6 Nov 2015 14:32:47 -0800 Subject: [PATCH] py: Clear finalizer flag when calling gc_free. Currently, the only place that clears the bit is in gc_collect. So if a block with a finalizer is allocated, and subsequently freed, and then the block is reallocated with no finalizer then the bit remains set. This could also be fixed by having gc_alloc clear the bit, but I'm pretty sure that free is called way less than alloc, so doing it in free is more efficient. --- py/gc.c | 4 ++++ py/gc.h | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/py/gc.c b/py/gc.c index e4d29d130f..077c291f3a 100644 --- a/py/gc.c +++ b/py/gc.c @@ -442,6 +442,7 @@ void *gc_alloc_with_finaliser(mp_uint_t n_bytes) { */ // force the freeing of a piece of memory +// TODO: freeing here does not call finaliser void gc_free(void *ptr_in) { if (MP_STATE_MEM(gc_lock_depth) > 0) { // TODO how to deal with this error? @@ -454,6 +455,9 @@ void gc_free(void *ptr_in) { if (VERIFY_PTR(ptr)) { mp_uint_t block = BLOCK_FROM_PTR(ptr); if (ATB_GET_KIND(block) == AT_HEAD) { + #if MICROPY_ENABLE_FINALISER + FTB_CLEAR(block); + #endif // set the last_free pointer to this block if it's earlier in the heap if (block / BLOCKS_PER_ATB < MP_STATE_MEM(gc_last_free_atb_index)) { MP_STATE_MEM(gc_last_free_atb_index) = block / BLOCKS_PER_ATB; diff --git a/py/gc.h b/py/gc.h index c61892f208..3bcf58664f 100644 --- a/py/gc.h +++ b/py/gc.h @@ -46,7 +46,7 @@ void gc_collect_root(void **ptrs, mp_uint_t len); void gc_collect_end(void); void *gc_alloc(mp_uint_t n_bytes, bool has_finaliser); -void gc_free(void *ptr); +void gc_free(void *ptr); // does not call finaliser mp_uint_t gc_nbytes(const void *ptr); void *gc_realloc(void *ptr, mp_uint_t n_bytes, bool allow_move);