/* Might GC */
code_block *factor_vm::add_code_block(code_block_type type, cell code_, cell labels_,
	cell owner_, cell relocation_, cell parameters_, cell literals_,
	cell frame_size_untagged)
{
	data_root<byte_array> code(code_,this);
	data_root<object> labels(labels_,this);
	data_root<object> owner(owner_,this);
	data_root<byte_array> relocation(relocation_,this);
	data_root<array> parameters(parameters_,this);
	data_root<array> literals(literals_,this);

	cell code_length = array_capacity(code.untagged());
	code_block *compiled = allot_code_block(code_length,type);

	compiled->owner = owner.value();

	/* slight space optimization */
	if(relocation.type() == BYTE_ARRAY_TYPE && array_capacity(relocation.untagged()) == 0)
		compiled->relocation = false_object;
	else
		compiled->relocation = relocation.value();

	if(parameters.type() == ARRAY_TYPE && array_capacity(parameters.untagged()) == 0)
		compiled->parameters = false_object;
	else
		compiled->parameters = parameters.value();

	/* code */
	memcpy(compiled + 1,code.untagged() + 1,code_length);

	/* fixup labels */
	if(to_boolean(labels.value()))
		fixup_labels(labels.as<array>().untagged(),compiled);

	compiled->set_stack_frame_size(frame_size_untagged);

	/* Once we are ready, fill in literal and word references in this code
	block's instruction operands. In most cases this is done right after this
	method returns, except when compiling words with the non-optimizing
	compiler at the beginning of bootstrap */
	this->code->uninitialized_blocks.insert(std::make_pair(compiled,literals.value()));
	this->code->all_blocks.insert((cell)compiled);

	/* next time we do a minor GC, we have to trace this code block, since
	the fields of the code_block struct might point into nursery or aging */
	this->code->write_barrier(compiled);

	return compiled;
}
/* Might GC */
code_block *factor_vm::add_code_block(code_block_type type, cell code_, cell labels_, cell owner_, cell relocation_, cell parameters_, cell literals_)
{
	data_root<byte_array> code(code_,this);
	data_root<object> labels(labels_,this);
	data_root<object> owner(owner_,this);
	data_root<byte_array> relocation(relocation_,this);
	data_root<array> parameters(parameters_,this);
	data_root<array> literals(literals_,this);

	cell code_length = array_capacity(code.untagged());
	code_block *compiled = allot_code_block(code_length,type);

	compiled->owner = owner.value();

	/* slight space optimization */
	if(relocation.type() == BYTE_ARRAY_TYPE && array_capacity(relocation.untagged()) == 0)
		compiled->relocation = false_object;
	else
		compiled->relocation = relocation.value();

	if(parameters.type() == ARRAY_TYPE && array_capacity(parameters.untagged()) == 0)
		compiled->parameters = false_object;
	else
		compiled->parameters = parameters.value();

	/* code */
	memcpy(compiled + 1,code.untagged() + 1,code_length);

	/* fixup labels */
	if(to_boolean(labels.value()))
		fixup_labels(labels.as<array>().untagged(),compiled);

	/* next time we do a minor GC, we have to scan the code heap for
	literals */
	this->code->write_barrier(compiled);
	this->code->uninitialized_blocks.insert(std::make_pair(compiled,literals.value()));

	return compiled;
}