Index: /trunk/ccl/lisp-kernel/ppc-exceptions.c
===================================================================
--- /trunk/ccl/lisp-kernel/ppc-exceptions.c	(revision 5950)
+++ /trunk/ccl/lisp-kernel/ppc-exceptions.c	(revision 5951)
@@ -364,4 +364,6 @@
 }
 
+natural gc_deferred = 0, full_gc_deferred = 0;
+
 OSStatus
 handle_gc_trap(ExceptionInformation *xp, TCR *tcr)
@@ -372,4 +374,5 @@
   area *a = active_dynamic_area;
   Boolean egc_was_enabled = (a->older != NULL);
+  natural gc_previously_deferred = gc_deferred;
 
 
@@ -416,6 +419,11 @@
 
     if (selector == GC_TRAP_FUNCTION_IMMEDIATE_GC) {
-      gc_from_xp(xp, 0L);
-      break;
+      if (!full_gc_deferred) {
+        gc_from_xp(xp, 0L);
+        break;
+      }
+      /* Tried to do a full GC when gc was disabled.  That failed,
+         so try full GC now */
+      selector = GC_TRAP_FUNCTION_GC;
     }
     
@@ -424,4 +432,9 @@
     }
     gc_from_xp(xp, 0L);
+    if (gc_deferred > gc_previously_deferred) {
+      full_gc_deferred = 1;
+    } else {
+      full_gc_deferred = 0;
+    }
     if (selector > GC_TRAP_FUNCTION_GC) {
       if (selector & GC_TRAP_FUNCTION_IMPURIFY) {
@@ -680,6 +693,8 @@
     }
     resume_other_threads(true);
+    gc_deferred++;
     return 0;
   }
+  gc_deferred = 0;
 
   gc_tcr = tcr;
Index: /trunk/ccl/lisp-kernel/x86-exceptions.c
===================================================================
--- /trunk/ccl/lisp-kernel/x86-exceptions.c	(revision 5950)
+++ /trunk/ccl/lisp-kernel/x86-exceptions.c	(revision 5951)
@@ -141,4 +141,6 @@
 }
 
+natural gc_deferred = 0, full_gc_deferred = 0;
+
 Boolean
 handle_gc_trap(ExceptionInformation *xp, TCR *tcr)
@@ -149,4 +151,5 @@
   area *a = active_dynamic_area;
   Boolean egc_was_enabled = (a->older != NULL);
+  natural gc_previously_deferred = gc_deferred;
 
   switch (selector) {
@@ -192,6 +195,11 @@
 
     if (selector == GC_TRAP_FUNCTION_IMMEDIATE_GC) {
-      gc_from_xp(xp, 0L);
-      break;
+      if (!full_gc_deferred) {
+        gc_from_xp(xp, 0L);
+        break;
+      }
+      /* Tried to do a full GC when gc was disabled.  That failed,
+         so try full GC now */
+      selector = GC_TRAP_FUNCTION_GC;
     }
     
@@ -200,4 +208,9 @@
     }
     gc_from_xp(xp, 0L);
+    if (gc_deferred > gc_previously_deferred) {
+      full_gc_deferred = 1;
+    } else {
+      full_gc_deferred = 0;
+    }
     if (selector & GC_TRAP_FUNCTION_PURIFY) {
       purify_from_xp(xp, 0L);
@@ -1640,4 +1653,5 @@
 TCR *gc_tcr = NULL;
 
+
 int
 gc_like_from_xp(ExceptionInformation *xp, 
@@ -1657,6 +1671,8 @@
     }
     resume_other_threads(true);
+    gc_deferred++;
     return 0;
   }
+  gc_deferred = 0;
 
   gc_tcr = tcr;
