1.0.32.25: save page table allocation information into core files
authorNikodemus Siivola <nikodemus@random-state.net>
Wed, 11 Nov 2009 19:01:20 +0000 (19:01 +0000)
committerNikodemus Siivola <nikodemus@random-state.net>
Wed, 11 Nov 2009 19:01:20 +0000 (19:01 +0000)
 * Allows unboxed objects in saved cores to be written to without
   write-protection & later scavenging.

src/runtime/coreparse.c
src/runtime/gencgc.c
src/runtime/save.c
version.lisp-expr

index 3ccdc23..1757444 100644 (file)
@@ -423,6 +423,7 @@ load_core_file(char *file, os_vm_offset_t file_offset)
             size_t offset = 0;
             long bytes_read;
             unsigned long data[4096];
+            unsigned long word;
             lseek(fd, fdoffset + file_offset, SEEK_SET);
             while ((bytes_read = read(fd, data, (size < 4096 ? size : 4096 )))
                     > 0)
@@ -435,9 +436,12 @@ load_core_file(char *file, os_vm_offset_t file_offset)
                      * core entry was rounded up to os_vm_page_size
                      * during the save, and might now have more
                      * elements than the page table.
+                     *
+                     * The low bits of each word are allocation flags.
                      */
-                    if (data[i]) {
-                        page_table[offset].region_start_offset = data[i];
+                    if (word=data[i]) {
+                        page_table[offset].region_start_offset = word & ~0x03;
+                        page_table[offset].allocated = word & 0x03;
                     }
                     i++;
                     offset++;
index f140646..8937ebe 100644 (file)
@@ -4626,7 +4626,6 @@ gencgc_pickup_dynamic(void)
     generation_index_t gen = PSEUDO_STATIC_GENERATION;
     do {
         lispobj *first,*ptr= (lispobj *)page_address(page);
-        page_table[page].allocated = BOXED_PAGE_FLAG;
         page_table[page].gen = gen;
         page_table[page].bytes_used = PAGE_BYTES;
         page_table[page].large_object = 0;
@@ -4636,8 +4635,10 @@ gencgc_pickup_dynamic(void)
         page_table[page].need_to_zero = 1;
 
         if (!gencgc_partial_pickup) {
+            page_table[page].allocated = BOXED_PAGE_FLAG;
             first=gc_search_space(prev,(ptr+2)-prev,ptr);
-            if(ptr == first)  prev=ptr;
+            if(ptr == first)
+                prev=ptr;
             page_table[page].region_start_offset =
                 page_address(page) - (void *)prev;
         }
index 635bf49..726f012 100644 (file)
@@ -312,15 +312,22 @@ save_to_filehandle(FILE *file, char *filename, lispobj init_function,
             &~(os_vm_page_size-1);
         unsigned long *data = calloc(size, 1);
         if (data) {
+            unsigned long word;
             long offset;
             int i;
             for (i = 0; i < last_free_page; i++) {
-                data[i] = page_table[i].region_start_offset;
+                /* Thanks to alignment requirements, the two low bits
+                 * are always zero, so we can use them to store the
+                 * allocation type -- region is always closed, so only
+                 * the two low bits of allocation flags matter. */
+                word = page_table[i].region_start_offset;
+                gc_assert((word & 0x03) == 0);
+                data[i] = word | (0x03 & page_table[i].allocated);
             }
             write_lispobj(PAGE_TABLE_CORE_ENTRY_TYPE_CODE, file);
             write_lispobj(4, file);
             write_lispobj(size, file);
-            offset = write_bytes(file, (char *) data, size, core_start_pos);
+            offset = write_bytes(file, (char *)data, size, core_start_pos);
             write_lispobj(offset, file);
         }
     }
index 4ebf1e4..a60c1c1 100644 (file)
@@ -17,4 +17,4 @@
 ;;; checkins which aren't released. (And occasionally for internal
 ;;; versions, especially for internal versions off the main CVS
 ;;; branch, it gets hairier, e.g. "0.pre7.14.flaky4.13".)
-"1.0.32.24"
+"1.0.32.25"