Save images to a temporary file first, then call MOVE_FILE to avoid writing incomplete and truncated images.
parent
07fcb43a06
commit
bb2f455747
|
@ -516,9 +516,9 @@ M: bad-executable summary
|
||||||
|
|
||||||
\ compact-gc { } { } define-primitive
|
\ compact-gc { } { } define-primitive
|
||||||
|
|
||||||
\ (save-image) { byte-array } { } define-primitive
|
\ (save-image) { byte-array byte-array } { } define-primitive
|
||||||
|
|
||||||
\ (save-image-and-exit) { byte-array } { } define-primitive
|
\ (save-image-and-exit) { byte-array byte-array } { } define-primitive
|
||||||
|
|
||||||
\ data-room { } { byte-array } define-primitive
|
\ data-room { } { byte-array } define-primitive
|
||||||
\ data-room make-flushable
|
\ data-room make-flushable
|
||||||
|
|
|
@ -511,8 +511,8 @@ tuple
|
||||||
{ "gc" "memory" "primitive_full_gc" (( -- )) }
|
{ "gc" "memory" "primitive_full_gc" (( -- )) }
|
||||||
{ "minor-gc" "memory" "primitive_minor_gc" (( -- )) }
|
{ "minor-gc" "memory" "primitive_minor_gc" (( -- )) }
|
||||||
{ "size" "memory" "primitive_size" (( obj -- n )) }
|
{ "size" "memory" "primitive_size" (( obj -- n )) }
|
||||||
{ "(save-image)" "memory.private" "primitive_save_image" (( path -- )) }
|
{ "(save-image)" "memory.private" "primitive_save_image" (( path1 path2 -- )) }
|
||||||
{ "(save-image-and-exit)" "memory.private" "primitive_save_image_and_exit" (( path -- )) }
|
{ "(save-image-and-exit)" "memory.private" "primitive_save_image_and_exit" (( path1 path2 -- )) }
|
||||||
{ "jit-compile" "quotations" "primitive_jit_compile" (( quot -- )) }
|
{ "jit-compile" "quotations" "primitive_jit_compile" (( quot -- )) }
|
||||||
{ "quot-compiled?" "quotations" "primitive_quot_compiled_p" (( quot -- ? )) }
|
{ "quot-compiled?" "quotations" "primitive_quot_compiled_p" (( quot -- ? )) }
|
||||||
{ "quotation-code" "quotations" "primitive_quotation_code" (( quot -- start end )) }
|
{ "quotation-code" "quotations" "primitive_quotation_code" (( quot -- start end )) }
|
||||||
|
|
|
@ -1,16 +1,20 @@
|
||||||
! Copyright (C) 2005, 2009 Slava Pestov.
|
! Copyright (C) 2005, 2009 Slava Pestov.
|
||||||
! See http://factorcode.org/license.txt for BSD license.
|
! See http://factorcode.org/license.txt for BSD license.
|
||||||
USING: kernel continuations sequences system
|
USING: alien.strings io.backend io.pathnames kernel
|
||||||
io.backend alien.strings memory.private ;
|
memory.private sequences system ;
|
||||||
IN: memory
|
IN: memory
|
||||||
|
|
||||||
: instances ( quot -- seq )
|
: instances ( quot -- seq )
|
||||||
[ all-instances ] dip filter ; inline
|
[ all-instances ] dip filter ; inline
|
||||||
|
|
||||||
|
: saving-path ( path -- saving-path path )
|
||||||
|
[ ".saving" append-path ] keep
|
||||||
|
[ native-string>alien ] bi@ ;
|
||||||
|
|
||||||
: save-image ( path -- )
|
: save-image ( path -- )
|
||||||
normalize-path native-string>alien (save-image) ;
|
normalize-path saving-path (save-image) ;
|
||||||
|
|
||||||
: save-image-and-exit ( path -- )
|
: save-image-and-exit ( path -- )
|
||||||
normalize-path native-string>alien (save-image-and-exit) ;
|
normalize-path saving-path (save-image-and-exit) ;
|
||||||
|
|
||||||
: save ( -- ) image save-image ;
|
: save ( -- ) image save-image ;
|
||||||
|
|
|
@ -442,7 +442,7 @@ void factor_vm::factorbug()
|
||||||
else if(strcmp(cmd,"x") == 0)
|
else if(strcmp(cmd,"x") == 0)
|
||||||
exit(1);
|
exit(1);
|
||||||
else if(strcmp(cmd,"im") == 0)
|
else if(strcmp(cmd,"im") == 0)
|
||||||
save_image(STRING_LITERAL("fep.image"));
|
save_image(STRING_LITERAL("fep.image.saving"),STRING_LITERAL("fep.image"));
|
||||||
else if(strcmp(cmd,"data") == 0)
|
else if(strcmp(cmd,"data") == 0)
|
||||||
dump_objects(TYPE_COUNT);
|
dump_objects(TYPE_COUNT);
|
||||||
else if(strcmp(cmd,"refs") == 0)
|
else if(strcmp(cmd,"refs") == 0)
|
||||||
|
|
21
vm/image.cpp
21
vm/image.cpp
|
@ -268,12 +268,12 @@ void factor_vm::load_image(vm_parameters *p)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Save the current image to disk */
|
/* Save the current image to disk */
|
||||||
bool factor_vm::save_image(const vm_char *filename)
|
bool factor_vm::save_image(const vm_char *saving_filename, const vm_char *filename)
|
||||||
{
|
{
|
||||||
FILE* file;
|
FILE* file;
|
||||||
image_header h;
|
image_header h;
|
||||||
|
|
||||||
file = OPEN_WRITE(filename);
|
file = OPEN_WRITE(saving_filename);
|
||||||
if(file == NULL)
|
if(file == NULL)
|
||||||
{
|
{
|
||||||
std::cout << "Cannot open image file: " << filename << std::endl;
|
std::cout << "Cannot open image file: " << filename << std::endl;
|
||||||
|
@ -303,6 +303,7 @@ bool factor_vm::save_image(const vm_char *filename)
|
||||||
if(safe_fwrite(code->allocator->first_block(),h.code_size,1,file) != 1) ok = false;
|
if(safe_fwrite(code->allocator->first_block(),h.code_size,1,file) != 1) ok = false;
|
||||||
if(safe_fclose(file)) ok = false;
|
if(safe_fclose(file)) ok = false;
|
||||||
|
|
||||||
|
MOVE_FILE(saving_filename,filename);
|
||||||
if(!ok)
|
if(!ok)
|
||||||
std::cout << "save-image failed: " << strerror(errno) << std::endl;
|
std::cout << "save-image failed: " << strerror(errno) << std::endl;
|
||||||
|
|
||||||
|
@ -314,9 +315,11 @@ void factor_vm::primitive_save_image()
|
||||||
/* do a full GC to push everything into tenured space */
|
/* do a full GC to push everything into tenured space */
|
||||||
primitive_compact_gc();
|
primitive_compact_gc();
|
||||||
|
|
||||||
data_root<byte_array> path(ctx->pop(),this);
|
data_root<byte_array> path1(ctx->pop(),this);
|
||||||
path.untag_check(this);
|
path1.untag_check(this);
|
||||||
save_image((vm_char *)(path.untagged() + 1));
|
data_root<byte_array> path2(ctx->pop(),this);
|
||||||
|
path2.untag_check(this);
|
||||||
|
save_image((vm_char *)(path1.untagged() + 1 ),(vm_char *)(path2.untagged() + 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
void factor_vm::primitive_save_image_and_exit()
|
void factor_vm::primitive_save_image_and_exit()
|
||||||
|
@ -324,8 +327,10 @@ void factor_vm::primitive_save_image_and_exit()
|
||||||
/* We unbox this before doing anything else. This is the only point
|
/* We unbox this before doing anything else. This is the only point
|
||||||
where we might throw an error, so we have to throw an error here since
|
where we might throw an error, so we have to throw an error here since
|
||||||
later steps destroy the current image. */
|
later steps destroy the current image. */
|
||||||
data_root<byte_array> path(ctx->pop(),this);
|
data_root<byte_array> path1(ctx->pop(),this);
|
||||||
path.untag_check(this);
|
path1.untag_check(this);
|
||||||
|
data_root<byte_array> path2(ctx->pop(),this);
|
||||||
|
path2.untag_check(this);
|
||||||
|
|
||||||
/* strip out special_objects data which is set on startup anyway */
|
/* strip out special_objects data which is set on startup anyway */
|
||||||
for(cell i = 0; i < special_object_count; i++)
|
for(cell i = 0; i < special_object_count; i++)
|
||||||
|
@ -336,7 +341,7 @@ void factor_vm::primitive_save_image_and_exit()
|
||||||
false /* discard objects only reachable from stacks */);
|
false /* discard objects only reachable from stacks */);
|
||||||
|
|
||||||
/* Save the image */
|
/* Save the image */
|
||||||
if(save_image((vm_char *)(path.untagged() + 1)))
|
if(save_image((vm_char *)(path1.untagged() + 1), (vm_char *)(path2.untagged() + 1)))
|
||||||
exit(0);
|
exit(0);
|
||||||
else
|
else
|
||||||
exit(1);
|
exit(1);
|
||||||
|
|
|
@ -31,6 +31,15 @@ typedef char symbol_char;
|
||||||
|
|
||||||
#define OPEN_READ(path) fopen(path,"rb")
|
#define OPEN_READ(path) fopen(path,"rb")
|
||||||
#define OPEN_WRITE(path) fopen(path,"wb")
|
#define OPEN_WRITE(path) fopen(path,"wb")
|
||||||
|
#define MOVE_FILE(path1,path2) \
|
||||||
|
do {\
|
||||||
|
int ret = 0;\
|
||||||
|
do {\
|
||||||
|
ret = rename((path1),(path2));\
|
||||||
|
} while(ret < 0 && errno == EINTR);\
|
||||||
|
if(ret < 0)\
|
||||||
|
general_error(ERROR_IO,tag_fixnum(errno),false_object,NULL);\
|
||||||
|
}while(0)
|
||||||
|
|
||||||
#define print_native_string(string) print_string(string)
|
#define print_native_string(string) print_string(string)
|
||||||
|
|
||||||
|
|
|
@ -37,8 +37,13 @@ typedef wchar_t vm_char;
|
||||||
#define CELL_HEX_FORMAT "%lx"
|
#define CELL_HEX_FORMAT "%lx"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define OPEN_READ(path) _wfopen(path,L"rb")
|
#define OPEN_READ(path) _wfopen((path),L"rb")
|
||||||
#define OPEN_WRITE(path) _wfopen(path,L"wb")
|
#define OPEN_WRITE(path) _wfopen((path),L"wb")
|
||||||
|
#define MOVE_FILE(path1,path2) \
|
||||||
|
do {\
|
||||||
|
if(MoveFile((path1),(path2)) == 0)\
|
||||||
|
general_error(ERROR_IO,tag_fixnum(GetLastError()),false_object,NULL);\
|
||||||
|
} while(0)
|
||||||
|
|
||||||
/* Difference between Jan 1 00:00:00 1601 and Jan 1 00:00:00 1970 */
|
/* Difference between Jan 1 00:00:00 1601 and Jan 1 00:00:00 1970 */
|
||||||
#define EPOCH_OFFSET 0x019db1ded53e8000LL
|
#define EPOCH_OFFSET 0x019db1ded53e8000LL
|
||||||
|
|
|
@ -549,7 +549,7 @@ struct factor_vm
|
||||||
void init_objects(image_header *h);
|
void init_objects(image_header *h);
|
||||||
void load_data_heap(FILE *file, image_header *h, vm_parameters *p);
|
void load_data_heap(FILE *file, image_header *h, vm_parameters *p);
|
||||||
void load_code_heap(FILE *file, image_header *h, vm_parameters *p);
|
void load_code_heap(FILE *file, image_header *h, vm_parameters *p);
|
||||||
bool save_image(const vm_char *filename);
|
bool save_image(const vm_char *saving_filename, const vm_char *filename);
|
||||||
void primitive_save_image();
|
void primitive_save_image();
|
||||||
void primitive_save_image_and_exit();
|
void primitive_save_image_and_exit();
|
||||||
void fixup_data(cell data_offset, cell code_offset);
|
void fixup_data(cell data_offset, cell code_offset);
|
||||||
|
|
Loading…
Reference in New Issue