Esempio n. 1
0
/* Save the current image to disk. We don't throw any exceptions here
   because if the 'then-die' argument is t it is not safe to do
   so. Instead we signal failure by returning false. */
bool factor_vm::save_image(const vm_char* saving_filename,
                           const vm_char* filename) {
  image_header h;

  h.magic = image_magic;
  h.version = image_version;
  h.data_relocation_base = data->tenured->start;
  h.data_size = data->tenured->occupied_space();
  h.code_relocation_base = code->allocator->start;
  h.code_size = code->allocator->occupied_space();

  for (cell i = 0; i < special_object_count; i++)
    h.special_objects[i] =
        (save_special_p(i) ? special_objects[i] : false_object);

  FILE* file = OPEN_WRITE(saving_filename);
  if (file == NULL)
    return false;
  if (safe_fwrite(&h, sizeof(image_header), 1, file) != 1)
    return false;
  if (safe_fwrite((void*)data->tenured->start, h.data_size, 1, file) != 1)
    return false;
  if (safe_fwrite((void*)code->allocator->start, h.code_size, 1, file) != 1)
    return false;
  if (raw_fclose(file) == -1)
    return false;
  if (!move_file(saving_filename, filename))
    return false;
  return true;
}
Esempio n. 2
0
// Allocates memory
void factor_vm::primitive_save_image() {
  // 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.
  bool then_die = to_boolean(ctx->pop());
  byte_array* path2 = untag_check<byte_array>(ctx->pop());
  byte_array* path1 = untag_check<byte_array>(ctx->pop());

  // Copy the paths to non-gc memory to avoid them hanging around in
  // the saved image.
  vm_char* path1_saved = safe_strdup(path1->data<vm_char>());
  vm_char* path2_saved = safe_strdup(path2->data<vm_char>());

  if (then_die) {
    // strip out special_objects data which is set on startup anyway
    for (cell i = 0; i < special_object_count; i++)
      if (!save_special_p(i))
        special_objects[i] = false_object;

    // dont trace objects only reachable from context stacks so we don't
    // get volatile data saved in the image.
    active_contexts.clear();
    code->uninitialized_blocks.clear();

    // I think clearing the callback heap should be fine too.
    callbacks->allocator->initial_free_list(0);
  }

  // do a full GC to push everything remaining into tenured space
  primitive_compact_gc();

  // Save the image
  bool ret = save_image(path1_saved, path2_saved);
  if (then_die) {
    exit(ret ? 0 : 1);
  }
  free(path1_saved);
  free(path2_saved);

  if (!ret) {
    general_error(ERROR_IO, tag_fixnum(errno), false_object);
  }
}
Esempio n. 3
0
/* Save the current image to disk */
bool factor_vm::save_image(const vm_char *saving_filename, const vm_char *filename)
{
	FILE* file;
	image_header h;

	file = OPEN_WRITE(saving_filename);
	if(file == NULL)
	{
		std::cout << "Cannot open image file: " << saving_filename << std::endl;
		std::cout << strerror(errno) << std::endl;
		return false;
	}

	h.magic = image_magic;
	h.version = image_version;
	h.data_relocation_base = data->tenured->start;
	h.data_size = data->tenured->occupied_space();
	h.code_relocation_base = code->seg->start;
	h.code_size = code->allocator->occupied_space();

	h.true_object = true_object;
	h.bignum_zero = bignum_zero;
	h.bignum_pos_one = bignum_pos_one;
	h.bignum_neg_one = bignum_neg_one;

	for(cell i = 0; i < special_object_count; i++)
		h.special_objects[i] = (save_special_p(i) ? special_objects[i] : false_object);

	bool ok = true;

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

	if(!ok)
		std::cout << "save-image failed: " << strerror(errno) << std::endl;
	else
		move_file(saving_filename,filename); 

	return ok;
}
Esempio n. 4
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. */
	data_root<byte_array> path(ctx->pop(),this);
	path.untag_check(this);

	/* strip out special_objects data which is set on startup anyway */
	for(cell i = 0; i < special_object_count; i++)
		if(!save_special_p(i)) special_objects[i] = false_object;

	gc(collect_compact_op,
		0, /* requested size */
		false /* discard objects only reachable from stacks */);

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