Fix bug: purify wasn't properly saving and restoring the scan state
authorChris Hanson <org/chris-hanson/cph>
Tue, 28 Nov 2000 05:19:05 +0000 (05:19 +0000)
committerChris Hanson <org/chris-hanson/cph>
Tue, 28 Nov 2000 05:19:05 +0000 (05:19 +0000)
around the scan of constant space.  Doing this right requires access
to internal state of bchmmg, so I built an abstraction to do this.

v7/src/microcode/bchgcc.h
v7/src/microcode/bchmmg.c
v7/src/microcode/bchpur.c

index 5b767344368219a124990b183623d2bc85bb645e..563e5ffcbc9f3bc99dbf3540b50d6f8b11eafbfc 100644 (file)
@@ -1,6 +1,6 @@
 /* -*-C-*-
 
-$Id: bchgcc.h,v 9.60 2000/01/18 02:59:13 cph Exp $
+$Id: bchgcc.h,v 9.61 2000/11/28 05:18:59 cph Exp $
 
 Copyright (c) 1987-2000 Massachusetts Institute of Technology
 
@@ -98,6 +98,20 @@ extern int EXFUN (retrying_file_operation,
 
 extern int EXFUN (io_error_retry_p, (char *, char *));
 extern int EXFUN (io_error_always_abort, (char *, char *));
+
+struct saved_scan_state
+{
+  SCHEME_OBJECT * virtual_scan_pointer;
+  unsigned long scan_position;
+  unsigned long scan_offset;
+};
+
+extern void EXFUN
+  (save_scan_state, (struct saved_scan_state * state, SCHEME_OBJECT * scan));
+extern SCHEME_OBJECT * EXFUN
+  (restore_scan_state, (struct saved_scan_state * state));
+extern void EXFUN
+  (set_fixed_scan_area, (SCHEME_OBJECT * bottom, SCHEME_OBJECT * top));
 \f
 #ifndef O_BINARY
 # define O_BINARY 0
index e2671bf1a6bc70ad66ee40ca6bf01eaa6a49f509..23b5f167b0a13bf5dd8acd70dcac7f1b0f8d633e 100644 (file)
@@ -1,6 +1,6 @@
 /* -*-C-*-
 
-$Id: bchmmg.c,v 9.95 2000/01/18 05:06:34 cph Exp $
+$Id: bchmmg.c,v 9.96 2000/11/28 05:19:02 cph Exp $
 
 Copyright (c) 1987-2000 Massachusetts Institute of Technology
 
@@ -2711,6 +2711,73 @@ DEFUN (dump_free_directly, (from, nbuffers, success),
   return (free_buffer_bottom);
 }
 \f
+/* This code is needed by purify.  After the purified object is
+   copied, the next step is to scan constant space.  In order to do
+   this, it's necessary to save the current scan position, reset the
+   scan limit pointers to scan constant space, then restore the saved
+   scan position and finish scanning the heap.  These procedures
+   provide the necessary functionality to do this.  */
+
+static void
+DEFUN_VOID (reset_scan_buffer)
+{
+  virtual_scan_pointer = 0;
+  scan_position = (-1L);
+  scan_buffer = 0;
+  scan_buffer_bottom = 0;
+  scan_buffer_top = Highest_Allocated_Address;
+  next_scan_buffer = 0;
+  scan_buffer_extended_p = false;
+  extension_overlap_p = false;
+  extension_overlap_length = 0;
+}
+
+void
+DEFUN (save_scan_state, (state, scan),
+       struct saved_scan_state * state AND
+       SCHEME_OBJECT * scan)
+{
+  (state -> virtual_scan_pointer) = virtual_scan_pointer;
+  (state -> scan_position) = scan_position;
+  (state -> scan_offset) = (scan - scan_buffer_bottom);
+  if (scan_position != free_position)
+    DUMP_BUFFER (scan_buffer, scan_position, gc_buffer_bytes,
+                0, "the scan buffer");
+  reset_scan_buffer ();
+}
+
+SCHEME_OBJECT *
+DEFUN (restore_scan_state, (state), struct saved_scan_state * state)
+{
+  virtual_scan_pointer = (state -> virtual_scan_pointer);
+  scan_position = (state -> scan_position);
+  if (scan_position == free_position)
+    {
+      scan_buffer = free_buffer;
+      scan_buffer_bottom = free_buffer_bottom;
+      scan_buffer_top = free_buffer_top;
+    }
+  else
+    {
+      scan_buffer = (OTHER_BUFFER (free_buffer));
+      scan_buffer_bottom = (GC_BUFFER_BOTTOM (scan_buffer));
+      scan_buffer_top = (GC_BUFFER_TOP (scan_buffer));
+      LOAD_BUFFER (scan_buffer, scan_position, gc_buffer_bytes,
+                  "the scan buffer");
+    }
+  return (scan_buffer_bottom + (state -> scan_offset));
+}
+
+void
+DEFUN (set_fixed_scan_area, (bottom, top),
+       SCHEME_OBJECT * bottom AND
+       SCHEME_OBJECT * top)
+{
+  virtual_scan_pointer = bottom;
+  scan_buffer_bottom = bottom;
+  scan_buffer_top = top;
+}
+\f
 #ifndef START_TRANSPORT_HOOK
 #define START_TRANSPORT_HOOK()         do { } while (0)
 #endif
