From 8b073cbd48427d9cb9794e8ec7679ed0c0b5c4c5 Mon Sep 17 00:00:00 2001 From: Egor Sheremetov Date: Wed, 27 Sep 2023 03:45:58 +0200 Subject: [PATCH] Fixed unit tests + fixed different compilation flags' combinations so that code compiles and works properly + added unit tests execution into a github actions workflow --- .github/workflows/blank.yml | 1 + Makefile | 8 +++ runtime/Makefile | 29 ++++++++--- runtime/TODO.md | 2 +- runtime/gc.c | 99 +++++++++++++++++++++---------------- runtime/gc.h | 24 +++++++-- runtime/runtime_common.h | 6 +-- runtime/test_main.c | 8 +-- 8 files changed, 116 insertions(+), 61 deletions(-) diff --git a/.github/workflows/blank.yml b/.github/workflows/blank.yml index 713d647c0..786b052b0 100644 --- a/.github/workflows/blank.yml +++ b/.github/workflows/blank.yml @@ -38,3 +38,4 @@ jobs: - run: eval $(opam env) - run: opam exec -- make - run: opam exec -- make regression-all + - run: opam exec -- make unit_tests diff --git a/Makefile b/Makefile index 1f523fab3..31cf4a107 100644 --- a/Makefile +++ b/Makefile @@ -9,6 +9,9 @@ all: $(MAKE) -C runtime $(MAKE) -C byterun $(MAKE) -C stdlib + $(MAKE) -C runtime unit_tests.o + $(MAKE) -C runtime invariants_check.o + $(MAKE) -C runtime invariants_check_debug_print.o STD_FILES=$(shell ls stdlib/*.[oi] stdlib/*.lama runtime/runtime.a runtime/Std.i) @@ -38,6 +41,11 @@ regression-lama-in-lama: all cp -R stdlib/* tmp-lama $(MAKE) -C lama-compiler +unit_tests: + ./runtime/unit_tests.o + ./runtime/invariants_check.o + ./runtime/invariants_check_debug_print.o + clean: $(MAKE) clean -C src $(MAKE) clean -C runtime diff --git a/runtime/Makefile b/runtime/Makefile index 68148f7e9..208355bc3 100644 --- a/runtime/Makefile +++ b/runtime/Makefile @@ -1,23 +1,38 @@ CC=gcc -FLAGS=-no-pie -m32 -g2 -fstack-protector-all -DLAMA_ENV +COMMON_FLAGS=-no-pie -m32 -g2 -fstack-protector-all +PROD_FLAGS=$(COMMON_FLAGS) -DLAMA_ENV +TEST_FLAGS=$(COMMON_FLAGS) -DDEBUG_VERSION +UNIT_TESTS_FLAGS=$(TEST_FLAGS) +INVARIANTS_CHECK_FLAGS=$(TEST_FLAGS) -DFULL_INVARIANT_CHECKS +# this target is the most important one, its' artefacts should be used as a runtime of Lama all: gc_runtime.o gc.o runtime.o ar rc runtime.a gc_runtime.o runtime.o gc.o -test.o: gc.c gc.h gc_runtime.s runtime.c runtime.h runtime_common.h virt_stack.c virt_stack.h test_main.c test_util.s - $(CC) -o test.o -DDEBUG_VERSION $(FLAGS) gc.c gc_runtime.s virt_stack.c ext_arr.c runtime.c test_main.c test_util.s +# this is a target that runs unit tests, scenarios are written in a single file `test_main.c` +unit_tests.o: gc.c gc.h gc_runtime.s runtime.c runtime.h runtime_common.h virt_stack.c virt_stack.h test_main.c test_util.s + $(CC) -o unit_tests.o $(UNIT_TESTS_FLAGS) gc.c gc_runtime.s virt_stack.c runtime.c test_main.c test_util.s + +# this target also runs unit tests but with additional expensive checks of GC invariants which aren't used in production version +invariants_check.o: gc.c gc.h gc_runtime.s runtime.c runtime.h runtime_common.h virt_stack.c virt_stack.h test_main.c test_util.s + $(CC) -o invariants_check.o $(INVARIANTS_CHECK_FLAGS) gc.c gc_runtime.s virt_stack.c runtime.c test_main.c test_util.s + +# this target also runs unit tests but with additional expensive checks of GC invariants which aren't used in production version +# additionally, it prints debug information +invariants_check_debug_print.o: gc.c gc.h gc_runtime.s runtime.c runtime.h runtime_common.h virt_stack.c virt_stack.h test_main.c test_util.s + $(CC) -o invariants_check_debug_print.o $(INVARIANTS_CHECK_FLAGS) -DDEBUG_PRINT gc.c gc_runtime.s virt_stack.c runtime.c test_main.c test_util.s virt_stack.o: virt_stack.h virt_stack.c - $(CC) $(FLAGS) -c virt_stack.c + $(CC) $(PROD_FLAGS) -c virt_stack.c gc.o: gc.c gc.h - $(CC) -rdynamic $(FLAGS) -c gc.c + $(CC) -rdynamic $(PROD_FLAGS) -c gc.c gc_runtime.o: gc_runtime.s - $(CC) $(FLAGS) -c gc_runtime.s + $(CC) $(PROD_FLAGS) -c gc_runtime.s runtime.o: runtime.c runtime.h - $(CC) $(FLAGS) -c runtime.c + $(CC) $(PROD_FLAGS) -c runtime.c clean: $(RM) *.a *.o *~ diff --git a/runtime/TODO.md b/runtime/TODO.md index 2c04a4a1d..d47c7327c 100644 --- a/runtime/TODO.md +++ b/runtime/TODO.md @@ -10,7 +10,7 @@ - [x] Fix warnings in ML code - [x] TODO: debug flag doesn't compile - [x] Sexp: move the tag to be `contents[0]` instead of the word in sexp header; i.e. get rid of sexp as separate data structure -- [ ] Run Lama compiler on Lama +- [x] Run Lama compiler on Lama - [ ] Add more stress tests (for graph-like structures) to `stdlib/regression` and unit tests - [ ] Magic constants - [ ] Normal documentation: a-la doxygen diff --git a/runtime/gc.c b/runtime/gc.c index a47343945..4c6c2fd63 100644 --- a/runtime/gc.c +++ b/runtime/gc.c @@ -16,7 +16,7 @@ static const size_t INIT_HEAP_SIZE = MINIMUM_HEAP_CAPACITY; -#ifdef FULL_INVARIANT_CHECKS +#ifdef DEBUG_VERSION size_t cur_id = 0; #endif @@ -49,12 +49,12 @@ void handler (int sig) { } void *alloc (size_t size) { -#ifdef FULL_INVARIANT_CHECKS +#ifdef DEBUG_VERSION ++cur_id; #endif size_t bytes_sz = size; size = BYTES_TO_WORDS(size); -#ifdef DEBUG_VERSION +#if defined(DEBUG_VERSION) && defined(DEBUG_PRINT) fprintf(stderr, "allocation of size %zu words (%zu bytes): ", size, bytes_sz); #endif void *p = gc_alloc_on_existing_heap(size); @@ -184,7 +184,7 @@ void *gc_alloc_on_existing_heap (size_t size) { } void *gc_alloc (size_t size) { -#ifdef DEBUG_VERSION +#if defined(DEBUG_VERSION) && defined(DEBUG_PRINT) fprintf(stderr, "===============================GC cycle has started\n"); #endif #ifdef FULL_INVARIANT_CHECKS @@ -217,32 +217,34 @@ void *gc_alloc (size_t size) { fclose(heap_before_compaction); fclose(heap_after_compaction); #endif -#ifdef DEBUG_VERSION +#if defined(DEBUG_VERSION) && defined(DEBUG_PRINT) fprintf(stderr, "===============================GC cycle has finished\n"); #endif return gc_alloc_on_existing_heap(size); } void mark_phase (void) { -#ifdef DEBUG_VERSION +#if defined(DEBUG_VERSION) && defined(DEBUG_PRINT) fprintf(stderr, "marking has started\n"); fprintf(stderr, "__gc_root_scan_stack has started: gc_top=%p bot=%p\n", - __gc_stack_top, - __gc_stack_bottom); + (void *)__gc_stack_top, + (void *)__gc_stack_bottom); #endif __gc_root_scan_stack(); -#ifdef DEBUG_VERSION +#if defined(DEBUG_VERSION) && defined(DEBUG_PRINT) fprintf(stderr, "__gc_root_scan_stack has finished\n"); fprintf(stderr, "scan_extra_roots has started\n"); #endif scan_extra_roots(); -#ifdef DEBUG_VERSION +#if defined(DEBUG_VERSION) && defined(DEBUG_PRINT) fprintf(stderr, "scan_extra_roots has finished\n"); fprintf(stderr, "scan_global_area has started\n"); #endif +#ifdef LAMA_ENV scan_global_area(); -#ifdef DEBUG_VERSION +#endif +#if defined(DEBUG_VERSION) && defined(DEBUG_PRINT) fprintf(stderr, "scan_global_area has finished\n"); fprintf(stderr, "marking has finished\n"); #endif @@ -254,8 +256,7 @@ void compact_phase (size_t additional_size) { // all in words size_t next_heap_size = MAX(live_size * EXTRA_ROOM_HEAP_COEFFICIENT + additional_size, MINIMUM_HEAP_CAPACITY); - size_t next_heap_pseudo_size = - MAX(next_heap_size, heap.size); // this is weird but here is why it happens: + size_t next_heap_pseudo_size = MAX(next_heap_size, heap.size); memory_chunk old_heap = heap; heap.begin = mremap( @@ -275,7 +276,7 @@ void compact_phase (size_t additional_size) { } size_t compute_locations () { -#ifdef DEBUG_VERSION +#if defined(DEBUG_VERSION) && defined(DEBUG_PRINT) fprintf(stderr, "GC compute_locations started\n"); #endif size_t *free_ptr = heap.begin; @@ -292,7 +293,7 @@ size_t compute_locations () { } } -#ifdef DEBUG_VERSION +#if defined(DEBUG_VERSION) && defined(DEBUG_PRINT) fprintf(stderr, "GC compute_locations finished\n"); #endif // it will return number of words @@ -300,7 +301,7 @@ size_t compute_locations () { } void scan_and_fix_region (memory_chunk *old_heap, void *start, void *end) { -#ifdef DEBUG_VERSION +#if defined(DEBUG_VERSION) && defined(DEBUG_PRINT) fprintf(stderr, "GC scan_and_fix_region started\n"); #endif for (size_t *ptr = (size_t *)start; ptr < (size_t *)end; ++ptr) { @@ -316,14 +317,14 @@ void scan_and_fix_region (memory_chunk *old_heap, void *start, void *end) { *(void **)ptr = new_addr + content_offset; } } -#ifdef DEBUG_VERSION +#if defined(DEBUG_VERSION) && defined(DEBUG_PRINT) fprintf(stderr, "GC scan_and_fix_region finished\n"); #endif } void scan_and_fix_region_roots (memory_chunk *old_heap) { -#ifdef DEBUG_VERSION - fprintf(stderr, "extra roots started: number os extra roots %i\n", extra_roots.current_free); +#if defined(DEBUG_VERSION) && defined(DEBUG_PRINT) + fprintf(stderr, "extra roots started: number of extra roots %i\n", extra_roots.current_free); #endif for (int i = 0; i < extra_roots.current_free; i++) { size_t *ptr = (size_t *)extra_roots.roots[i]; @@ -339,12 +340,14 @@ void scan_and_fix_region_roots (memory_chunk *old_heap) { ) { #ifdef DEBUG_VERSION if (is_valid_heap_pointer((size_t *)ptr_value)) { +# ifdef DEBUG_PRINT fprintf(stderr, "|\tskip extra root: %p (%p), since it points to Lama's stack top=%p bot=%p\n", extra_roots.roots[i], - ptr_value, - __gc_stack_top, - __gc_stack_bottom); + (void *)ptr_value, + (void *)__gc_stack_top, + (void *)__gc_stack_bottom); +# endif } # ifdef LAMA_ENV else if ((extra_roots.roots[i] <= (void *)&__stop_custom_data @@ -353,17 +356,19 @@ void scan_and_fix_region_roots (memory_chunk *old_heap) { stderr, "|\tskip extra root: %p (%p), since it points to Lama's static area stop=%p start=%p\n", extra_roots.roots[i], - ptr_value, + (void *)ptr_value, (void *)&__stop_custom_data, (void *)&__start_custom_data); exit(1); } # endif else { +# ifdef DEBUG_PRINT fprintf(stderr, "|\tskip extra root: %p (%p): not a valid Lama pointer \n", extra_roots.roots[i], - ptr_value); + (void *)ptr_value); +# endif } #endif continue; @@ -374,18 +379,22 @@ void scan_and_fix_region_roots (memory_chunk *old_heap) { (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; -#ifdef DEBUG_VERSION - fprintf(stderr, "|\textra root (%p) %p -> %p\n", extra_roots.roots[i], ptr_value, *ptr); +#if defined(DEBUG_VERSION) && defined(DEBUG_PRINT) + fprintf(stderr, + "|\textra root (%p) %p -> %p\n", + extra_roots.roots[i], + (void *)ptr_value, + (void *)*ptr); #endif } } -#ifdef DEBUG_VERSION +#if defined(DEBUG_VERSION) && defined(DEBUG_PRINT) fprintf(stderr, "|\textra roots finished\n"); #endif } void update_references (memory_chunk *old_heap) { -#ifdef DEBUG_VERSION +#if defined(DEBUG_VERSION) && defined(DEBUG_PRINT) fprintf(stderr, "GC update_references started\n"); #endif heap_iterator it = heap_begin_iterator(); @@ -410,9 +419,11 @@ void update_references (memory_chunk *old_heap) { size_t content_offset = get_header_size(get_type_row_ptr(field_obj_content_addr)); #ifdef DEBUG_VERSION if (!is_valid_heap_pointer((void *)(new_addr + content_offset))) { +# ifdef DEBUG_PRINT fprintf(stderr, "ur: incorrect pointer assignment: on object with id %d", TO_DATA(get_object_content_ptr(it.current))->id); +# endif exit(1); } #endif @@ -431,13 +442,13 @@ void update_references (memory_chunk *old_heap) { assert((void *)&__stop_custom_data >= (void *)&__start_custom_data); scan_and_fix_region(old_heap, (void *)&__start_custom_data, (void *)&__stop_custom_data); #endif -#ifdef DEBUG_VERSION +#if defined(DEBUG_VERSION) && defined(DEBUG_PRINT) fprintf(stderr, "GC update_references finished\n"); #endif } void physically_relocate (memory_chunk *old_heap) { -#ifdef DEBUG_VERSION +#if defined(DEBUG_VERSION) && defined(DEBUG_PRINT) fprintf(stderr, "GC physically_relocate started\n"); #endif heap_iterator from_iter = heap_begin_iterator(); @@ -455,7 +466,7 @@ void physically_relocate (memory_chunk *old_heap) { } from_iter = next_iter; } -#ifdef DEBUG_VERSION +#if defined(DEBUG_VERSION) && defined(DEBUG_PRINT) fprintf(stderr, "GC physically_relocate finished\n"); #endif } @@ -532,7 +543,7 @@ void scan_global_area (void) { #endif extern void gc_test_and_mark_root (size_t **root) { -#ifdef DEBUG_VERSION +#if defined(DEBUG_VERSION) && defined(DEBUG_PRINT) fprintf(stderr, "\troot = %p (%p), stack addresses: [%p, %p)\n", root, @@ -563,7 +574,7 @@ extern void __init (void) { extern void __shutdown (void) { munmap(heap.begin, heap.size); -#ifdef FULL_INVARIANT_CHECKS +#ifdef DEBUG_VERSION cur_id = 0; #endif heap.begin = NULL; @@ -600,7 +611,7 @@ void pop_extra_root (void **p) { /* Functions for tests */ -#if defined(FULL_INVARIANT_CHECKS) && defined(DEBUG_VERSION) +#if defined(DEBUG_VERSION) size_t objects_snapshot (int *object_ids_buf, size_t object_ids_buf_size) { size_t *ids_ptr = (size_t *)object_ids_buf; size_t i = 0; @@ -720,11 +731,12 @@ lama_type get_type_header_ptr (void *ptr) { case CLOSURE_TAG: return CLOSURE; case SEXP_TAG: return SEXP; default: { -#ifdef DEBUG_VERSION +#if defined(DEBUG_VERSION) && defined(DEBUG_PRINT) fprintf(stderr, "ERROR: get_type_header_ptr: unknown object header, cur_id=%d", cur_id); raise(SIGINT); // only for debug purposes #else # ifdef FULL_INVARIANT_CHECKS +# ifdef DEBUG_PRINT fprintf(stderr, "ERROR: get_type_header_ptr: unknown object header, ptr is %p, tag %i, heap size is " "%d cur_id=%d stack_top=%p stack_bot=%p ", @@ -734,6 +746,7 @@ lama_type get_type_header_ptr (void *ptr) { cur_id, (void *)__gc_stack_top, (void *)__gc_stack_bottom); +# endif FILE *heap_before_compaction = print_objects_traversal("dump_kill", 1); fclose(heap_before_compaction); # endif @@ -847,10 +860,10 @@ size_t get_header_size (lama_type type) { void *alloc_string (int len) { data *obj = alloc(string_size(len)); obj->data_header = STRING_TAG | (len << 3); -#ifdef DEBUG_VERSION +#if defined(DEBUG_VERSION) && defined(DEBUG_PRINT) fprintf(stderr, "%p, [STRING] tag=%zu\n", obj, TAG(obj->data_header)); #endif -#ifdef FULL_INVARIANT_CHECKS +#ifdef DEBUG_VERSION obj->id = cur_id; #endif obj->forward_address = 0; @@ -860,10 +873,10 @@ void *alloc_string (int len) { void *alloc_array (int len) { data *obj = alloc(array_size(len)); obj->data_header = ARRAY_TAG | (len << 3); -#ifdef DEBUG_VERSION +#if defined(DEBUG_VERSION) && defined(DEBUG_PRINT) fprintf(stderr, "%p, [ARRAY] tag=%zu\n", obj, TAG(obj->data_header)); #endif -#ifdef FULL_INVARIANT_CHECKS +#ifdef DEBUG_VERSION obj->id = cur_id; #endif obj->forward_address = 0; @@ -873,10 +886,10 @@ void *alloc_array (int len) { void *alloc_sexp (int members) { sexp *obj = alloc(sexp_size(members)); obj->data_header = SEXP_TAG | (members << 3); -#ifdef DEBUG_VERSION +#if defined(DEBUG_VERSION) && defined(DEBUG_PRINT) fprintf(stderr, "%p, SEXP tag=%zu\n", obj, TAG(obj->data_header)); #endif -#ifdef FULL_INVARIANT_CHECKS +#ifdef DEBUG_VERSION obj->id = cur_id; #endif obj->forward_address = 0; @@ -888,10 +901,10 @@ void *alloc_closure (int captured) { data *obj = alloc(closure_size(captured)); obj->data_header = CLOSURE_TAG | (captured << 3); -#ifdef DEBUG_VERSION +#if defined(DEBUG_VERSION) && defined(DEBUG_PRINT) fprintf(stderr, "%p, [CLOSURE] tag=%zu\n", obj, TAG(obj->data_header)); #endif -#ifdef FULL_INVARIANT_CHECKS +#ifdef DEBUG_VERSION obj->id = cur_id; #endif obj->forward_address = 0; diff --git a/runtime/gc.h b/runtime/gc.h index db765e2fc..8dd5e2e98 100644 --- a/runtime/gc.h +++ b/runtime/gc.h @@ -46,6 +46,7 @@ typedef struct { size_t size; } memory_chunk; + // the only GC-related function that should be exposed, others are useful for tests and internal implementation // allocates object of the given size on the heap void *alloc(size_t); @@ -72,6 +73,7 @@ size_t compute_locations (); void update_references (memory_chunk *); void physically_relocate (memory_chunk *); + // ============================================================================ // GC extra roots // ============================================================================ @@ -92,26 +94,31 @@ void clear_extra_roots (void); void push_extra_root (void **p); void pop_extra_root (void **p); + // ============================================================================ // Implemented in GASM: see gc_runtime.s // ============================================================================ // MANDATORY TO CALL BEFORE ANY INTERACTION WITH GC (apart from cases where we // are working with virtual stack as happens in tests) extern void __gc_init (void); + // should be called before interaction with GC in case of using in tests with // virtual stack, otherwise it is automatically invoked by `__gc_init` extern void __init (void); + // mostly useful for tests but basically you want to call this in case you want // to deallocate all object allocated via GC extern void __shutdown (void); + // Next two functions sets and unsets `__gc_stack_top` // The first (`__pre_gc`) should be called in the very beginning of any runtime // function during the execution of which garbage collection can be initiated. // The last one is a `companion function` which has to be called at the very -// end of any function that called `__prec_gc` +// end of any function that previously called `__pre_gc` extern void __pre_gc (void); extern void __post_gc (void); + // ============================================================================ // invoked from GASM: see gc_runtime.s // ============================================================================ @@ -119,10 +126,11 @@ extern void gc_test_and_mark_root (size_t **root); bool is_valid_heap_pointer (const size_t *); static inline bool is_valid_pointer (const size_t *); + // ============================================================================ // Auxiliary functions for tests // ============================================================================ -#if defined(FULL_INVARIANT_CHECKS) && defined(DEBUG_VERSION) +#if defined(DEBUG_VERSION) // makes a snapshot of current objects in heap (both alive and dead), writes these ids to object_ids_buf, // returns number of ids dumped // object_ids_buf is pointer to area preallocated by user for dumping ids of objects in heap @@ -130,6 +138,7 @@ static inline bool is_valid_pointer (const size_t *); size_t objects_snapshot (int *object_ids_buf, size_t object_ids_buf_size); #endif + #ifdef DEBUG_VERSION // essential function to mock program stack void set_stack (size_t stack_top, size_t stack_bottom); @@ -138,6 +147,7 @@ void set_stack (size_t stack_top, size_t stack_bottom); void set_extra_roots (size_t extra_roots_size, void **extra_roots_ptr); #endif + // ============================================================================ // Utility functions // ============================================================================ @@ -186,13 +196,16 @@ size_t obj_size_header_ptr (void *ptr); // returns total padding size that we need to store given object type size_t get_header_size (lama_type type); + // returns number of bytes that are required to allocate array with 'sz' elements (header included) size_t array_size (size_t sz); + // returns number of bytes that are required to allocate string of length 'l' (header included) size_t string_size (size_t len); -// TODO: ask if it is actually so? number of captured elements is actually sz-1 and 1 extra word is code ptr? + // returns number of bytes that are required to allocate closure with 'sz-1' captured values (header included) size_t closure_size (size_t sz); + // returns number of bytes that are required to allocate s-expression with 'members' fields (header included) size_t sexp_size (size_t members); @@ -200,16 +213,21 @@ size_t sexp_size (size_t members); // (in case of s-exp, it is mandatory that obj ptr is very beginning of the object, // considering that now we store two versions of header in there) obj_field_iterator field_begin_iterator (void *obj); + // returns an iterator over object fields which are actual pointers, obj is ptr to object header // (in case of s-exp, it is mandatory that obj ptr is very beginning of the object, // considering that now we store two versions of header in there) obj_field_iterator ptr_field_begin_iterator (void *obj); + // moves the iterator to next object field void obj_next_field_iterator (obj_field_iterator *it); + // moves the iterator to the next object field which is an actual pointer void obj_next_ptr_field_iterator (obj_field_iterator *it); + // returns if we are done iterating over fields of the object bool field_is_done_iterator (obj_field_iterator *it); + // ptr is pointer to the actual object content, returns pointer to the very beginning of the object (header) void *get_obj_header_ptr (void *ptr); void *get_object_content_ptr (void *header_ptr); diff --git a/runtime/runtime_common.h b/runtime/runtime_common.h index a386719e0..9dd25e89b 100644 --- a/runtime/runtime_common.h +++ b/runtime/runtime_common.h @@ -17,7 +17,7 @@ #define SEXP_ONLY_HEADER_SZ (sizeof(int)) -#ifndef FULL_INVARIANT_CHECKS +#ifndef DEBUG_VERSION # define DATA_HEADER_SZ (sizeof(size_t) + sizeof(int)) #else # define DATA_HEADER_SZ (sizeof(size_t) + sizeof(size_t) + sizeof(int)) @@ -44,7 +44,7 @@ typedef struct { // other utility info (i.e., size for array, number of fields for s-expression) int data_header; -#ifdef FULL_INVARIANT_CHECKS +#ifdef DEBUG_VERSION size_t id; #endif @@ -59,7 +59,7 @@ typedef struct { // other utility info (i.e., size for array, number of fields for s-expression) int data_header; -#ifdef FULL_INVARIANT_CHECKS +#ifdef DEBUG_VERSION size_t id; #endif diff --git a/runtime/test_main.c b/runtime/test_main.c index bd3f8312d..8e88aaac8 100644 --- a/runtime/test_main.c +++ b/runtime/test_main.c @@ -22,15 +22,15 @@ void test_correct_structure_sizes (void) { // something like induction base assert((array_size(0) == get_header_size(ARRAY))); assert((string_size(0) == get_header_size(STRING) + 1)); // +1 is because of '\0' - assert((sexp_size(0) == get_header_size(SEXP))); + assert((sexp_size(0) == get_header_size(SEXP) + MEMBER_SIZE)); assert((closure_size(0) == get_header_size(CLOSURE))); // just check correctness for some small sizes for (int k = 1; k < 20; ++k) { - assert((array_size(k) == get_header_size(ARRAY) + sizeof(int) * k)); + assert((array_size(k) == get_header_size(ARRAY) + MEMBER_SIZE * k)); assert((string_size(k) == get_header_size(STRING) + k + 1)); - assert((sexp_size(k) == get_header_size(SEXP) + sizeof(int) * k)); - assert((closure_size(k) == get_header_size(CLOSURE) + sizeof(int) * k)); + assert((sexp_size(k) == get_header_size(SEXP) + MEMBER_SIZE * (k + 1))); + assert((closure_size(k) == get_header_size(CLOSURE) + MEMBER_SIZE * k)); } }