95
95
#define BLOCK_FROM_PTR (area , ptr ) (((byte *)(ptr) - area->gc_pool_start) / BYTES_PER_BLOCK)
96
96
#define PTR_FROM_BLOCK (area , block ) (((block) * BYTES_PER_BLOCK + (uintptr_t)area->gc_pool_start))
97
97
98
+ // After the ATB, there must be a byte filled with AT_FREE so that gc_mark_tree
99
+ // cannot erroneously conclude that a block extends past the end of the GC heap
100
+ // due to bit patterns in the FTB (or first block, if finalizers are disabled)
101
+ // being interpreted as AT_TAIL.
102
+ #define ALLOC_TABLE_GAP_BYTE (1)
103
+
98
104
#if MICROPY_ENABLE_FINALISER
99
105
// FTB = finaliser table byte
100
106
// if set, then the corresponding block may have a finaliser
@@ -123,7 +129,8 @@ STATIC void gc_setup_area(mp_state_mem_area_t *area, void *start, void *end) {
123
129
// => T = A * (1 + BLOCKS_PER_ATB / BLOCKS_PER_FTB + BLOCKS_PER_ATB * BYTES_PER_BLOCK)
124
130
size_t total_byte_len = (byte * )end - (byte * )start ;
125
131
#if MICROPY_ENABLE_FINALISER
126
- area -> gc_alloc_table_byte_len = total_byte_len * MP_BITS_PER_BYTE / (MP_BITS_PER_BYTE + MP_BITS_PER_BYTE * BLOCKS_PER_ATB / BLOCKS_PER_FTB + MP_BITS_PER_BYTE * BLOCKS_PER_ATB * BYTES_PER_BLOCK );
132
+ size_t gc_alloc_table_byte_len = (total_byte_len - ALLOC_TABLE_GAP_BYTE ) * MP_BITS_PER_BYTE / (MP_BITS_PER_BYTE + MP_BITS_PER_BYTE * BLOCKS_PER_ATB / BLOCKS_PER_FTB + MP_BITS_PER_BYTE * BLOCKS_PER_ATB * BYTES_PER_BLOCK );
133
+ area -> gc_alloc_table_byte_len = gc_alloc_table_byte_len ;
127
134
#else
128
135
area -> gc_alloc_table_byte_len = total_byte_len / (1 + MP_BITS_PER_BYTE / 2 * BYTES_PER_BLOCK );
129
136
#endif
@@ -132,7 +139,7 @@ STATIC void gc_setup_area(mp_state_mem_area_t *area, void *start, void *end) {
132
139
133
140
#if MICROPY_ENABLE_FINALISER
134
141
size_t gc_finaliser_table_byte_len = (area -> gc_alloc_table_byte_len * BLOCKS_PER_ATB + BLOCKS_PER_FTB - 1 ) / BLOCKS_PER_FTB ;
135
- area -> gc_finaliser_table_start = area -> gc_alloc_table_start + area -> gc_alloc_table_byte_len ;
142
+ area -> gc_finaliser_table_start = area -> gc_alloc_table_start + area -> gc_alloc_table_byte_len + ALLOC_TABLE_GAP_BYTE ;
136
143
#endif
137
144
138
145
size_t gc_pool_block_len = area -> gc_alloc_table_byte_len * BLOCKS_PER_ATB ;
@@ -143,12 +150,12 @@ STATIC void gc_setup_area(mp_state_mem_area_t *area, void *start, void *end) {
143
150
assert (area -> gc_pool_start >= area -> gc_finaliser_table_start + gc_finaliser_table_byte_len );
144
151
#endif
145
152
146
- // clear ATBs
147
- memset (area -> gc_alloc_table_start , 0 , area -> gc_alloc_table_byte_len );
148
-
149
153
#if MICROPY_ENABLE_FINALISER
150
- // clear FTBs
151
- memset (area -> gc_finaliser_table_start , 0 , gc_finaliser_table_byte_len );
154
+ // clear ATBs and FTBs
155
+ memset (area -> gc_alloc_table_start , 0 , gc_finaliser_table_byte_len + gc_alloc_table_byte_len + ALLOC_TABLE_GAP_BYTE );
156
+ #else
157
+ // clear ATBs
158
+ memset (area -> gc_alloc_table_start , 0 , area -> gc_alloc_table_byte_len + ALLOC_TABLE_GAP_BYTE );
152
159
#endif
153
160
154
161
area -> gc_last_free_atb_index = 0 ;
0 commit comments