2 * This software is part of the SBCL system. See the README file for
5 * This software is derived from the CMU CL system, which was
6 * written at Carnegie Mellon University and released into the
7 * public domain. The software is in the public domain and is
8 * provided with absolutely no warranty. See the COPYING and CREDITS
9 * files for more information.
26 #include "gc-internal.h"
29 write_bytes(FILE *file, char *addr, long bytes)
31 long count, here, data;
33 bytes = (bytes+os_vm_page_size-1)&~(os_vm_page_size-1);
38 data = (ftell(file)+os_vm_page_size-1)&~(os_vm_page_size-1);
42 count = fwrite(addr, 1, bytes, file);
48 perror("error writing to save file");
54 return data/os_vm_page_size - 1;
58 output_space(FILE *file, int id, lispobj *addr, lispobj *end)
60 int words, bytes, data;
61 static char *names[] = {NULL, "dynamic", "static", "read-only"};
67 bytes = words * sizeof(lispobj);
69 printf("writing %d bytes from the %s space at 0x%08lx\n",
70 bytes, names[id], (unsigned long)addr);
72 data = write_bytes(file, (char *)addr, bytes);
75 putw((long)addr / os_vm_page_size, file);
76 putw((bytes + os_vm_page_size - 1) / os_vm_page_size, file);
80 save(char *filename, lispobj init_function)
84 /* Open the output file. We don't actually need the file yet, but
85 * the fopen() might fail for some reason, and we want to detect
86 * that and back out before we do anything irreversible. */
88 file = fopen(filename, "w");
94 /* Smash the enclosing state. (Once we do this, there's no good
95 * way to go back, which is a sufficient reason that this ends up
96 * being SAVE-LISP-AND-DIE instead of SAVE-LISP-AND-GO-ON). */
97 printf("[undoing binding stack and other enclosing state... ");
99 unbind_to_here((lispobj *)BINDING_STACK_START);
100 SetSymbolValue(CURRENT_CATCH_BLOCK, 0);
101 SetSymbolValue(CURRENT_UNWIND_PROTECT_BLOCK, 0);
105 /* (Now we can actually start copying ourselves into the
108 printf("[saving current Lisp image into %s:\n", filename);
111 putw(CORE_MAGIC, file);
113 putw(VERSION_CORE_ENTRY_TYPE_CODE, file);
115 putw(SBCL_CORE_VERSION_INTEGER, file);
117 putw(NEW_DIRECTORY_CORE_ENTRY_TYPE_CODE, file);
121 READ_ONLY_CORE_SPACE_ID,
122 (lispobj *)READ_ONLY_SPACE_START,
123 (lispobj *)SymbolValue(READ_ONLY_SPACE_FREE_POINTER));
125 STATIC_CORE_SPACE_ID,
126 (lispobj *)STATIC_SPACE_START,
127 (lispobj *)SymbolValue(STATIC_SPACE_FREE_POINTER));
130 DYNAMIC_CORE_SPACE_ID,
131 (lispobj *)current_dynamic_space,
132 dynamic_space_free_pointer);
134 #ifdef LISP_FEATURE_GENCGC
135 /* I don't know too much about the circumstances in which we could
136 * end up here. It may be that current_region_free_pointer is
137 * guaranteed to be relevant and we could skip these slightly
138 * paranoid checks. TRT would be to rid the code of
139 * current_region_foo completely - dan 2002.09.17 */
140 if((boxed_region.free_pointer < current_region_free_pointer) &&
141 (boxed_region.end_addr == current_region_end_addr))
142 boxed_region.free_pointer = current_region_free_pointer;
143 /* Flush the current_region, updating the tables. */
144 gc_alloc_update_page_tables(0,&boxed_region);
145 gc_alloc_update_page_tables(1,&unboxed_region);
146 update_x86_dynamic_space_free_pointer();
149 DYNAMIC_CORE_SPACE_ID,
150 (lispobj *)DYNAMIC_SPACE_START,
151 (lispobj *)SymbolValue(ALLOCATION_POINTER));
154 putw(INITIAL_FUN_CORE_ENTRY_TYPE_CODE, file);
156 putw(init_function, file);
158 putw(END_CORE_ENTRY_TYPE_CODE, file);