diff --git a/ldb/gc.c b/ldb/gc.c index 338908c4611768809df1f1d03e6abedd16addc01..77107bb6ee952841e3a411c3d1402df98e3f1c94 100644 --- a/ldb/gc.c +++ b/ldb/gc.c @@ -1,7 +1,7 @@ /* * Stop and Copy GC based on Cheney's algorithm. * - * $Header: /Volumes/share2/src/cmucl/cvs2git/cvsroot/src/ldb/Attic/gc.c,v 1.7 1990/05/24 18:04:14 ch Exp $ + * $Header: /Volumes/share2/src/cmucl/cvs2git/cvsroot/src/ldb/Attic/gc.c,v 1.8 1990/06/04 01:30:47 ch Exp $ * * Written by Christopher Hoover. */ @@ -12,6 +12,7 @@ #include <signal.h> #include "lisp.h" #include "ldb.h" +#include "os.h" #include "gc.h" #include "globals.h" #include "interrupt.h" @@ -134,24 +135,25 @@ collect_garbage() struct timeval start_tv, stop_tv; struct rusage start_rusage, stop_rusage; double real_time, system_time, user_time; + double percent_retained, gc_rate; lispobj *current_static_space_free_pointer; - long static_space_size; - long control_stack_size, binding_stack_size; - long size_retained, size_discarded; + unsigned long static_space_size; + unsigned long control_stack_size, binding_stack_size; + unsigned long size_retained, size_discarded; int oldmask; + printf("[Collecting garbage ... \n"); + getrusage(RUSAGE_SELF, &start_rusage); gettimeofday(&start_tv, (struct timezone *) 0); - printf("[Collecting garbage ... \n"); - oldmask = sigblock(BLOCKABLE); current_static_space_free_pointer = (lispobj *) SymbolValue(STATIC_SPACE_FREE_POINTER); - /* Set up from space and new space pointers */ + /* Set up from space and new space pointers. */ from_space = current_dynamic_space; from_space_free_pointer = current_dynamic_space_free_pointer; @@ -165,7 +167,6 @@ collect_garbage() gc_lose(); } - os_validate(new_space, DYNAMIC_SPACE_SIZE); new_space_free_pointer = new_space; @@ -173,7 +174,7 @@ collect_garbage() weak_pointers = (struct weak_pointer *) NULL; - /* Scavenge the roots. */ + /* Scavenge all of the roots. */ printf("Scavenging interrupt contexts ...\n"); scavenge_interrupt_contexts(); @@ -197,52 +198,207 @@ collect_garbage() static_space_size * sizeof(lispobj)); scavenge(static_space, static_space_size); + + /* Scavenge newspace. */ printf("Scavenging new space (%d bytes) ...\n", (new_space_free_pointer - new_space) * sizeof(lispobj)); scavenge_newspace(); + #if defined(DEBUG_PRINT_GARBAGE) print_garbage(from_space, from_space_free_pointer); #endif + /* Scan the weak pointers. */ printf("Scanning weak pointers ...\n"); scan_weak_pointers(); - /* Flip spaces */ - os_invalidate(current_dynamic_space, DYNAMIC_SPACE_SIZE); + + /* Flip spaces. */ + printf("Flipping spaces ...\n"); + + os_zero((os_vm_address_t) current_dynamic_space, + (os_vm_size_t) DYNAMIC_SPACE_SIZE); + current_dynamic_space = new_space; current_dynamic_space_free_pointer = new_space_free_pointer; size_discarded = (from_space_free_pointer - from_space) * sizeof(lispobj); size_retained = (new_space_free_pointer - new_space) * sizeof(lispobj); - /* Zero stack */ + + /* Flush the icache. */ + printf("Flushing instruction cache ...\n"); + os_flush_icache((os_vm_address_t) new_space, + (os_vm_size_t) size_retained); + + + /* Zero stack. */ printf("Zeroing empty part of control stack ...\n"); - os_zero(current_control_stack_pointer, - CONTROL_STACK_SIZE - control_stack_size * sizeof(lispobj)); + os_zero((os_vm_address_t) current_control_stack_pointer, + (os_vm_size_t) (CONTROL_STACK_SIZE - + control_stack_size * sizeof(lispobj))); (void) sigsetmask(oldmask); + + gettimeofday(&stop_tv, (struct timezone *) 0); + getrusage(RUSAGE_SELF, &stop_rusage); + printf("done.]\n"); + + percent_retained = (((float) size_retained) / + ((float) size_discarded)) * 100.0; + printf("Total of %d bytes out of %d bytes retained (%3.2f%%).\n", - size_retained, size_discarded, - (((float) size_retained) / ((float) size_discarded)) * 100.0); + size_retained, size_discarded, percent_retained); + + real_time = tv_diff(&stop_tv, &start_tv); + user_time = tv_diff(&stop_rusage.ru_utime, &start_rusage.ru_utime); + system_time = tv_diff(&stop_rusage.ru_stime, &start_rusage.ru_stime); + + printf("Statistics:\n"); + printf("%10.2f sec of real time\n", real_time); + printf("%10.2f sec of user time,\n", user_time); + printf("%10.2f sec of system time.\n", system_time); + + gc_rate = ((float) size_retained / (float) (1<<20)) / real_time; + + printf("%10.2f M bytes/sec collected.\n", gc_rate); +} + + +/* Purify */ + +/* First attempt at a purify. */ + +purify() +{ + struct timeval start_tv, stop_tv; + struct rusage start_rusage, stop_rusage; + double real_time, system_time, user_time; + double percent_retained, gc_rate; + lispobj *current_static_space_free_pointer; + unsigned long control_stack_size, binding_stack_size; + unsigned long size_retained, size_discarded; + int oldmask; + + printf("[Purifying ... \n"); + + getrusage(RUSAGE_SELF, &start_rusage); + gettimeofday(&start_tv, (struct timezone *) 0); + + oldmask = sigblock(BLOCKABLE); + + current_static_space_free_pointer = + (lispobj *) SymbolValue(STATIC_SPACE_FREE_POINTER); + + /* Set up from space and new space pointers. */ + + from_space = current_dynamic_space; + from_space_free_pointer = current_dynamic_space_free_pointer; + + new_space = static_space; + new_space_free_pointer = current_static_space_free_pointer; + + + /* Initialize the weak pointer list. */ + weak_pointers = (struct weak_pointer *) NULL; + + + /* Scavenge all of the roots. */ + printf("Scavenging interrupt contexts ...\n"); + scavenge_interrupt_contexts(); + + printf("Scavenging interrupt handlers (%d bytes) ...\n", + sizeof(interrupt_handlers)); + scavenge((lispobj *) interrupt_handlers, + sizeof(interrupt_handlers) / sizeof(lispobj)); + + control_stack_size = current_control_stack_pointer - control_stack; + printf("Scavenging the control stack (%d bytes) ...\n", + control_stack_size * sizeof(lispobj)); + scavenge(control_stack, control_stack_size); + + binding_stack_size = current_binding_stack_pointer - binding_stack; + printf("Scavenging the binding stack (%d bytes) ...\n", + binding_stack_size * sizeof(lispobj)); + scavenge(binding_stack, binding_stack_size); + + + /* Scavenge newspace. */ + printf("Scavenging new (static) space (%d bytes) ...\n", + (new_space_free_pointer - new_space) * sizeof(lispobj)); + scavenge_newspace(); + + +#if defined(DEBUG_PRINT_GARBAGE) + print_garbage(from_space, from_space_free_pointer); +#endif + + /* Scan the weak pointers. */ + printf("Scanning weak pointers ...\n"); + scan_weak_pointers(); + + + /* Save the static space free pointer. */ + SetSymbolValue(STATIC_SPACE_FREE_POINTER, + (lispobj) new_space_free_pointer); + + /* Flip spaces. */ + printf("Flipping spaces (sort of) ...\n"); + + os_zero((os_vm_address_t) current_dynamic_space, + (os_vm_size_t) DYNAMIC_SPACE_SIZE); + + current_dynamic_space_free_pointer = current_dynamic_space; + + size_discarded = (from_space_free_pointer - from_space) * sizeof(lispobj); + size_retained = (new_space_free_pointer - new_space) * sizeof(lispobj); + + + /* Flush the icache. */ + printf("Flushing instruction cache ...\n"); + os_flush_icache((os_vm_address_t) new_space, + (os_vm_size_t) size_retained); + + + /* Zero stack. */ + printf("Zeroing empty part of control stack ...\n"); + os_zero((os_vm_address_t) current_control_stack_pointer, + (os_vm_size_t) (CONTROL_STACK_SIZE - + control_stack_size * sizeof(lispobj))); + + + + (void) sigsetmask(oldmask); + gettimeofday(&stop_tv, (struct timezone *) 0); getrusage(RUSAGE_SELF, &stop_rusage); + printf("done.]\n"); + + + percent_retained = (((float) size_retained) / + ((float) size_discarded)) * 100.0; + + printf("Total of %d bytes out of %d bytes retained (%3.2f%%).\n", + size_retained, size_discarded, percent_retained); + real_time = tv_diff(&stop_tv, &start_tv); user_time = tv_diff(&stop_rusage.ru_utime, &start_rusage.ru_utime); system_time = tv_diff(&stop_rusage.ru_stime, &start_rusage.ru_stime); printf("Statistics:\n"); - printf("%10.2f msec of real time\n", real_time * 1000.0); - printf("%10.2f msec of user time,\n", user_time * 1000.0); - printf("%10.2f msec of system time.\n", system_time * 1000.0); + printf("%10.2f sec of real time\n", real_time); + printf("%10.2f sec of user time,\n", user_time); + printf("%10.2f sec of system time.\n", system_time); + + gc_rate = ((float) size_retained / (float) (1<<20)) / real_time; - printf("%10.2f M bytes/sec collected.\n", - (((float) size_retained / (float) (1<<20)) / real_time)); + printf("%10.2f M bytes/sec collected.\n", gc_rate); } @@ -1530,10 +1686,6 @@ scan_weak_pointers() printf("Value: 0x%08x\n", (unsigned long) value); #endif - /* ### May want to make it an error to make a weak */ - /* pointer to a non-pointer since it doesn't make any */ - /* sense to do it. But for now, if it happens, don't */ - /* lose big -- just go on. */ if (!(Pointerp(value) && from_space_p(value))) continue; @@ -1541,6 +1693,7 @@ scan_weak_pointers() /* forwarded. If it has been, the weak pointer is */ /* still good and needs to be updated. Otherwise, the */ /* weak pointer needs to be nil'ed out. */ + first_pointer = (lispobj *) PTR(value); first = *first_pointer; @@ -1550,8 +1703,10 @@ scan_weak_pointers() if (Pointerp(first) && new_space_p(first)) wp->value = first; - else + else { wp->value = NIL; + wp->broken = T; + } } }