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;
+		}
 	}
 }