@@ -33,6 +33,8 @@ static machine_uint_t *gc_sp;
3333void gc_init (void * start , void * end ) {
3434 // align end pointer on block boundary
3535 end = (void * )((machine_uint_t )end & (~(BYTES_PER_BLOCK - 1 )));
36+
37+ // calculate parameters for GC
3638 machine_uint_t total_word_len = (machine_uint_t * )end - (machine_uint_t * )start ;
3739 gc_alloc_table_byte_len = total_word_len * BYTES_PER_WORD / (1 + BITS_PER_BYTE / 2 * BYTES_PER_BLOCK );
3840 gc_alloc_table_start = (byte * )start ;
@@ -42,6 +44,9 @@ void gc_init(void *start, void *end) {
4244 gc_pool_start = (machine_uint_t * )end - gc_pool_word_len ;
4345 gc_pool_end = end ;
4446
47+ // clear ATBs
48+ memset (gc_alloc_table_start , 0 , gc_alloc_table_byte_len );
49+
4550 /*
4651 printf("GC layout:\n");
4752 printf(" alloc table at %p, length %u bytes\n", gc_alloc_table_start, gc_alloc_table_byte_len);
@@ -80,19 +85,6 @@ void gc_init(void *start, void *end) {
8085#define ATB_HEAD_TO_MARK (block ) do { gc_alloc_table_start[(block) / BLOCKS_PER_ATB] |= (AT_MARK << BLOCK_SHIFT(block)); } while (0)
8186#define ATB_MARK_TO_HEAD (block ) do { gc_alloc_table_start[(block) / BLOCKS_PER_ATB] &= (~(AT_TAIL << BLOCK_SHIFT(block))); } while (0)
8287
83- void gc_dump_at () {
84- for (machine_uint_t bl = 0 ; bl < gc_alloc_table_byte_len * BLOCKS_PER_ATB ; bl ++ ) {
85- printf ("block % 6u " , bl );
86- switch (ATB_GET_KIND (bl )) {
87- case AT_FREE : printf ("FREE" ); break ;
88- case AT_HEAD : printf ("HEAD" ); break ;
89- case AT_TAIL : printf ("TAIL" ); break ;
90- default : printf ("MARK" ); break ;
91- }
92- printf ("\n" );
93- }
94- }
95-
9688#define BLOCK_FROM_PTR (ptr ) (((ptr) - (machine_uint_t)gc_pool_start) / BYTES_PER_BLOCK)
9789#define PTR_FROM_BLOCK (block ) (((block) * BYTES_PER_BLOCK + (machine_uint_t)gc_pool_start))
9890#define ATB_FROM_BLOCK (bl ) ((bl) / BLOCKS_PER_ATB)
@@ -122,7 +114,7 @@ static void gc_drain_stack() {
122114 // pop the next block off the stack
123115 machine_uint_t block = * -- gc_sp ;
124116
125- // work out number of consecutive blocks in the chain starting with this on
117+ // work out number of consecutive blocks in the chain starting with this one
126118 machine_uint_t n_blocks = 0 ;
127119 do {
128120 n_blocks += 1 ;
@@ -192,26 +184,51 @@ void gc_collect_root(void **ptrs, machine_uint_t len) {
192184void gc_collect_end () {
193185 gc_deal_with_stack_overflow ();
194186 gc_sweep ();
187+ }
195188
196- machine_uint_t n_free = 0 ;
197- machine_uint_t n_used = 0 ;
198- for (machine_uint_t block = 0 ; block < gc_alloc_table_byte_len * BLOCKS_PER_ATB ; block ++ ) {
199- switch (ATB_GET_KIND (block )) {
189+ void gc_info (gc_info_t * info ) {
190+ info -> total = (gc_pool_end - gc_pool_start ) * sizeof (machine_uint_t );
191+ info -> used = 0 ;
192+ info -> free = 0 ;
193+ info -> num_1block = 0 ;
194+ info -> num_2block = 0 ;
195+ info -> max_block = 0 ;
196+ for (machine_uint_t block = 0 , len = 0 ; block < gc_alloc_table_byte_len * BLOCKS_PER_ATB ; block ++ ) {
197+ machine_uint_t kind = ATB_GET_KIND (block );
198+ if (kind == AT_FREE || kind == AT_HEAD ) {
199+ if (len == 1 ) {
200+ info -> num_1block += 1 ;
201+ } else if (len == 2 ) {
202+ info -> num_2block += 1 ;
203+ }
204+ if (len > info -> max_block ) {
205+ info -> max_block = len ;
206+ }
207+ }
208+ switch (kind ) {
200209 case AT_FREE :
201- n_free += 1 ;
210+ info -> free += 1 ;
211+ len = 0 ;
202212 break ;
203213
204214 case AT_HEAD :
215+ info -> used += 1 ;
216+ len = 1 ;
217+ break ;
218+
205219 case AT_TAIL :
206- n_used += 1 ;
220+ info -> used += 1 ;
221+ len += 1 ;
207222 break ;
208223
209224 case AT_MARK :
225+ // shouldn't happen
210226 break ;
211227 }
212228 }
213229
214- printf ("GC %u/%u\n" , n_used * BYTES_PER_BLOCK , (n_free + n_used ) * BYTES_PER_BLOCK );
230+ info -> used *= BYTES_PER_BLOCK ;
231+ info -> free *= BYTES_PER_BLOCK ;
215232}
216233
217234void * gc_alloc (machine_uint_t n_bytes ) {
@@ -301,6 +318,19 @@ void *gc_realloc(void *ptr, machine_uint_t n_bytes) {
301318}
302319
303320/*
321+ static void gc_dump_at() {
322+ for (machine_uint_t bl = 0; bl < gc_alloc_table_byte_len * BLOCKS_PER_ATB; bl++) {
323+ printf("block % 6u ", bl);
324+ switch (ATB_GET_KIND(bl)) {
325+ case AT_FREE: printf("FREE"); break;
326+ case AT_HEAD: printf("HEAD"); break;
327+ case AT_TAIL: printf("TAIL"); break;
328+ default: printf("MARK"); break;
329+ }
330+ printf("\n");
331+ }
332+ }
333+
304334int main() {
305335 machine_uint_t len = 1000;
306336 machine_uint_t *heap = malloc(len);
0 commit comments