py: Fix bug where GC finaliser table was not completely zeroed out.

This was a nasty bug to track down.  It only had consequences when the
heap size was just the right size to expose the rounding error in the
calculation of the finaliser table size.  And, a script had to allocate
a small (1 or 2 cell) object at the very end of the heap.  And, this
object must not have a finaliser.  And, the initial state of the heap
must have been all bits set to 1.  All these conspire on the pyboard,
but only if your run the script fresh (so unused memory is all 1's),
and if your script allocates a lot of small objects (eg 2-char strings
that are not interned).
This commit is contained in:
Damien George 2014-08-08 12:33:49 +01:00
parent 5d9b816449
commit a1d3ee376c
1 changed files with 5 additions and 2 deletions

View File

@ -126,11 +126,10 @@ void gc_init(void *start, void *end) {
gc_alloc_table_byte_len = total_byte_len / (1 + BITS_PER_BYTE / 2 * BYTES_PER_BLOCK); gc_alloc_table_byte_len = total_byte_len / (1 + BITS_PER_BYTE / 2 * BYTES_PER_BLOCK);
#endif #endif
gc_alloc_table_start = (byte*)start; gc_alloc_table_start = (byte*)start;
#if MICROPY_ENABLE_FINALISER #if MICROPY_ENABLE_FINALISER
mp_uint_t gc_finaliser_table_byte_len = (gc_alloc_table_byte_len * BLOCKS_PER_ATB) / BLOCKS_PER_FTB; mp_uint_t gc_finaliser_table_byte_len = (gc_alloc_table_byte_len * BLOCKS_PER_ATB + BLOCKS_PER_FTB - 1) / BLOCKS_PER_FTB;
gc_finaliser_table_start = gc_alloc_table_start + gc_alloc_table_byte_len; gc_finaliser_table_start = gc_alloc_table_start + gc_alloc_table_byte_len;
#endif #endif
@ -138,6 +137,10 @@ void gc_init(void *start, void *end) {
gc_pool_start = (mp_uint_t*)((byte*)end - gc_pool_block_len * BYTES_PER_BLOCK); gc_pool_start = (mp_uint_t*)((byte*)end - gc_pool_block_len * BYTES_PER_BLOCK);
gc_pool_end = (mp_uint_t*)end; gc_pool_end = (mp_uint_t*)end;
#if MICROPY_ENABLE_FINALISER
assert((byte*)gc_pool_start >= gc_finaliser_table_start + gc_finaliser_table_byte_len);
#endif
// clear ATBs // clear ATBs
memset(gc_alloc_table_start, 0, gc_alloc_table_byte_len); memset(gc_alloc_table_start, 0, gc_alloc_table_byte_len);