From 81475dfab157425291352cfd08d050e49a2760a0 Mon Sep 17 00:00:00 2001 From: Chris Hanson Date: Tue, 28 Nov 2000 05:19:05 +0000 Subject: [PATCH] Fix bug: purify wasn't properly saving and restoring the scan state 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 | 16 +++++++- v7/src/microcode/bchmmg.c | 79 ++++++++++++++++++++++++++++++++++----- v7/src/microcode/bchpur.c | 21 ++++------- 3 files changed, 92 insertions(+), 24 deletions(-) diff --git a/v7/src/microcode/bchgcc.h b/v7/src/microcode/bchgcc.h index 5b7673443..563e5ffcb 100644 --- a/v7/src/microcode/bchgcc.h +++ b/v7/src/microcode/bchgcc.h @@ -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)); #ifndef O_BINARY # define O_BINARY 0 diff --git a/v7/src/microcode/bchmmg.c b/v7/src/microcode/bchmmg.c index e2671bf1a..23b5f167b 100644 --- a/v7/src/microcode/bchmmg.c +++ b/v7/src/microcode/bchmmg.c @@ -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); } +/* 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; +} + #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); } diff --git a/v7/src/microcode/bchpur.c b/v7/src/microcode/bchpur.c index 2c0095eaa..d5a0a20d9 100644 --- a/v7/src/microcode/bchpur.c +++ b/v7/src/microcode/bchpur.c @@ -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) -- 2.25.1