Index: /trunk/source/lisp-kernel/x86-gc.c
===================================================================
--- /trunk/source/lisp-kernel/x86-gc.c	(revision 13496)
+++ /trunk/source/lisp-kernel/x86-gc.c	(revision 13497)
@@ -2363,8 +2363,12 @@
 
 Boolean
-copy_reference(LispObj *ref, BytePtr low, BytePtr high, area *dest, int what)
-{
-  LispObj obj = *ref;
+copy_reference(LispObj *ref, BytePtr low, BytePtr high, area *dest, int what, Boolean recursive)
+{
+  LispObj obj = *ref, *scan = NULL;
   natural tag = fulltag_of(obj);
+
+  if (recursive) {
+    scan = (LispObj *)(dest->active);
+  }
 
   if (
@@ -2379,5 +2383,35 @@
   }
   if (is_node_fulltag(tag)) {
-    return purify_locref(ref,low,high,dest,what);
+    if (purify_locref(ref,low,high,dest,what)) {
+      if (recursive) {
+        LispObj header;
+        unsigned tag;
+        natural nwords;
+        
+        while (scan < (LispObj *)(dest->active)) {
+          header = *scan;
+          tag = fulltag_of(header);
+          if (immheader_tag_p(tag)) {
+            scan = (LispObj *)skip_over_ivector((natural)scan, header);
+          } else if (nodeheader_tag_p(tag)) {
+            if ((header_subtag(header) == subtag_simple_vector) ||
+                (header_subtag(header) == subtag_struct)) {
+              scan++;
+              purify_locref(scan,low,high,dest,what);
+              scan++;
+            } else {
+              nwords = (header_element_count(header)+2)&~1;
+              scan += nwords;
+            }
+          } else {
+            purify_locref(scan,low,high,dest,what);
+            scan++;
+            purify_locref(scan,low,high,dest,what);
+            scan++;
+          }
+        }            
+      }
+    }
+    return true;
   }
   return false;
@@ -2392,5 +2426,5 @@
 
   while ((*prev) != (LispObj)NULL) {
-    copy_reference(prev, low, high, to, what);
+    copy_reference(prev, low, high, to, what, false);
     next = *prev;
     prev = &(((xmacptr *)ptr_from_lispobj(untag(next)))->link);
@@ -2402,5 +2436,5 @@
 {
   while (start < end) { 
-    copy_reference(start, low, high, to, what);
+    copy_reference(start, low, high, to, what, false);
     start++;
   }
@@ -2408,5 +2442,5 @@
    
 void
-purify_range(LispObj *start, LispObj *end, BytePtr low, BytePtr high, area *to, int what)
+purify_range(LispObj *start, LispObj *end, BytePtr low, BytePtr high, area *to, int what, Boolean recursive)
 {
   LispObj header;
@@ -2435,5 +2469,5 @@
           nwords -= skip;
           while(skip--) {
-            copy_reference(start, low, high, to, what);
+            copy_reference(start, low, high, to, what, recursive);
             start++;
           }
@@ -2444,10 +2478,12 @@
           nwords >>= 1;
           while(nwords--) {
-            if (copy_reference(start, low, high, to, what) && hashp) {
+
+            if (copy_reference(start, low, high, to, what, recursive) 
+                && hashp) {
               hashp->flags |= nhash_key_moved_mask;
               hashp = NULL;
             }
             start++;
-            copy_reference(start, low, high, to, what);
+            copy_reference(start, low, high, to, what, recursive);
             start++;
           }
@@ -2469,5 +2505,5 @@
           start++;
           while(nwords--) {
-            copy_reference(start, low, high, to, what);
+            copy_reference(start, low, high, to, what, recursive);
             start++;
           }
@@ -2475,7 +2511,7 @@
       } else {
         /* Not a header, just a cons cell */
-        copy_reference(start, low, high, to, what);
+        copy_reference(start, low, high, to, what, recursive);
         start++;
-        copy_reference(start, low, high, to, what);
+        copy_reference(start, low, high, to, what, recursive);
         start++;
       }
@@ -2500,5 +2536,5 @@
     next = (LispObj *) ptr_from_lispobj(*current);
     end = ((next >= start) && (next < limit)) ? next : limit;
-    purify_range(current+2, end, low, high, to, what);
+    purify_range(current+2, end, low, high, to, what, false);
   }
 }
@@ -2527,15 +2563,15 @@
 
 #ifdef X8664
-  copy_reference(&(regs[Iarg_z]), low, high, to, what);
-  copy_reference(&(regs[Iarg_y]), low, high, to, what);
-  copy_reference(&(regs[Iarg_x]), low, high, to, what);
-  copy_reference(&(regs[Isave3]), low, high, to, what);
-  copy_reference(&(regs[Isave2]), low, high, to, what);
-  copy_reference(&(regs[Isave1]), low, high, to, what);
-  copy_reference(&(regs[Isave0]), low, high, to, what);
-  copy_reference(&(regs[Ifn]), low, high, to, what);
-  copy_reference(&(regs[Itemp0]), low, high, to, what);
-  copy_reference(&(regs[Itemp1]), low, high, to, what);
-  copy_reference(&(regs[Itemp2]), low, high, to, what);
+  copy_reference(&(regs[Iarg_z]), low, high, to, what, false);
+  copy_reference(&(regs[Iarg_y]), low, high, to, what, false);
+  copy_reference(&(regs[Iarg_x]), low, high, to, what, false);
+  copy_reference(&(regs[Isave3]), low, high, to, what, false);
+  copy_reference(&(regs[Isave2]), low, high, to, what, false);
+  copy_reference(&(regs[Isave1]), low, high, to, what, false);
+  copy_reference(&(regs[Isave0]), low, high, to, what, false);
+  copy_reference(&(regs[Ifn]), low, high, to, what, false);
+  copy_reference(&(regs[Itemp0]), low, high, to, what, false);
+  copy_reference(&(regs[Itemp1]), low, high, to, what, false);
+  copy_reference(&(regs[Itemp2]), low, high, to, what, false);
 
   purify_locref(&(regs[Iip]), low, high, to, PURIFY_NOTHING);
@@ -2543,28 +2579,28 @@
 #else
   if (node_regs_mask & (1<<0)) {
-    copy_reference(&(regs[REG_EAX]), low, high, to, what);
+    copy_reference(&(regs[REG_EAX]), low, high, to, what, false);
   }
   if (node_regs_mask & (1<<1)) {
-    copy_reference(&(regs[REG_ECX]), low, high, to, what);
+    copy_reference(&(regs[REG_ECX]), low, high, to, what, false);
   }
   if (! (regs[REG_EFL] & EFL_DF)) {
     if (node_regs_mask & (1<<2)) {
-      copy_reference(&(regs[REG_EDX]), low, high, to, what);
+      copy_reference(&(regs[REG_EDX]), low, high, to, what, false);
     }
   }
   if (node_regs_mask & (1<<3)) {
-    copy_reference(&(regs[REG_EBX]), low, high, to, what);
+    copy_reference(&(regs[REG_EBX]), low, high, to, what, false);
   }
   if (node_regs_mask & (1<<4)) {
-    copy_reference(&(regs[REG_ESP]), low, high, to, what);
+    copy_reference(&(regs[REG_ESP]), low, high, to, what, false);
   }
   if (node_regs_mask & (1<<5)) {
-    copy_reference(&(regs[REG_EBP]), low, high, to, what);
+    copy_reference(&(regs[REG_EBP]), low, high, to, what, false);
   }
   if (node_regs_mask & (1<<6)) {
-    copy_reference(&(regs[REG_ESI]), low, high, to, what);
+    copy_reference(&(regs[REG_ESI]), low, high, to, what, false);
   }
   if (node_regs_mask & (1<<7)) {
-    copy_reference(&(regs[REG_EDI]), low, high, to, what);
+    copy_reference(&(regs[REG_EDI]), low, high, to, what, false);
   }
   purify_locref(&regs[REG_EIP], low, high, to, what);
@@ -2578,5 +2614,5 @@
   LispObj *start = tcr->tlb_pointer, *end = (LispObj *) ((BytePtr)start+n);
 
-  purify_range(start, end, low, high, to, what);
+  purify_range(start, end, low, high, to, what, false);
 }
 
@@ -2596,9 +2632,9 @@
   }
 #ifdef X8632
-  copy_reference(&tcr->save0, low, high, to, what);
-  copy_reference(&tcr->save1, low, high, to, what);
-  copy_reference(&tcr->save2, low, high, to, what);
-  copy_reference(&tcr->save3, low, high, to, what);
-  copy_reference(&tcr->next_method_context, low, high, to, what);
+  copy_reference(&tcr->save0, low, high, to, what, false);
+  copy_reference(&tcr->save1, low, high, to, what, false);
+  copy_reference(&tcr->save2, low, high, to, what, false);
+  copy_reference(&tcr->save3, low, high, to, what, false);
+  copy_reference(&tcr->next_method_context, low, high, to, what, false);
 #endif
 
@@ -2635,5 +2671,5 @@
     case AREA_DYNAMIC:
     case AREA_MANAGED_STATIC:
-      purify_range((LispObj *) next_area->low, (LispObj *) next_area->active, low, high, target, what);
+      purify_range((LispObj *) next_area->low, (LispObj *) next_area->active, low, high, target, what, false);
       break;
       
@@ -2762,9 +2798,9 @@
       LispObj package_list;
 
-      copy_reference(&nrs_UDF.vcell,low,high,managed_static_area,PURIFY_ALL);
+      copy_reference(&nrs_UDF.vcell,low,high,managed_static_area,PURIFY_ALL, false);
       for (package_list = nrs_ALL_PACKAGES.vcell;
            package_list != lisp_nil;
            package_list = deref(package_list,0)) {
-        copy_reference(&(deref(package_list,1)),low,high,managed_static_area,PURIFY_ALL);
+        copy_reference(&(deref(package_list,1)),low,high,managed_static_area,PURIFY_ALL, false);
       }
 
@@ -2778,5 +2814,6 @@
                    high,
                    managed_static_area,
-                   PURIFY_ALL);
+                   PURIFY_ALL,
+                   true);
       /* Go back through all areas, resolving forwarding pointers
          (but without copying anything.) */
