version 1.2, 2000/04/10 08:31:32 |
version 1.3, 2000/12/01 09:26:13 |
|
|
/* An incomplete test for the garbage collector. */ |
/* An incomplete test for the garbage collector. */ |
/* Some more obscure entry points are not tested at all. */ |
/* Some more obscure entry points are not tested at all. */ |
|
|
|
# undef GC_BUILD |
|
|
# if defined(mips) && defined(SYSTYPE_BSD43) |
# if defined(mips) && defined(SYSTYPE_BSD43) |
/* MIPS RISCOS 4 */ |
/* MIPS RISCOS 4 */ |
# else |
# else |
|
|
register sexpr r; |
register sexpr r; |
|
|
r = (sexpr) GC_MALLOC_UNCOLLECTABLE(sizeof(struct SEXPR)); |
r = (sexpr) GC_MALLOC_UNCOLLECTABLE(sizeof(struct SEXPR)); |
assert(GC_is_marked(r)); |
|
if (r == 0) { |
if (r == 0) { |
(void)GC_printf0("Out of memory\n"); |
(void)GC_printf0("Out of memory\n"); |
exit(1); |
exit(1); |
Line 157 assert(GC_is_marked(r)); |
|
Line 158 assert(GC_is_marked(r)); |
|
return(r); |
return(r); |
} |
} |
|
|
|
#ifdef GC_GCJ_SUPPORT |
|
|
|
#include "gc_mark.h" |
|
#include "dbg_mlc.h" |
|
#include "include/gc_gcj.h" |
|
|
|
/* The following struct emulates the vtable in gcj. */ |
|
/* This assumes the default value of MARK_DESCR_OFFSET. */ |
|
struct fake_vtable { |
|
void * dummy; /* class pointer in real gcj. */ |
|
size_t descr; |
|
}; |
|
|
|
struct fake_vtable gcj_class_struct1 = { 0, sizeof(struct SEXPR) |
|
+ sizeof(struct fake_vtable *) }; |
|
/* length based descriptor. */ |
|
struct fake_vtable gcj_class_struct2 = |
|
{ 0, (3l << (CPP_WORDSZ - 3)) | DS_BITMAP}; |
|
/* Bitmap based descriptor. */ |
|
|
|
struct ms_entry * fake_gcj_mark_proc(word * addr, |
|
struct ms_entry *mark_stack_ptr, |
|
struct ms_entry *mark_stack_limit, |
|
word env ) |
|
{ |
|
sexpr x; |
|
if (1 == env) { |
|
/* Object allocated with debug allocator. */ |
|
addr = (word *)USR_PTR_FROM_BASE(addr); |
|
} |
|
x = (sexpr)(addr + 1); /* Skip the vtable pointer. */ |
|
/* We could just call PUSH_CONTENTS directly here. But any real */ |
|
/* real client would try to filter out the obvious misses. */ |
|
if (0 != x -> sexpr_cdr) { |
|
PUSH_CONTENTS((ptr_t)(x -> sexpr_cdr), mark_stack_ptr, |
|
mark_stack_limit, &(x -> sexpr_cdr), exit1); |
|
} |
|
if ((ptr_t)(x -> sexpr_car) > GC_least_plausible_heap_addr) { |
|
PUSH_CONTENTS((ptr_t)(x -> sexpr_car), mark_stack_ptr, |
|
mark_stack_limit, &(x -> sexpr_car), exit2); |
|
} |
|
return(mark_stack_ptr); |
|
} |
|
|
|
sexpr gcj_cons(x, y) |
|
sexpr x; |
|
sexpr y; |
|
{ |
|
GC_word * r; |
|
sexpr result; |
|
static int count = 0; |
|
|
|
if (++count & 1) { |
|
r = (GC_word *) GC_GCJ_FAST_MALLOC(3, &gcj_class_struct1); |
|
} else { |
|
r = (GC_word *) GC_GCJ_MALLOC(sizeof(struct SEXPR) |
|
+ sizeof(struct fake_vtable*), |
|
&gcj_class_struct2); |
|
} |
|
if (r == 0) { |
|
(void)GC_printf0("Out of memory\n"); |
|
exit(1); |
|
} |
|
result = (sexpr)(r + 1); |
|
result -> sexpr_car = x; |
|
result -> sexpr_cdr = y; |
|
return(result); |
|
} |
|
#endif |
|
|
/* Return reverse(x) concatenated with y */ |
/* Return reverse(x) concatenated with y */ |
sexpr reverse1(x, y) |
sexpr reverse1(x, y) |
sexpr x, y; |
sexpr x, y; |
|
|
} |
} |
} |
} |
|
|
|
#ifdef GC_GCJ_SUPPORT |
|
/* Return reverse(x) concatenated with y */ |
|
sexpr gcj_reverse1(x, y) |
|
sexpr x, y; |
|
{ |
|
if (is_nil(x)) { |
|
return(y); |
|
} else { |
|
return( gcj_reverse1(cdr(x), gcj_cons(car(x), y)) ); |
|
} |
|
} |
|
|
|
sexpr gcj_reverse(x) |
|
sexpr x; |
|
{ |
|
return( gcj_reverse1(x, nil) ); |
|
} |
|
|
|
sexpr gcj_ints(low, up) |
|
int low, up; |
|
{ |
|
if (low > up) { |
|
return(nil); |
|
} else { |
|
return(gcj_cons(gcj_cons(INT_TO_SEXPR(low), nil), gcj_ints(low+1, up))); |
|
} |
|
} |
|
#endif /* GC_GCJ_SUPPORT */ |
|
|
/* To check uncollectable allocation we build lists with disguised cdr */ |
/* To check uncollectable allocation we build lists with disguised cdr */ |
/* pointers, and make sure they don't go away. */ |
/* pointers, and make sure they don't go away. */ |
sexpr uncollectable_ints(low, up) |
sexpr uncollectable_ints(low, up) |
Line 367 void reverse_test() |
|
Line 467 void reverse_test() |
|
g[799] = ints(1,18); |
g[799] = ints(1,18); |
h = (sexpr *)GC_MALLOC(1025 * sizeof(sexpr)); |
h = (sexpr *)GC_MALLOC(1025 * sizeof(sexpr)); |
h = (sexpr *)GC_REALLOC((GC_PTR)h, 2000 * sizeof(sexpr)); |
h = (sexpr *)GC_REALLOC((GC_PTR)h, 2000 * sizeof(sexpr)); |
h[1999] = ints(1,19); |
# ifdef GC_GCJ_SUPPORT |
|
h[1999] = gcj_ints(1,200); |
|
h[1999] = gcj_reverse(h[1999]); |
|
# else |
|
h[1999] = ints(1,200); |
|
# endif |
/* Try to force some collections and reuse of small list elements */ |
/* Try to force some collections and reuse of small list elements */ |
for (i = 0; i < 10; i++) { |
for (i = 0; i < 10; i++) { |
(void)ints(1, BIG); |
(void)ints(1, BIG); |
Line 412 void reverse_test() |
|
Line 517 void reverse_test() |
|
check_uncollectable_ints(d, 1, 100); |
check_uncollectable_ints(d, 1, 100); |
check_ints(f[5], 1,17); |
check_ints(f[5], 1,17); |
check_ints(g[799], 1,18); |
check_ints(g[799], 1,18); |
check_ints(h[1999], 1,19); |
# ifdef GC_GCJ_SUPPORT |
|
h[1999] = gcj_reverse(h[1999]); |
|
# endif |
|
check_ints(h[1999], 1,200); |
# ifndef THREADS |
# ifndef THREADS |
a = 0; |
a = 0; |
# endif |
# endif |
Line 759 void typed_test() |
|
Line 867 void typed_test() |
|
old = 0; |
old = 0; |
for (i = 0; i < 4000; i++) { |
for (i = 0; i < 4000; i++) { |
new = (GC_word *) GC_malloc_explicitly_typed(4 * sizeof(GC_word), d1); |
new = (GC_word *) GC_malloc_explicitly_typed(4 * sizeof(GC_word), d1); |
|
if (0 != new[0] || 0 != new[1]) { |
|
GC_printf0("Bad initialization by GC_malloc_explicitly_typed\n"); |
|
FAIL; |
|
} |
new[0] = 17; |
new[0] = 17; |
new[1] = (GC_word)old; |
new[1] = (GC_word)old; |
old = new; |
old = new; |
Line 782 void typed_test() |
|
Line 894 void typed_test() |
|
new = (GC_word *) GC_calloc_explicitly_typed(1001, |
new = (GC_word *) GC_calloc_explicitly_typed(1001, |
3 * sizeof(GC_word), |
3 * sizeof(GC_word), |
d2); |
d2); |
|
if (0 != new[0] || 0 != new[1]) { |
|
GC_printf0("Bad initialization by GC_malloc_explicitly_typed\n"); |
|
FAIL; |
|
} |
} |
} |
new[0] = 17; |
new[0] = 17; |
new[1] = (GC_word)old; |
new[1] = (GC_word)old; |
Line 906 void run_one_test() |
|
Line 1022 void run_one_test() |
|
/* Test floating point alignment */ |
/* Test floating point alignment */ |
*(double *)GC_MALLOC(sizeof(double)) = 1.0; |
*(double *)GC_MALLOC(sizeof(double)) = 1.0; |
*(double *)GC_MALLOC(sizeof(double)) = 1.0; |
*(double *)GC_MALLOC(sizeof(double)) = 1.0; |
|
# ifdef GC_GCJ_SUPPORT |
|
GC_REGISTER_DISPLACEMENT(sizeof(struct fake_vtable *)); |
|
GC_init_gcj_malloc(0, (void *)fake_gcj_mark_proc); |
|
# endif |
/* Repeated list reversal test. */ |
/* Repeated list reversal test. */ |
reverse_test(); |
reverse_test(); |
# ifdef PRINTSTATS |
# ifdef PRINTSTATS |
Line 1032 void SetMinimumStack(long minSize) |
|
Line 1152 void SetMinimumStack(long minSize) |
|
#if !defined(PCR) && !defined(SOLARIS_THREADS) && !defined(WIN32_THREADS) \ |
#if !defined(PCR) && !defined(SOLARIS_THREADS) && !defined(WIN32_THREADS) \ |
&& !defined(IRIX_THREADS) && !defined(LINUX_THREADS) \ |
&& !defined(IRIX_THREADS) && !defined(LINUX_THREADS) \ |
&& !defined(HPUX_THREADS) || defined(LINT) |
&& !defined(HPUX_THREADS) || defined(LINT) |
#ifdef MSWIN32 |
#if defined(MSWIN32) && !defined(__MINGW32__) |
int APIENTRY WinMain(HINSTANCE instance, HINSTANCE prev, LPSTR cmd, int n) |
int APIENTRY WinMain(HINSTANCE instance, HINSTANCE prev, LPSTR cmd, int n) |
#else |
#else |
int main() |
int main() |
Line 1114 int APIENTRY WinMain(HINSTANCE instance, HINSTANCE pre |
|
Line 1234 int APIENTRY WinMain(HINSTANCE instance, HINSTANCE pre |
|
# endif |
# endif |
InitializeCriticalSection(&incr_cs); |
InitializeCriticalSection(&incr_cs); |
(void) GC_set_warn_proc(warn_proc); |
(void) GC_set_warn_proc(warn_proc); |
for (i = 0; i < NTEST; i++) { |
# if NTEST > 0 |
|
for (i = 0; i < NTEST; i++) { |
h[i] = (HANDLE)_beginthreadex(NULL, 0, thr_run_one_test, 0, 0, &thread_id); |
h[i] = (HANDLE)_beginthreadex(NULL, 0, thr_run_one_test, 0, 0, &thread_id); |
if (h[i] == (HANDLE)-1) { |
if (h[i] == (HANDLE)-1) { |
(void)GC_printf1("Thread creation failed %lu\n", (unsigned long)GetLastError()); |
(void)GC_printf1("Thread creation failed %lu\n", (unsigned long)GetLastError()); |
FAIL; |
FAIL; |
} |
} |
} |
} |
|
# endif /* NTEST > 0 */ |
run_one_test(); |
run_one_test(); |
for (i = 0; i < NTEST; i++) |
# if NTEST > 0 |
|
for (i = 0; i < NTEST; i++) { |
if (WaitForSingleObject(h[i], INFINITE) != WAIT_OBJECT_0) { |
if (WaitForSingleObject(h[i], INFINITE) != WAIT_OBJECT_0) { |
(void)GC_printf1("Thread wait failed %lu\n", (unsigned long)GetLastError()); |
(void)GC_printf1("Thread wait failed %lu\n", (unsigned long)GetLastError()); |
FAIL; |
FAIL; |
} |
} |
|
} |
|
# endif /* NTEST > 0 */ |
check_heap_stats(); |
check_heap_stats(); |
(void)fflush(stdout); |
(void)fflush(stdout); |
return(0); |
return(0); |