Skip to content

Commit

Permalink
make copying iterative
Browse files Browse the repository at this point in the history
  • Loading branch information
Kirillog committed May 8, 2024
1 parent dec3195 commit fdc736b
Showing 1 changed file with 45 additions and 12 deletions.
57 changes: 45 additions & 12 deletions runtime/runtime.c
Original file line number Diff line number Diff line change
Expand Up @@ -621,6 +621,7 @@ typedef struct

static pool from_space; // From-space (active ) semi-heap
static pool to_space; // To-space (passive) semi-heap
size_t* next_unchecked;

const int WORD = sizeof(int);

Expand Down Expand Up @@ -698,9 +699,8 @@ size_t round_word(size_t num) {
return (num + WORD - 1) / WORD;
}

void gc_test_and_copy_root(size_t** root);

void *gc_copy(size_t *p) {
// p in from_space, return pointer in to_space
void *gc_copy_unchecked(size_t *p) {
data* obj = TO_DATA(p);
if (IS_FORWARD_PTR((size_t*)obj->tag)) {
return (void*)obj->tag;
Expand All @@ -712,23 +712,18 @@ void *gc_copy(size_t *p) {
size_t* pos = to_space.current + 1;
obj->tag = (int)pos;
to_space.current += 1 + len;
size_t* first = pos;
for (size_t* it = first; it < first + len; ++it) {
gc_test_and_copy_root((size_t**)it);
}
return pos;
}
case SEXP_TAG: {
sexp* s = TO_SEXP(p);
size_t len = LEN(obj->tag);
memcpy((void*)to_space.current, (void*)s, (len + 2) * WORD);
// Swap to distinguish SEXP on checked step
*(to_space.current + 1) = s->tag;
*(to_space.current) = obj->tag;
size_t* pos = to_space.current + 2;
obj->tag = (int)pos;
to_space.current += 2 + len;
size_t* first = pos;
for (size_t* it = first; it < first + len; ++it) {
gc_test_and_copy_root((size_t**)it);
}
return pos;
}
case STRING_TAG: {
Expand All @@ -747,7 +742,39 @@ void *gc_copy(size_t *p) {

void gc_test_and_copy_root(size_t **root) {
if (IS_VALID_HEAP_POINTER(*root)) {
*root = gc_copy(*root);
*root = gc_copy_unchecked(*root);
}
}

// p in to_space, return pointer to next object
size_t* gc_copy(size_t *p) {
// fprintf(stderr, "gc_copy on 0x%x\n", p);
data* obj = p;
size_t len = LEN(obj->tag);
switch(TAG(obj->tag)) {
case ARRAY_TAG: {
size_t* first = p + 1;
for (size_t* it = first; it < first + len; ++it) {
gc_test_and_copy_root(it);
}
return p + 1 + len;
}
case SEXP_TAG: {
// Swap back
size_t tag = *(p + 1);
*(p + 1) = obj->tag;
*p = tag;
size_t* first = p + 2;
for (size_t* it = first; it < first + len; ++it) {
gc_test_and_copy_root(it);
}
return p + 2 + len;
}
case STRING_TAG: {
return p + 1 + round_word(len);
}
default:
failure("gc copy: tag: 0x%x\n",TAG(obj->tag));
}
}

Expand All @@ -756,6 +783,7 @@ void gc_test_and_copy_root(size_t **root) {
// @size is a size of the block that @alloc failed to allocate
static void gc(size_t size) {
// fprintf(stderr, "gc called on %d\n", size);
next_unchecked = to_space.begin;
// Static data
for (size_t* i = (size_t*)&__gc_data_start; i < &__gc_data_end; i++) {
gc_test_and_copy_root((size_t**)i);
Expand All @@ -768,6 +796,11 @@ static void gc(size_t size) {
for (int i = 0; i < extra_roots.current_free; ++i) {
gc_test_and_copy_root((size_t**)extra_roots.roots[i]);
}

while (next_unchecked != to_space.current) {
next_unchecked = gc_copy(next_unchecked);
}

// Equal to avoid empty arrays and sexps (their content == space.end)
while (to_space.end - to_space.current <= size) {
extend_spaces();
Expand Down

0 comments on commit fdc736b

Please sign in to comment.