166 lines
3.3 KiB
C
166 lines
3.3 KiB
C
#include <sys/time.h>
|
|
|
|
#include <inttypes.h>
|
|
#include <stdbool.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <time.h>
|
|
|
|
#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();
|
|
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: */
|