Commit 7f3c0d1e authored by Dave Hylands's avatar Dave Hylands Committed by Damien George
Browse files

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.
parent 41b688e2
......@@ -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;
......
......@@ -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);
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment