Skip to content

Commit eefcc79

Browse files
committed
Clear ATBs on gc_init; better gc_info.
1 parent 3f69aca commit eefcc79

2 files changed

Lines changed: 62 additions & 21 deletions

File tree

py/gc.c

Lines changed: 51 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ static machine_uint_t *gc_sp;
3333
void 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) {
192184
void 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

217234
void *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+
304334
int main() {
305335
machine_uint_t len = 1000;
306336
machine_uint_t *heap = malloc(len);

py/gc.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,14 @@ void gc_collect();
66
void *gc_alloc(machine_uint_t n_bytes);
77
machine_uint_t gc_nbytes(void *ptr_in);
88
void *gc_realloc(void *ptr, machine_uint_t n_bytes);
9+
10+
typedef struct _gc_info_t {
11+
machine_uint_t total;
12+
machine_uint_t used;
13+
machine_uint_t free;
14+
machine_uint_t num_1block;
15+
machine_uint_t num_2block;
16+
machine_uint_t max_block;
17+
} gc_info_t;
18+
19+
void gc_info(gc_info_t *info);

0 commit comments

Comments
 (0)