diff --git a/lisp/Darwin-os.c b/lisp/Darwin-os.c
index d3c2d9cd0c09129ded0319da445946f02883ba21..452519f1719a7a8fca95e526cc7a0bc255ac7fd8 100644
--- a/lisp/Darwin-os.c
+++ b/lisp/Darwin-os.c
@@ -14,7 +14,7 @@
  * Frobbed for OpenBSD by Pierre R. Mai, 2001.
  * Frobbed for Darwin by Pierre R. Mai, 2003.
  *
- * $Header: /Volumes/share2/src/cmucl/cvs2git/cvsroot/src/lisp/Darwin-os.c,v 1.18 2008/09/11 00:15:28 rtoy Exp $
+ * $Header: /Volumes/share2/src/cmucl/cvs2git/cvsroot/src/lisp/Darwin-os.c,v 1.19 2008/09/16 08:52:31 cshapiro Exp $
  *
  */
 
@@ -371,7 +371,6 @@ sigbus_handler(HANDLER_ARGS)
 {
 #if defined(GENCGC)
     caddr_t fault_addr = code->si_addr;
-    int page_index = find_page_index((void *) fault_addr);
 #endif
     
 #ifdef __ppc__
@@ -390,30 +389,13 @@ sigbus_handler(HANDLER_ARGS)
     fprintf(stderr, "Signal %d, fault_addr=%x, page_index=%d:\n",
 	    signal, fault_addr, page_index);
 #endif
-    
-    /* Check if the fault is within the dynamic space. */
-    if (page_index != -1) {
-	/* Un-protect the page */
-
-	/* The page should have been marked write protected */
-	if (!PAGE_WRITE_PROTECTED(page_index))
-	    fprintf(stderr,
-		    "*** Sigsegv in page not marked as write protected\n");
-
-	os_protect(page_address(page_index), PAGE_SIZE, OS_VM_PROT_ALL);
-	page_table[page_index].flags &= ~PAGE_WRITE_PROTECTED_MASK;
-	page_table[page_index].flags |= PAGE_WRITE_PROTECT_CLEARED_MASK;
-    } else {
-	/* a *real* protection fault */
-	fprintf(stderr, "segv_handler: Real protection violation: %p\n", fault_addr);
-	interrupt_handle_now(signal, code, context);
-    }
+    if (gc_write_barrier(code->si_addr))
+	 return;
 #else
-
-    if (!interrupt_maybe_gc(signal, code, context)) {
-	interrupt_handle_now(signal, code, context);
-    }
+    if (interrupt_maybe_gc(signal, code, context))
+	return;
 #endif
+    interrupt_handle_now(signal, code, context);
 #ifdef __ppc__
     /* Work around G5 bug; fix courtesy gbyers via chandler */
     sigreturn(context);
diff --git a/lisp/FreeBSD-os.c b/lisp/FreeBSD-os.c
index 12f12b3654b8dabbd28683b4f53fedc44e221aa5..d5b1e88470f82165384c604ba7d266cc06758d53 100644
--- a/lisp/FreeBSD-os.c
+++ b/lisp/FreeBSD-os.c
@@ -12,7 +12,7 @@
  * Much hacked by Paul Werkowski
  * GENCGC support by Douglas Crosher, 1996, 1997.
  *
- * $Header: /Volumes/share2/src/cmucl/cvs2git/cvsroot/src/lisp/FreeBSD-os.c,v 1.23 2008/03/18 09:22:55 cshapiro Exp $
+ * $Header: /Volumes/share2/src/cmucl/cvs2git/cvsroot/src/lisp/FreeBSD-os.c,v 1.24 2008/09/16 08:52:31 cshapiro Exp $
  *
  */
 
@@ -201,8 +201,6 @@ boolean valid_addr(os_vm_address_t addr)
 static void
 sigbus_handler(int signal, siginfo_t *info, ucontext_t *context)
 {
-    int page_index;
-
 #ifdef RED_ZONE_HIT
     if (os_control_stack_overflow(info->si_addr, context))
 	return;
@@ -210,21 +208,7 @@ sigbus_handler(int signal, siginfo_t *info, ucontext_t *context)
 
 #if defined GENCGC
     if (info->si_code == PROTECTION_VIOLATION_CODE) {
-	page_index = find_page_index(info->si_addr);
-
-	/* Check if the fault is within the dynamic space. */
-	if (page_index != -1) {
-	    /* Un-protect the page */
-
-	    /* The page should have been marked write protected */
-	    if (!PAGE_WRITE_PROTECTED(page_index))
-		fprintf(stderr,
-			"*** Sigbus in page not marked as write protected\n");
-
-	    os_protect(page_address(page_index), 4096, OS_VM_PROT_ALL);
-	    page_table[page_index].flags &= ~PAGE_WRITE_PROTECTED_MASK;
-	    page_table[page_index].flags |= PAGE_WRITE_PROTECT_CLEARED_MASK;
-
+	if (gc_write_barrier(info->si_addr)) {
 	    return;
 	}
     }
diff --git a/lisp/Linux-os.c b/lisp/Linux-os.c
index 19792b4d4778e406a1cdf3d12e1b2246056fe2a8..10ff1e655438994a6345d2be643ecf793ae8dddd 100644
--- a/lisp/Linux-os.c
+++ b/lisp/Linux-os.c
@@ -15,7 +15,7 @@
  * GENCGC support by Douglas Crosher, 1996, 1997.
  * Alpha support by Julian Dolby, 1999.
  *
- * $Header: /Volumes/share2/src/cmucl/cvs2git/cvsroot/src/lisp/Linux-os.c,v 1.37 2008/01/03 11:41:54 cshapiro Exp $
+ * $Header: /Volumes/share2/src/cmucl/cvs2git/cvsroot/src/lisp/Linux-os.c,v 1.38 2008/09/16 08:52:31 cshapiro Exp $
  *
  */
 
@@ -280,27 +280,13 @@ void
 sigsegv_handler(HANDLER_ARGS)
 {
     int fault_addr = context->uc_mcontext.cr2;
-    int page_index = find_page_index((void *) fault_addr);
 
 #ifdef RED_ZONE_HIT
     if (os_control_stack_overflow((void *) fault_addr, context))
 	return;
 #endif
-
-    /* check if the fault is within the dynamic space. */
-    if (page_index != -1) {
-	/* Un-protect the page */
-
-	/* The page should have been marked write protected */
-	if (!PAGE_WRITE_PROTECTED(page_index))
-	    fprintf(stderr,
-		    "*** Sigsegv in page not marked as write protected\n");
-	os_protect(page_address(page_index), 4096, OS_VM_PROT_ALL);
-	page_table[page_index].flags &= ~PAGE_WRITE_PROTECTED_MASK;
-	page_table[page_index].flags |= PAGE_WRITE_PROTECT_CLEARED_MASK;
-
+    if (gc_write_barrier(code->si_addr))
 	return;
-    }
 #if defined(__x86_64)
     DPRINTF(0, (stderr, "sigsegv: rip: %p\n", context->uc_mcontext.gregs[REG_RIP]));
 #else
diff --git a/lisp/NetBSD-os.c b/lisp/NetBSD-os.c
index 07546ee5f27566c7a96e5183877ed5baa82d8f01..90c1dae76fc413f38936c8959b2bcae48cd31867 100644
--- a/lisp/NetBSD-os.c
+++ b/lisp/NetBSD-os.c
@@ -15,7 +15,7 @@
  * Frobbed for OpenBSD by Pierre R. Mai, 2001.
  * Frobbed for NetBSD by Pierre R. Mai, 2002.
  *
- * $Header: /Volumes/share2/src/cmucl/cvs2git/cvsroot/src/lisp/NetBSD-os.c,v 1.9 2008/05/16 13:30:21 rswindells Exp $
+ * $Header: /Volumes/share2/src/cmucl/cvs2git/cvsroot/src/lisp/NetBSD-os.c,v 1.10 2008/09/16 08:52:31 cshapiro Exp $
  *
  */
 
@@ -213,28 +213,14 @@ sigsegv_handler(HANDLER_ARGS)
 {
 #if defined GENCGC
     caddr_t fault_addr = code ? code->si_addr : 0;
-    int page_index = find_page_index((void *) fault_addr);
 
 #if SIGSEGV_VERBOSE
     fprintf(stderr, "Signal %d, fault_addr=%p, page_index=%d:\n",
 	    signal, fault_addr, page_index);
 #endif
 
-    /* Check if the fault is within the dynamic space. */
-    if (page_index != -1) {
-	/* Un-protect the page */
-
-	/* The page should have been marked write protected */
-	if (!PAGE_WRITE_PROTECTED(page_index))
-	    fprintf(stderr,
-		    "*** Sigsegv in page not marked as write protected\n");
-
-	os_protect(page_address(page_index), 4096, OS_VM_PROT_ALL);
-	page_table[page_index].flags &= ~PAGE_WRITE_PROTECTED_MASK;
-	page_table[page_index].flags |= PAGE_WRITE_PROTECT_CLEARED_MASK;
-
+    if (gc_write_barrier(code->si_addr))
 	return;
-    }
 #endif
 
     SAVE_CONTEXT();
diff --git a/lisp/OpenBSD-os.c b/lisp/OpenBSD-os.c
index bbc8f18646f91a8ed0a2ce7aa648dd20d8e40545..161fbb798bbcd10eb400a1124f43222952ef7622 100644
--- a/lisp/OpenBSD-os.c
+++ b/lisp/OpenBSD-os.c
@@ -13,7 +13,7 @@
  * GENCGC support by Douglas Crosher, 1996, 1997.
  * Frobbed for OpenBSD by Pierre R. Mai, 2001.
  *
- * $Header: /Volumes/share2/src/cmucl/cvs2git/cvsroot/src/lisp/OpenBSD-os.c,v 1.6 2007/07/30 07:24:46 cshapiro Exp $
+ * $Header: /Volumes/share2/src/cmucl/cvs2git/cvsroot/src/lisp/OpenBSD-os.c,v 1.7 2008/09/16 08:52:31 cshapiro Exp $
  *
  */
 
@@ -164,28 +164,14 @@ sigsegv_handler(HANDLER_ARGS)
 {
 #if defined GENCGC
     caddr_t fault_addr = code->si_addr;
-    int page_index = find_page_index((void *) fault_addr);
 
 #if SIGSEGV_VERBOSE
     fprintf(stderr, "Signal %d, fault_addr=%x, page_index=%d:\n",
 	    signal, fault_addr, page_index);
 #endif
 
-    /* Check if the fault is within the dynamic space. */
-    if (page_index != -1) {
-	/* Un-protect the page */
-
-	/* The page should have been marked write protected */
-	if (!PAGE_WRITE_PROTECTED(page_index))
-	    fprintf(stderr,
-		    "*** Sigsegv in page not marked as write protected\n");
-
-	os_protect(page_address(page_index), 4096, OS_VM_PROT_ALL);
-	page_table[page_index].flags &= ~PAGE_WRITE_PROTECTED_MASK;
-	page_table[page_index].flags |= PAGE_WRITE_PROTECT_CLEARED_MASK;
-
+    if (gc_write_barrier(code->si_addr))
 	return;
-    }
 #endif
 
     SAVE_CONTEXT();
diff --git a/lisp/gencgc.c b/lisp/gencgc.c
index ede257886e147fdd3c073d47682431222c3f71fc..483e29f5412e680f83f5d190e7dc4b7f4fa42336 100644
--- a/lisp/gencgc.c
+++ b/lisp/gencgc.c
@@ -7,7 +7,7 @@
  *
  * Douglas Crosher, 1996, 1997, 1998, 1999.
  *
- * $Header: /Volumes/share2/src/cmucl/cvs2git/cvsroot/src/lisp/gencgc.c,v 1.96 2008/09/11 00:15:28 rtoy Exp $
+ * $Header: /Volumes/share2/src/cmucl/cvs2git/cvsroot/src/lisp/gencgc.c,v 1.97 2008/09/16 08:52:31 cshapiro Exp $
  *
  */
 
@@ -385,7 +385,7 @@ static char *heap_base = NULL;
 /*
  * Calculate the start address for the given page number.
  */
-inline char *
+static char *
 page_address(int page_num)
 {
     return heap_base + PAGE_SIZE * page_num;
@@ -395,7 +395,7 @@ page_address(int page_num)
  * Find the page index within the page_table for the given address.
  * Returns -1 on failure.
  */
-inline int
+int
 find_page_index(void *addr)
 {
     int index = (char *) addr - heap_base;
@@ -409,6 +409,38 @@ find_page_index(void *addr)
     return -1;
 }
 
+/*
+ * This routine implements a write barrier used to record stores into
+ * to boxed regions outside of generation 0.  When such a store occurs
+ * this routine will be automatically invoked by the page fault
+ * handler.  If passed an address outside of the dynamic space, this
+ * routine will return immediately with a value of 0.  Otherwise, the
+ * page belonging to the address is made writable, the protection
+ * change is recorded in the garbage collector page table, and a value
+ * of 1 is returned.
+ */
+int
+gc_write_barrier(void *addr)
+{
+    int page_index = find_page_index(addr);
+
+    /* Check if the fault is within the dynamic space. */
+    if (page_index == -1) {
+	 return 0;
+    }
+
+    /* The page should have been marked write protected */
+    if (!PAGE_WRITE_PROTECTED(page_index))
+	 fprintf(stderr,
+		 "*** Page fault in page not marked as write protected\n");
+
+    /* Un-protect the page */
+    os_protect(page_address(page_index), PAGE_SIZE, OS_VM_PROT_ALL);
+    page_table[page_index].flags &= ~PAGE_WRITE_PROTECTED_MASK;
+    page_table[page_index].flags |= PAGE_WRITE_PROTECT_CLEARED_MASK;
+
+    return 1;
+}
 
 /*
  * A structure to hold the state of a generation.
diff --git a/lisp/gencgc.h b/lisp/gencgc.h
index 8d3a515c2451716582166020a5fcade492ac6dd9..ea3023dd7186cd0863255359ad758ae0cd11e0c9 100644
--- a/lisp/gencgc.h
+++ b/lisp/gencgc.h
@@ -7,7 +7,7 @@
  *
  * Douglas Crosher, 1996, 1997.
  *
- * $Header: /Volumes/share2/src/cmucl/cvs2git/cvsroot/src/lisp/gencgc.h,v 1.13 2006/01/18 15:21:26 rtoy Exp $
+ * $Header: /Volumes/share2/src/cmucl/cvs2git/cvsroot/src/lisp/gencgc.h,v 1.14 2008/09/16 08:52:32 cshapiro Rel $
  *
  */
 
@@ -15,8 +15,7 @@
 #define _GENCGC_H_
 
 void gc_free_heap(void);
-inline int find_page_index(void *);
-inline char *page_address(int);
+int gc_write_barrier(void *);
 
 
 
diff --git a/lisp/solaris-os.c b/lisp/solaris-os.c
index bb37779d3c527e2b4df661da2ce7ab5799cd1321..1c49f1754b2b251797cdfb326fcbb4a0ca08dea6 100644
--- a/lisp/solaris-os.c
+++ b/lisp/solaris-os.c
@@ -1,5 +1,5 @@
 /*
- * $Header: /Volumes/share2/src/cmucl/cvs2git/cvsroot/src/lisp/solaris-os.c,v 1.21 2008/09/07 07:07:50 cshapiro Exp $
+ * $Header: /Volumes/share2/src/cmucl/cvs2git/cvsroot/src/lisp/solaris-os.c,v 1.22 2008/09/16 08:52:32 cshapiro Exp $
  *
  * OS-dependent routines.  This file (along with os.h) exports an
  * OS-independent interface to the operating system VM facilities.
@@ -211,32 +211,16 @@ void
 segv_handler(HANDLER_ARGS)
 {
     caddr_t addr = code->si_addr;
-    int page_index;
 
     SAVE_CONTEXT();
 
-    page_index = find_page_index((void *) addr);
-
 #ifdef RED_ZONE_HIT
     if (os_control_stack_overflow(addr, context))
 	return;
 #endif
 
-    /* check if the fault is within the dynamic space. */
-    if (page_index != -1) {
-	/* Un-protect the page */
-
-	/* The page should have been marked write protected */
-	if (!PAGE_WRITE_PROTECTED(page_index))
-	    fprintf(stderr,
-		    "*** Sigsegv in page not marked as write protected\n");
-	os_protect((os_vm_address_t) page_address(page_index), PAGE_SIZE,
-		   OS_VM_PROT_ALL);
-	page_table[page_index].flags &= ~PAGE_WRITE_PROTECTED_MASK;
-	page_table[page_index].flags |= PAGE_WRITE_PROTECT_CLEARED_MASK;
-
-	return;
-    }
+    if (gc_write_barrier(code->si_addr))
+	 return;
 
     /*
      * Could be a C stack overflow.  Let's check