mirror of
https://github.com/ProgramSnail/Lama.git
synced 2025-12-05 22:38:44 +00:00
Added extra debug output in debug mode and added one more check of invariants
This commit is contained in:
parent
1a2342c411
commit
144db5d677
2 changed files with 36 additions and 15 deletions
49
runtime/gc.c
49
runtime/gc.c
|
|
@ -74,10 +74,12 @@ static void print_object_info(FILE *f, void *obj_content) {
|
|||
}
|
||||
|
||||
static void print_unboxed (FILE *f, int unboxed) {
|
||||
fprintf(f, "unboxed %d | ", UNBOX(unboxed));
|
||||
fprintf(f, "unboxed %zu | ", unboxed);
|
||||
}
|
||||
|
||||
static void print_stack_content (FILE *f) {
|
||||
static FILE *print_stack_content (char *filename) {
|
||||
FILE *f = fopen(filename, "w+");
|
||||
ftruncate(fileno(f), 0);
|
||||
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) {
|
||||
size_t value = *stack_ptr;
|
||||
|
|
@ -88,6 +90,8 @@ static void print_stack_content (FILE *f) {
|
|||
}
|
||||
fprintf(f, "\n");
|
||||
}
|
||||
fprintf(f, "Stack content end.\n");
|
||||
return f;
|
||||
}
|
||||
|
||||
// precondition: obj_content is a valid address pointing to the content of an object
|
||||
|
|
@ -154,7 +158,6 @@ FILE *print_objects_traversal(char *filename, bool marked) {
|
|||
int files_cmp(FILE *f1, FILE *f2) {
|
||||
int symbol1, symbol2;
|
||||
int position = 0;
|
||||
|
||||
while (true) {
|
||||
symbol1 = fgetc(f1);
|
||||
symbol2 = fgetc(f2);
|
||||
|
|
@ -183,7 +186,7 @@ void *gc_alloc_on_existing_heap (size_t size) {
|
|||
void *gc_alloc (size_t size) {
|
||||
fprintf(stderr, "GC cycle has started\n");
|
||||
#ifdef FULL_INVARIANT_CHECKS
|
||||
print_objects_traversal("before-mark", 0);
|
||||
FILE *stack_before = print_stack_content("stack-dump-before-compaction");
|
||||
#endif
|
||||
mark_phase();
|
||||
#ifdef FULL_INVARIANT_CHECKS
|
||||
|
|
@ -192,9 +195,15 @@ void *gc_alloc (size_t size) {
|
|||
|
||||
compact_phase(size);
|
||||
#ifdef FULL_INVARIANT_CHECKS
|
||||
FILE *stack_after = print_stack_content("stack-dump-after-compaction");
|
||||
FILE *heap_after_compaction = print_objects_traversal("after-compaction", 0);
|
||||
|
||||
int pos = files_cmp(heap_before_compaction, heap_after_compaction);
|
||||
int pos = files_cmp(stack_before, stack_after);
|
||||
if (pos >= 0) { // position of difference is found
|
||||
fprintf(stderr, "Stack is modified incorrectly, see position %d\n", pos);
|
||||
exit(1);
|
||||
}
|
||||
pos = files_cmp(heap_before_compaction, heap_after_compaction);
|
||||
if (pos >= 0) { // position of difference is found
|
||||
fprintf(stderr, "GC invariant is broken, pos is %d\n", pos);
|
||||
exit(1);
|
||||
|
|
@ -208,14 +217,13 @@ void *gc_alloc (size_t size) {
|
|||
}
|
||||
|
||||
void mark_phase (void) {
|
||||
#ifdef FULL_INVARIANT_CHECKS
|
||||
print_stack_content(stderr);
|
||||
#endif
|
||||
fprintf(stderr, "marking has started\n");
|
||||
__gc_root_scan_stack();
|
||||
scan_extra_roots();
|
||||
#ifndef DEBUG_VERSION
|
||||
scan_global_area();
|
||||
#endif
|
||||
fprintf(stderr, "marking has finished\n");
|
||||
}
|
||||
|
||||
void compact_phase (size_t additional_size) {
|
||||
|
|
@ -393,6 +401,7 @@ static inline void *queue_dequeue (heap_iterator *head_iter) {
|
|||
}
|
||||
|
||||
void mark (void *obj) {
|
||||
// fprintf(stderr, "Marking object with content address %p on the heap\n", obj);
|
||||
if (!is_valid_heap_pointer(obj) || is_marked(obj)) { return; }
|
||||
|
||||
// TL;DR: [q_head_iter, q_tail_iter) q_head_iter -- current dequeue's victim, q_tail_iter -- place for next enqueue
|
||||
|
|
@ -440,7 +449,19 @@ void scan_global_area (void) {
|
|||
}
|
||||
#endif
|
||||
|
||||
extern void gc_test_and_mark_root (size_t **root) { mark((void *)*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);
|
||||
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);
|
||||
} else {
|
||||
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);
|
||||
} else {
|
||||
fprintf(stderr, "Value on the stack by address %p, value is %d\n", root, UNBOX(*root));
|
||||
}
|
||||
}
|
||||
mark((void *)*root);
|
||||
}
|
||||
|
||||
extern void __init (void) {
|
||||
signal(SIGSEGV, handler);
|
||||
|
|
@ -477,7 +498,7 @@ void clear_extra_roots (void) { extra_roots.current_free = 0; }
|
|||
|
||||
void push_extra_root (void **p) {
|
||||
if (extra_roots.current_free >= MAX_EXTRA_ROOTS_NUMBER) {
|
||||
perror("ERROR: push_extra_roots: extra_roots_pool overflow");
|
||||
perror("ERROR: push_extra_roots: extra_roots_pool overflow\n");
|
||||
exit(1);
|
||||
}
|
||||
extra_roots.roots[extra_roots.current_free] = p;
|
||||
|
|
@ -486,12 +507,12 @@ void push_extra_root (void **p) {
|
|||
|
||||
void pop_extra_root (void **p) {
|
||||
if (extra_roots.current_free == 0) {
|
||||
perror("ERROR: pop_extra_root: extra_roots are empty");
|
||||
perror("ERROR: pop_extra_root: extra_roots are empty\n");
|
||||
exit(1);
|
||||
}
|
||||
extra_roots.current_free--;
|
||||
if (extra_roots.roots[extra_roots.current_free] != p) {
|
||||
perror("ERROR: pop_extra_root: stack invariant violation");
|
||||
perror("ERROR: pop_extra_root: stack invariant violation\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
|
@ -650,7 +671,7 @@ size_t obj_size_header_ptr (void *ptr) {
|
|||
fprintf(stderr, "ERROR: obj_size_header_ptr: unknown object header, cur_id=%d", cur_id);
|
||||
raise(SIGINT); // only for debug purposes
|
||||
#else
|
||||
perror("ERROR: obj_size_header_ptr: unknown object header");
|
||||
perror("ERROR: obj_size_header_ptr: unknown object header\n");
|
||||
#endif
|
||||
exit(1);
|
||||
}
|
||||
|
|
@ -717,7 +738,7 @@ size_t get_header_size (lama_type type) {
|
|||
case CLOSURE:
|
||||
case ARRAY: return DATA_HEADER_SZ;
|
||||
case SEXP: return SEXP_ONLY_HEADER_SZ + DATA_HEADER_SZ;
|
||||
default: perror("ERROR: get_header_size: unknown object type");
|
||||
default: perror("ERROR: get_header_size: unknown object type\n");
|
||||
#ifdef DEBUG_VERSION
|
||||
raise(SIGINT); // only for debug purposes
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@
|
|||
#ifdef DEBUG_VERSION
|
||||
# define MINIMUM_HEAP_CAPACITY (8)
|
||||
#else
|
||||
# define MINIMUM_HEAP_CAPACITY (1 << 5)
|
||||
# define MINIMUM_HEAP_CAPACITY (1 << 10)
|
||||
#endif
|
||||
|
||||
#include <stdbool.h>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue