This commit is contained in:
Danya Berezun 2023-06-29 20:05:54 +02:00
parent 144db5d677
commit 8bc173762d
3 changed files with 93 additions and 60 deletions

View file

@ -73,17 +73,18 @@ static void print_object_info(FILE *f, void *obj_content) {
fprintf(f, "id %zu tag %zu | ", obj_id, obj_tag); fprintf(f, "id %zu tag %zu | ", obj_id, obj_tag);
} }
static void print_unboxed (FILE *f, int unboxed) { static void print_unboxed (FILE *f, int unboxed) { fprintf(f, "unboxed %zu | ", unboxed); }
fprintf(f, "unboxed %zu | ", unboxed);
}
static FILE *print_stack_content (char *filename) { static FILE *print_stack_content (char *filename) {
FILE *f = fopen(filename, "w+"); FILE *f = fopen(filename, "w+");
ftruncate(fileno(f), 0); ftruncate(fileno(f), 0);
fprintf(f, "Stack content:\n"); fprintf(f, "Stack content:\n");
for (size_t *stack_ptr = (size_t *) ((void*)__gc_stack_top + 4); stack_ptr < (size_t *) __gc_stack_bottom; ++stack_ptr) { for (size_t *stack_ptr = (size_t *)((void *)__gc_stack_top + 4);
stack_ptr < (size_t *)__gc_stack_bottom;
++stack_ptr) {
size_t value = *stack_ptr; size_t value = *stack_ptr;
if (is_valid_heap_pointer((size_t *)value)) { if (is_valid_heap_pointer((size_t *)value)) {
fprintf(f, "%p, ", (void *)value);
print_object_info(f, (void *)value); print_object_info(f, (void *)value);
} else { } else {
print_unboxed(f, (int)value); print_unboxed(f, (int)value);
@ -99,9 +100,7 @@ static void objects_dfs (FILE *f, void *obj_content) {
void *obj_header = get_obj_header_ptr(obj_content); void *obj_header = get_obj_header_ptr(obj_content);
data *obj_data = TO_DATA(obj_content); data *obj_data = TO_DATA(obj_content);
// internal mark-bit for this dfs, should be recovered by the caller // internal mark-bit for this dfs, should be recovered by the caller
if ((obj_data->forward_address & 2) != 0) { if ((obj_data->forward_address & 2) != 0) { return; }
return;
}
// set this bit as 1 // set this bit as 1
obj_data->forward_address |= 2; obj_data->forward_address |= 2;
fprintf(f, "object at addr %p: ", obj_content); fprintf(f, "object at addr %p: ", obj_content);
@ -124,17 +123,14 @@ static void objects_dfs (FILE *f, void *obj_content) {
!field_is_done_iterator(&field_it); !field_is_done_iterator(&field_it);
obj_next_field_iterator(&field_it)) { obj_next_field_iterator(&field_it)) {
size_t field_value = *(size_t *)field_it.cur_field; size_t field_value = *(size_t *)field_it.cur_field;
if (is_valid_heap_pointer((size_t *) field_value)) { if (is_valid_heap_pointer((size_t *)field_value)) { objects_dfs(f, (void *)field_value); }
objects_dfs(f, (void*) field_value);
}
} }
} }
FILE *print_objects_traversal (char *filename, bool marked) { FILE *print_objects_traversal (char *filename, bool marked) {
FILE *f = fopen(filename, "w+"); FILE *f = fopen(filename, "w+");
ftruncate(fileno(f), 0); ftruncate(fileno(f), 0);
for (heap_iterator it = heap_begin_iterator(); for (heap_iterator it = heap_begin_iterator(); !heap_is_done_iterator(&it);
!heap_is_done_iterator(&it);
heap_next_obj_iterator(&it)) { heap_next_obj_iterator(&it)) {
void *obj_header = it.current; void *obj_header = it.current;
data *obj_data = TO_DATA(get_object_content_ptr(obj_header)); data *obj_data = TO_DATA(get_object_content_ptr(obj_header));
@ -144,14 +140,19 @@ FILE *print_objects_traversal(char *filename, bool marked) {
} }
// resetting bit that represent mark-bit for this internal dfs-traversal // resetting bit that represent mark-bit for this internal dfs-traversal
for (heap_iterator it = heap_begin_iterator(); for (heap_iterator it = heap_begin_iterator(); !heap_is_done_iterator(&it);
!heap_is_done_iterator(&it);
heap_next_obj_iterator(&it)) { heap_next_obj_iterator(&it)) {
void *obj_header = it.current; void *obj_header = it.current;
data *obj_data = TO_DATA(get_object_content_ptr(obj_header)); data *obj_data = TO_DATA(get_object_content_ptr(obj_header));
obj_data->forward_address &= (~2); obj_data->forward_address &= (~2);
} }
fflush(f); fflush(f);
// print extra roots
for (int i = 0; i < extra_roots.current_free; i++) {
fprintf(f, "extra root %p %p: ", extra_roots.roots[i], *(size_t **)extra_roots.roots[i]);
}
fflush(f);
return f; return f;
} }
@ -161,12 +162,8 @@ int files_cmp(FILE *f1, FILE *f2) {
while (true) { while (true) {
symbol1 = fgetc(f1); symbol1 = fgetc(f1);
symbol2 = fgetc(f2); symbol2 = fgetc(f2);
if (symbol1 == EOF && symbol2 == EOF) { if (symbol1 == EOF && symbol2 == EOF) { return -1; }
return -1; if (symbol1 != symbol2) { return position; }
}
if (symbol1 != symbol2) {
return position;
}
++position; ++position;
} }
} }
@ -185,16 +182,19 @@ void *gc_alloc_on_existing_heap (size_t size) {
void *gc_alloc (size_t size) { void *gc_alloc (size_t size) {
fprintf(stderr, "GC cycle has started\n"); fprintf(stderr, "GC cycle has started\n");
#ifdef FULL_INVARIANT_CHECKS // #ifdef FULL_INVARIANT_CHECKS
FILE *stack_before = print_stack_content("stack-dump-before-compaction"); FILE *stack_before = print_stack_content("stack-dump-before-compaction");
#endif FILE *heap_before = print_objects_traversal("before-mark", 0);
fclose(heap_before);
fclose(stack_before);
// #endif
mark_phase(); mark_phase();
#ifdef FULL_INVARIANT_CHECKS // #ifdef FULL_INVARIANT_CHECKS
FILE *heap_before_compaction = print_objects_traversal("after-mark", 1); FILE *heap_before_compaction = print_objects_traversal("after-mark", 1);
#endif // #endif
compact_phase(size); compact_phase(size);
#ifdef FULL_INVARIANT_CHECKS // #ifdef FULL_INVARIANT_CHECKS
FILE *stack_after = print_stack_content("stack-dump-after-compaction"); FILE *stack_after = print_stack_content("stack-dump-after-compaction");
FILE *heap_after_compaction = print_objects_traversal("after-compaction", 0); FILE *heap_after_compaction = print_objects_traversal("after-compaction", 0);
@ -211,7 +211,7 @@ void *gc_alloc (size_t size) {
fclose(heap_before_compaction); fclose(heap_before_compaction);
fclose(heap_after_compaction); fclose(heap_after_compaction);
#endif // #endif
fprintf(stderr, "GC cycle has finished\n"); fprintf(stderr, "GC cycle has finished\n");
return gc_alloc_on_existing_heap(size); return gc_alloc_on_existing_heap(size);
} }
@ -308,6 +308,24 @@ void scan_and_fix_region (memory_chunk *old_heap, void *start, void *end) {
fprintf(stderr, "GC scan_and_fix_region finished\n"); fprintf(stderr, "GC scan_and_fix_region finished\n");
} }
void scan_and_fix_region_roots (memory_chunk *old_heap) {
fprintf(stderr, "extra roots started %i\n", extra_roots.current_free);
for (int i = 0; i < extra_roots.current_free; i++) {
size_t *ptr = extra_roots.roots[i];
size_t ptr_value = *ptr;
if (is_valid_pointer((size_t *)ptr_value) && (size_t)old_heap->begin <= ptr_value
&& ptr_value <= (size_t)old_heap->current) {
void *obj_ptr = (void *)heap.begin + ((void *)ptr_value - (void *)old_heap->begin);
void *new_addr =
(void *)heap.begin + ((void *)get_forward_address(obj_ptr) - (void *)old_heap->begin);
size_t content_offset = get_header_size(get_type_row_ptr(obj_ptr));
*(void **)ptr = new_addr + content_offset;
fprintf(stderr, "extra root %p -> %p\n", ptr_value, *ptr);
}
}
fprintf(stderr, "extra roots finished\n");
}
void update_references (memory_chunk *old_heap) { void update_references (memory_chunk *old_heap) {
fprintf(stderr, "GC update_references started\n"); fprintf(stderr, "GC update_references started\n");
heap_iterator it = heap_begin_iterator(); heap_iterator it = heap_begin_iterator();
@ -347,8 +365,7 @@ void update_references (memory_chunk *old_heap) {
scan_and_fix_region(old_heap, (void *)__gc_stack_top + 4, (void *)__gc_stack_bottom); scan_and_fix_region(old_heap, (void *)__gc_stack_top + 4, (void *)__gc_stack_bottom);
// fix pointers from extra_roots // fix pointers from extra_roots
scan_and_fix_region( scan_and_fix_region_roots(old_heap);
old_heap, (void *)extra_roots.roots, (size_t *)extra_roots.roots + extra_roots.current_free);
#ifndef DEBUG_VERSION #ifndef DEBUG_VERSION
// fix pointers from static area // fix pointers from static area
@ -450,12 +467,22 @@ void scan_global_area (void) {
#endif #endif
extern void gc_test_and_mark_root (size_t **root) { extern void gc_test_and_mark_root (size_t **root) {
fprintf(stderr, "stack addresses: [%p, %p)\n", (void*)__gc_stack_top + 4, (void*)__gc_stack_bottom); fprintf(
stderr, "stack addresses: [%p, %p)\n", (void *)__gc_stack_top + 4, (void *)__gc_stack_bottom);
if (is_valid_pointer(*root) && !is_valid_heap_pointer(*root)) { if (is_valid_pointer(*root) && !is_valid_heap_pointer(*root)) {
fprintf(stderr, "Found weird pointer on the stack by address %p, value is %p (stack starts at %p, ends at %p)\n", root, *root, (void*)__gc_stack_top + 4, (void*)__gc_stack_bottom); fprintf(stderr,
"Found weird pointer on the stack by address %p, value is %p (stack starts at %p, ends "
"at %p)\n",
root,
*root,
(void *)__gc_stack_top + 4,
(void *)__gc_stack_bottom);
} else { } else {
if (is_valid_pointer(*root)) { if (is_valid_pointer(*root)) {
fprintf(stderr, "Object that is supposed to be on the heap on the stack by address %p, value is %p\n", root, *root); fprintf(stderr,
"Object that is supposed to be on the heap on the stack by address %p, value is %p\n",
root,
*root);
} else { } else {
fprintf(stderr, "Value on the stack by address %p, value is %d\n", root, UNBOX(*root)); fprintf(stderr, "Value on the stack by address %p, value is %d\n", root, UNBOX(*root));
} }
@ -648,6 +675,10 @@ lama_type get_type_header_ptr (void *ptr) {
ptr, ptr,
TAG(*header), TAG(*header),
heap.size); heap.size);
FILE *heap_before_compaction = print_objects_traversal("dump_kill", 1);
close(heap_before_compaction);
kill(getpid(), SIGSEGV);
#endif #endif
exit(1); exit(1);
} }
@ -778,6 +809,7 @@ void *alloc_sexp (int members) {
} }
void *alloc_closure (int captured) { void *alloc_closure (int captured) {
data *obj = alloc(closure_size(captured)); data *obj = alloc(closure_size(captured));
obj->data_header = CLOSURE_TAG | (captured << 3); obj->data_header = CLOSURE_TAG | (captured << 3);
#ifdef FULL_INVARIANT_CHECKS #ifdef FULL_INVARIANT_CHECKS

View file

@ -18,7 +18,7 @@
#ifdef DEBUG_VERSION #ifdef DEBUG_VERSION
# define MINIMUM_HEAP_CAPACITY (8) # define MINIMUM_HEAP_CAPACITY (8)
#else #else
# define MINIMUM_HEAP_CAPACITY (1 << 10) # define MINIMUM_HEAP_CAPACITY (1 << 2)
#endif #endif
#include <stdbool.h> #include <stdbool.h>

View file

@ -890,10 +890,10 @@ extern void *Bclosure (int bn, void *entry, ...) {
fflush(stdout); fflush(stdout);
#endif #endif
argss = (ebp + 12); argss = (ebp + 12);
for (i = 0; i < n; i++, argss++) { push_extra_root((void **)argss); } // for (i = 0; i < n; i++, argss++) { push_extra_root((void **)argss); }
r = (data *)alloc_closure(n + 1); r = (data *)alloc_closure(n + 1);
// push_extra_root(&r);
((void **)r->contents)[0] = entry; ((void **)r->contents)[0] = entry;
va_start(args, entry); va_start(args, entry);
@ -907,8 +907,9 @@ extern void *Bclosure (int bn, void *entry, ...) {
__post_gc(); __post_gc();
// pop_extra_root(&r);
argss--; argss--;
for (i = 0; i < n; i++, argss--) { pop_extra_root((void **)argss); } //for (i = 0; i < n; i++, argss--) { pop_extra_root((void **)argss); }
#ifdef DEBUG_PRINT #ifdef DEBUG_PRINT
print_indent(); print_indent();
@ -1019,8 +1020,7 @@ extern int Btag (void *d, int t, int n) {
return BOX(TAG(r->data_header) == SEXP_TAG && TO_SEXP(d)->tag == UNBOX(t) return BOX(TAG(r->data_header) == SEXP_TAG && TO_SEXP(d)->tag == UNBOX(t)
&& LEN(r->data_header) == UNBOX(n)); && LEN(r->data_header) == UNBOX(n));
#else #else
return BOX(TAG(r->data_header) == SEXP_TAG return BOX(TAG(r->data_header) == SEXP_TAG && GET_SEXP_TAG(TO_SEXP(d)->data_header) == UNBOX(t)
&& GET_SEXP_TAG(TO_SEXP(d)->data_header) == UNBOX(t)
&& LEN(r->data_header) == UNBOX(n)); && LEN(r->data_header) == UNBOX(n));
#endif #endif
} }
@ -1407,6 +1407,7 @@ extern void set_args (int argc, char *argv[]) {
__post_gc(); __post_gc();
global_sysargs = p; global_sysargs = p;
push_extra_root((void **)&global_sysargs); push_extra_root((void **)&global_sysargs);
#ifdef DEBUG_PRINT #ifdef DEBUG_PRINT
print_indent(); print_indent();