From 96191081d3a73894005f32d370163c8ade2a2a3e Mon Sep 17 00:00:00 2001 From: Nikodemus Siivola Date: Wed, 11 Nov 2009 19:01:20 +0000 Subject: [PATCH] 1.0.32.25: save page table allocation information into core files * Allows unboxed objects in saved cores to be written to without write-protection & later scavenging. --- src/runtime/coreparse.c | 8 ++++++-- src/runtime/gencgc.c | 5 +++-- src/runtime/save.c | 11 +++++++++-- version.lisp-expr | 2 +- 4 files changed, 19 insertions(+), 7 deletions(-) diff --git a/src/runtime/coreparse.c b/src/runtime/coreparse.c index 3ccdc23..1757444 100644 --- a/src/runtime/coreparse.c +++ b/src/runtime/coreparse.c @@ -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++; diff --git a/src/runtime/gencgc.c b/src/runtime/gencgc.c index f140646..8937ebe 100644 --- a/src/runtime/gencgc.c +++ b/src/runtime/gencgc.c @@ -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; } diff --git a/src/runtime/save.c b/src/runtime/save.c index 635bf498..726f012 100644 --- a/src/runtime/save.c +++ b/src/runtime/save.c @@ -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); } } diff --git a/version.lisp-expr b/version.lisp-expr index 4ebf1e4..a60c1c1 100644 --- a/version.lisp-expr +++ b/version.lisp-expr @@ -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" -- 1.7.10.4