#include #include #include #include #include #include #include #include "gc.h" #include "builtin.h" #include "interp.h" #include "reader.h" static void test_builtins(void); static void test_weak_boxes_and_wills(void); static void test_garbage_collection(bool keep_going); static void test_reader(void); static inline void comma(void) { fputs(", ", stdout); } static inline void nl(void) { putchar('\n'); } void out_of_memory(void) { fprintf(stderr, "Out of memory!\n\n"); print_gc_stats(); abort(); } int main(int argc, char **argv) { srand((unsigned int)time(NULL)); gc_init(1024, 256*1024*1024); builtin_init(); interpreter_init(); test_builtins(); test_weak_boxes_and_wills(); if (argc > 1) test_reader(); test_garbage_collection(argc > 1); return 0; } static void test_builtins(void) { print_value(lookup_builtin(BI_STRUCTURE)); nl(); nl(); print_value(lookup_builtin(BI_TEMPLATE)); nl(); nl(); print_value(lookup_builtin(BI_LAMBDA)); nl(); nl(); } static void print_weak_box_results(value_t box) { value_t v, f; print_value(box); comma(); get_next_finalizer(&v, &f); print_value(v); comma(); print_value(f); nl(); } static void test_weak_boxes_and_wills(void) { gc_root_t box_root, tmp_root; register_gc_root(&box_root, UNDEFINED); register_gc_root(&tmp_root, UNDEFINED); tmp_root.value = cons(fixnum_value(1), cons(fixnum_value(2), NIL)); box_root.value = make_weak_box(tmp_root.value); register_finalizer(tmp_root.value, fixnum_value(10)); print_weak_box_results(box_root.value); collect_garbage(0); print_weak_box_results(box_root.value); tmp_root.value = UNDEFINED; print_weak_box_results(box_root.value); collect_garbage(0); print_weak_box_results(box_root.value); collect_garbage(0); print_weak_box_results(box_root.value); nl(); unregister_gc_root(&box_root); unregister_gc_root(&tmp_root); } static void test_garbage_collection(bool keep_going) { gc_root_t root; int count = 0; register_gc_root(&root, NIL); while (1) { int r = rand() & 0xffff; if (r == 0) root.value = fixnum_value(rand()); else { switch (r & 7) { case 0: root.value = cons(fixnum_value(rand()), root.value); break; case 1: root.value = cons(root.value, make_byte_string(256, '\0')); break; case 2: root.value = make_box(root.value); break; case 3: root.value = cons(root.value, cons(fixnum_value(-1), NIL)); get_pair(get_pair(root.value)->cdr)->cdr = root.value; break; case 4: case 5: case 6: case 7: { value_t s = make_vector(4, FALSE_VALUE); _get_vector(s)->elements[r & 3] = root.value; root.value = s; } break; } } if (++count >= 50000000) { nl(); print_gc_stats(); gc_stats.collections = 0; gc_stats.total_ns = 0; gc_stats.total_freed = 0; gc_stats.high_water = 0; gc_stats.max_ns = 0; count = 0; if (!keep_going) break; } } unregister_gc_root(&root); } static void test_reader(void) { value_t v; do { v = read_value(stdin); print_value(v); nl(); nl(); } while (v != NIL); } /* vim:set sw=2 expandtab: */