#include #include #include #include #include #include #include #include "gc.h" void out_of_memory(void) { fprintf(stderr, "Out of memory!\n"); abort(); } static void print_value(value_t v); static inline void comma(void) { fputs(", ", stdout); } static inline void nl(void) { putchar('\n'); } int main(int argc, char **argv) { gc_root_t list_root, tmp_root; int count = 0; gc_init(1024, 256*1024*1024); srand((unsigned int)time(NULL)); register_gc_root(&list_root, NIL); register_gc_root(&tmp_root, NIL); tmp_root.value = cons(make_fixnum(1), cons(make_fixnum(2), NIL)); list_root.value = make_weak_box(tmp_root.value); register_finalizer(tmp_root.value, make_fixnum(10)); print_value(list_root.value); comma(); { value_t v, f; get_next_finalizer(&v, &f); print_value(v); comma(); print_value(f); nl(); nl(); } collect_garbage(0); print_value(list_root.value); comma(); { value_t v, f; get_next_finalizer(&v, &f); print_value(v); comma(); print_value(f); nl(); nl(); } tmp_root.value = NIL; print_value(list_root.value); comma(); { value_t v, f; get_next_finalizer(&v, &f); print_value(v); comma(); print_value(f); nl(); nl(); } collect_garbage(0); print_value(list_root.value); comma(); { value_t v, f; get_next_finalizer(&v, &f); print_value(v); comma(); print_value(f); nl(); nl(); } #if 0 while (1) { int r = rand() & 0x3fff; if (r == 0) list_root.value = make_fixnum(rand()); else { switch (r & 7) { case 0: list_root.value = cons(make_fixnum(rand()), list_root.value); break; case 1: list_root.value = cons(list_root.value, make_byte_string(256, '\0')); break; case 2: list_root.value = make_box(list_root.value); break; case 3: list_root.value = cons(list_root.value, cons(make_fixnum(-1), NIL)); get_pair(get_pair(list_root.value)->cdr)->cdr = list_root.value; break; case 4: case 5: case 6: case 7: { value_t s = make_struct(NIL, 5); _get_struct(s)->slots[1+(r & 3)] = list_root.value; list_root.value = s; } break; } } if (++count >= 10000000) { const double total_time = gc_stats.total_ticks / (double)CLOCKS_PER_SEC; fprintf(stderr, "%0.3f sec / %d GCs => %0.3f usec/GC; peak was %u bytes.\n", total_time, gc_stats.collections, (1000000 * total_time) / gc_stats.collections, gc_stats.high_water); gc_stats.collections = 0; gc_stats.total_ticks = 0; gc_stats.high_water = 0; count = 0; break; } } #endif unregister_gc_root(&list_root); return 0; } static void print_value(value_t v) { if (v == NIL) { fputs("nil", stdout); } else if (v == FALSE_VALUE) { fputs("#f", stdout); } else if (v == TRUE_VALUE) { fputs("#t", stdout); } else if (is_fixnum(v)) { printf("%d", (int)get_fixnum(v)); } else if (is_box(v)) { fputs("#&", stdout); print_value(_get_box(v)->value); } else if (is_pair(v)) { putchar('('); print_value(_get_pair(v)->car); v = _get_pair(v)->cdr; while (is_pair(v)) { putchar(' '); print_value(_get_pair(v)->car); v = _get_pair(v)->cdr; } if (v != NIL) { fputs(" . ", stdout); print_value(v); } putchar(')'); } else if (is_vector(v)) { fputs("#(", stdout); for (size_t i = 0; i < _get_vector(v)->size; ++i) { if (i != 0) putchar(' '); print_value(_get_vector(v)->elements[i]); } putchar(')'); } else if (is_byte_string(v)) { fputs("#B(", stdout); for (size_t i = 0; i < _get_byte_string(v)->size; ++i) { if (i != 0) putchar(' '); printf("%d", (int)_get_byte_string(v)->bytes[i]); } putchar(')'); } else if (is_struct(v)) { fputs("#S(", stdout); for (size_t i = 0; i < _get_struct(v)->nslots; ++i) { if (i != 0) putchar(' '); print_value(_get_struct(v)->slots[i]); } putchar(')'); } else if (is_weak_box(v)) { fputs("#W&", stdout); print_value(_get_weak_box(v)->value); } else { fputs("#", stdout); } } /* vim:set sw=2 expandtab: */