3 $Header: /Volumes/share2/src/cmucl/cvs2git/cvsroot/src/lisp/save.c,v 1.29 2010/09/24 04:08:39 rtoy Rel $
5 This code was written as part of the CMU Common Lisp project at
6 Carnegie Mellon University, and has been placed in the public domain.
18 #include "internals.h"
30 #ifdef FEATURE_EXECUTABLE
32 #if !(defined(DARWIN) && defined(__ppc__))
40 write_bytes(FILE * file, char *addr, long bytes)
42 long count, here, data;
44 bytes = (bytes + CORE_PAGESIZE - 1) & ~(CORE_PAGESIZE - 1);
49 data = (ftell(file) + CORE_PAGESIZE - 1) & ~(CORE_PAGESIZE - 1);
53 count = fwrite(addr, 1, bytes, file);
58 perror("Error writing to save file");
64 return data / CORE_PAGESIZE - 1;
68 output_space(FILE * file, int id, lispobj * addr, lispobj * end)
70 int words, bytes, data;
71 static char *names[] = { NULL, "Dynamic", "Static", "Read-Only" };
77 bytes = words * sizeof(lispobj);
79 printf("Writing %d bytes from the %s space at 0x%08lX.\n",
80 bytes, names[id], (unsigned long) addr);
82 data = write_bytes(file, (char *) addr, bytes);
85 putw((long) addr / CORE_PAGESIZE, file);
86 putw((bytes + CORE_PAGESIZE - 1) / CORE_PAGESIZE, file);
91 dump_region(struct alloc_region *alloc_region)
93 fprintf(stderr, "free_pointer = %p\n", alloc_region->free_pointer);
94 fprintf(stderr, "end_addr = %p\n", alloc_region->end_addr);
95 fprintf(stderr, "first_page = %d\n", alloc_region->first_page);
96 fprintf(stderr, "last_page = %d\n", alloc_region->last_page);
97 fprintf(stderr, "start_addr = %p\n", alloc_region->start_addr);
99 fprintf(stderr, " page_table[%d]\n", alloc_region->first_page);
100 fprintf(stderr, " flags = %x\n", page_table[alloc_region->first_page].flags);
101 fprintf(stderr, " offset = %x\n", page_table[alloc_region->first_page].first_object_offset);
102 fprintf(stderr, " used = %x\n", page_table[alloc_region->first_page].bytes_used);
107 save(char *filename, lispobj init_function, int sse2_mode)
112 volatile lispobj *func_ptr = &init_function;
115 strcpy(sbuf, filename);
117 /* Get rid of remnant stuff. This is a MUST so that
118 * the memory manager can get started correctly when
119 * we restart after this save. Purify is going to
120 * maybe move the args so we need to consider them volatile,
121 * especially if the gcc optimizer is working!!
125 init_function = *func_ptr;
126 /* Set dynamic space pointer to base value so we don't write out
127 * MBs of just cleared heap.
129 if (SymbolValue(X86_CGC_ACTIVE_P) != NIL)
130 SetSymbolValue(ALLOCATION_POINTER, DYNAMIC_0_SPACE_START);
134 file = fopen(filename, "w");
139 printf("[Undoing binding stack... ");
141 unbind_to_here((lispobj *) BINDING_STACK_START);
142 SetSymbolValue(CURRENT_CATCH_BLOCK, 0);
143 SetSymbolValue(CURRENT_UNWIND_PROTECT_BLOCK, 0);
144 SetSymbolValue(EVAL_STACK_TOP, 0);
146 #if defined WANT_CGC && defined X86_CGC_ACTIVE_P
147 SetSymbolValue(X86_CGC_ACTIVE_P, T);
149 printf("[Saving current lisp image into %s:\n", filename);
151 putw(CORE_MAGIC, file);
153 putw(CORE_VERSION, file);
154 #if defined(i386) && defined(FEATURE_SSE2)
161 #if defined(i386) && defined(FEATURE_SSE2)
169 putw(CORE_NDIRECTORY, file);
170 putw((5 * 3) + 2, file);
172 output_space(file, READ_ONLY_SPACE_ID, read_only_space,
173 (lispobj *) SymbolValue(READ_ONLY_SPACE_FREE_POINTER));
174 output_space(file, STATIC_SPACE_ID, static_space,
175 (lispobj *) SymbolValue(STATIC_SPACE_FREE_POINTER));
177 /* Flush the current_region updating the tables. */
178 #ifdef DEBUG_BAD_HEAP
179 fprintf(stderr, "before ALLOC_POINTER = %p\n", (lispobj *) SymbolValue(ALLOCATION_POINTER));
180 dump_region(&boxed_region);
182 gc_alloc_update_page_tables(0, &boxed_region);
183 gc_alloc_update_page_tables(1, &unboxed_region);
184 #ifdef DEBUG_BAD_HEAP
185 fprintf(stderr, "boxed_region after update\n");
186 dump_region(&boxed_region);
188 print_ptr((lispobj*) 0x2805a184);
191 #ifdef DEBUG_BAD_HEAP
193 * For some reason x86 has a heap corruption problem. I (rtoy)
194 * have not been able to figure out how that occurs, but what is
195 * happening is that when a core is loaded, there is some static
196 * object pointing to an object that is on a free page. In normal
197 * usage, at startup there should be 4 objects in static space
198 * pointing to a free page, because these are newly allocated
199 * objects created by the C runtime. However, there is an
202 * I do not know what this object should be or how it got there,
203 * but it will often cause CMUCL to fail to save a new core file.
205 * Disabling this call to update_dynamic_space_free_pointer is a
206 * work around. What is happening is that u_d_s_f_p is resetting
207 * ALLOCATION_POINTER, but that weird object is in the current
208 * region, but after resetting the pointer, that object isn't
209 * saved to the core file. By not resetting the pointer, the
210 * object (or at least enough of it) gets saved in the core file
211 * that we don't have problems when reloading.
213 * Note that on sparc and ppc, u_d_s_f_p doesn't actually do
214 * anything because the call to reset ALLOCATION_POINTER is a nop
215 * on sparc and ppc. And sparc and ppc dont' have the heap
216 * corruption issue. That's not conclusive evidence, though.
218 * This needs more work and investigation.
220 update_dynamic_space_free_pointer();
223 #ifdef DEBUG_BAD_HEAP
224 fprintf(stderr, "after ALLOC_POINTER = %p\n", (lispobj *) SymbolValue(ALLOCATION_POINTER));
229 output_space(file, DYNAMIC_SPACE_ID, current_dynamic_space,
230 current_dynamic_space_free_pointer);
232 output_space(file, DYNAMIC_SPACE_ID, current_dynamic_space,
233 (lispobj *) SymbolValue(ALLOCATION_POINTER));
236 putw(CORE_INITIAL_FUNCTION, file);
238 putw(init_function, file);
240 putw(CORE_END, file);
249 #ifdef FEATURE_EXECUTABLE
251 save_executable(char *filename, lispobj init_function)
256 volatile lispobj *func_ptr = &init_function;
259 strcpy(sbuf, filename);
261 /* Get rid of remnant stuff. This is a MUST so that
262 * the memory manager can get started correctly when
263 * we restart after this save. Purify is going to
264 * maybe move the args so we need to consider them volatile,
265 * especially if the gcc optimizer is working!!
269 init_function = *func_ptr;
270 /* Set dynamic space pointer to base value so we don't write out
271 * MBs of just cleared heap.
273 if(SymbolValue(X86_CGC_ACTIVE_P) != NIL)
274 SetSymbolValue(ALLOCATION_POINTER, DYNAMIC_0_SPACE_START);
276 dir_name = dirname(strdup(filename));
278 printf("[Undoing binding stack... ");
280 unbind_to_here((lispobj *)BINDING_STACK_START);
281 SetSymbolValue(CURRENT_CATCH_BLOCK, 0);
282 SetSymbolValue(CURRENT_UNWIND_PROTECT_BLOCK, 0);
283 SetSymbolValue(EVAL_STACK_TOP, 0);
285 #if defined WANT_CGC && defined X86_CGC_ACTIVE_P
286 SetSymbolValue(X86_CGC_ACTIVE_P, T);
288 printf("[Saving current lisp image as executable into \"%s\":\n", filename);
290 printf("\t[Writing core objects\n");
292 write_space_object(dir_name, READ_ONLY_SPACE_ID, (os_vm_address_t)read_only_space,
293 (os_vm_address_t)SymbolValue(READ_ONLY_SPACE_FREE_POINTER));
294 write_space_object(dir_name, STATIC_SPACE_ID, (os_vm_address_t)static_space,
295 (os_vm_address_t)SymbolValue(STATIC_SPACE_FREE_POINTER));
297 /* Flush the current_region updating the tables. */
298 #ifdef DEBUG_BAD_HEAP
299 fprintf(stderr, "before ALLOC_POINTER = %p\n", (lispobj *) SymbolValue(ALLOCATION_POINTER));
300 dump_region(&boxed_region);
302 gc_alloc_update_page_tables(0,&boxed_region);
303 gc_alloc_update_page_tables(1,&unboxed_region);
304 #ifdef DEBUG_BAD_HEAP
305 fprintf(stderr, "boxed_region after update\n");
306 dump_region(&boxed_region);
308 print_ptr((lispobj*) 0x2805a184);
310 #ifdef DEBUG_BAD_HEAP
312 * For some reason x86 has a heap corruption problem. I (rtoy)
313 * have not been able to figure out how that occurs, but what is
314 * happening is that when a core is loaded, there is some static
315 * object pointing to an object that is on a free page. In normal
316 * usage, at startup there should be 4 objects in static space
317 * pointing to a free page, because these are newly allocated
318 * objects created by the C runtime. However, there is an
321 * I do not know what this object should be or how it got there,
322 * but it will often cause CMUCL to fail to save a new core file.
324 * Disabling this call to update_dynamic_space_free_pointer is a
325 * work around. What is happening is that u_d_s_f_p is resetting
326 * ALLOCATION_POINTER, but that weird object is in the current
327 * region, but after resetting the pointer, that object isn't
328 * saved to the core file. By not resetting the pointer, the
329 * object (or at least enough of it) gets saved in the core file
330 * that we don't have problems when reloading.
332 * Note that on sparc and ppc, u_d_s_f_p doesn't actually do
333 * anything because the call to reset ALLOCATION_POINTER is a nop
334 * on sparc and ppc. And sparc and ppc dont' have the heap
335 * corruption issue. That's not conclusive evidence, though.
337 * This needs more work and investigation.
339 update_dynamic_space_free_pointer();
342 #ifdef DEBUG_BAD_HEAP
343 fprintf(stderr, "after ALLOC_POINTER = %p\n", (lispobj *) SymbolValue(ALLOCATION_POINTER));
348 write_space_object(dir_name, DYNAMIC_SPACE_ID, (os_vm_address_t)current_dynamic_space,
349 (os_vm_address_t)current_dynamic_space_free_pointer);
351 write_space_object(dir_name, DYNAMIC_SPACE_ID, (os_vm_address_t)current_dynamic_space,
352 (os_vm_address_t)SymbolValue(ALLOCATION_POINTER));
358 printf("Linking executable...\n");
360 obj_run_linker(init_function, filename);