@@ -2749,17 +2816,9 @@ DEFUN_VOID (initialize_free_buffer)
   free_buffer = (INITIAL_FREE_BUFFER ());
   free_buffer_bottom = (GC_BUFFER_BOTTOM (free_buffer));
   free_buffer_top = (GC_BUFFER_TOP (free_buffer));
-  virtual_scan_pointer = NULL;
-  scan_position = -1L;
-  scan_buffer = NULL;
-  scan_buffer_bottom = NULL;
-  scan_buffer_top = Highest_Allocated_Address;
+  reset_scan_buffer ();
   /* Force first write to do an lseek. */
   gc_file_current_position = -1;
-  next_scan_buffer = NULL;
-  scan_buffer_extended_p = false;
-  extension_overlap_p = false;
-  extension_overlap_length = 0;
   return (free_buffer_bottom);
 }
 \f
index 2c0095eaa41f39762f5f940f131d3751389342f8..d5a0a20d965ac32f764e4a4d0c49f668d90eb134 100644 (file)
@@ -1,8 +1,8 @@
 /* -*-C-*-
 
-$Id: bchpur.c,v 9.67 1999/01/02 06:11:34 cph Exp $
+$Id: bchpur.c,v 9.68 2000/11/28 05:19:05 cph Exp $
 
-Copyright (c) 1987-1999 Massachusetts Institute of Technology
+Copyright (c) 1987-2000 Massachusetts Institute of Technology
 
 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
@@ -407,7 +407,8 @@ DEFUN (purify, (object, purify_mode),
     * old_free_const, * block_start,
     * scan_start, * new_free_const, * pending_scan,
     * root, * root2, the_precious_objects,
-    * saved_const_top, * saved_vsp, * saved_sbb, * saved_sbt;
+    * saved_const_top;
+  struct saved_scan_state scan_state;
   extern Boolean EXFUN (update_allocator_parameters, (SCHEME_OBJECT *));
 
   run_pre_gc_hooks ();
@@ -526,15 +527,11 @@ DEFUN (purify, (object, purify_mode),
   Free += (GC_relocate_root (&free_buffer_ptr));
 
   saved_const_top = Constant_Top;
-  saved_vsp = virtual_scan_pointer;
-  saved_sbb = scan_buffer_bottom;
-  saved_sbt = scan_buffer_top;
-
-  virtual_scan_pointer = ((SCHEME_OBJECT *) NULL);
-  scan_buffer_bottom = ((SCHEME_OBJECT *) NULL);
-  scan_buffer_top = Highest_Allocated_Address;
   Constant_Top = old_free_const;
 
+  save_scan_state ((&scan_state), pending_scan);
+  set_fixed_scan_area (0, Highest_Allocated_Address);
+
   result = (GCLoop ((CONSTANT_AREA_START ()), &free_buffer_ptr, &Free));
   if (result != old_free_const)
   {
@@ -544,9 +541,7 @@ DEFUN (purify, (object, purify_mode),
     /*NOTREACHED*/
   }
 
-  virtual_scan_pointer = saved_vsp;
-  scan_buffer_bottom = saved_sbb;
-  scan_buffer_top = saved_sbt;
+  pending_scan = (restore_scan_state (&scan_state));
 
   result = (GCLoop (pending_scan, &free_buffer_ptr, &Free));
   if (free_buffer_ptr != result)