Esempio n. 1
0
/* Save the current image to disk */
bool save_image(const vm_char *filename)
{
	FILE* file;
	image_header h;

	file = OPEN_WRITE(filename);
	if(file == NULL)
	{
		print_string("Cannot open image file: "); print_native_string(filename); nl();
		print_string(strerror(errno)); nl();
		return false;
	}

	zone *tenured = &data->generations[data->tenured()];

	h.magic = image_magic;
	h.version = image_version;
	h.data_relocation_base = tenured->start;
	h.data_size = tenured->here - tenured->start;
	h.code_relocation_base = code.seg->start;
	h.code_size = heap_size(&code);

	h.t = T;
	h.bignum_zero = bignum_zero;
	h.bignum_pos_one = bignum_pos_one;
	h.bignum_neg_one = bignum_neg_one;

	for(cell i = 0; i < USER_ENV; i++)
		h.userenv[i] = (save_env_p(i) ? userenv[i] : F);

	bool ok = true;

	if(fwrite(&h,sizeof(image_header),1,file) != 1) ok = false;
	if(fwrite((void*)tenured->start,h.data_size,1,file) != 1) ok = false;
	if(fwrite(first_block(&code),h.code_size,1,file) != 1) ok = false;
	if(fclose(file)) ok = false;

	if(!ok)
	{
		print_string("save-image failed: "); print_string(strerror(errno)); nl();
	}

	return ok;
}
Esempio n. 2
0
void factor_vm::primitive_save_image_and_exit()
{
	/* 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
	later steps destroy the current image. */
	gc_root<byte_array> path(dpop(),this);
	path.untag_check(this);

	/* strip out userenv data which is set on startup anyway */
	for(cell i = 0; i < USER_ENV; i++)
	{
		if(!save_env_p(i)) userenv[i] = F;
	}

	/* do a full GC + code heap compaction */
	compact_code_heap();

	/* Save the image */
	if(save_image((vm_char *)(path.untagged() + 1)))
		exit(0);
	else
		exit(1);
}