/* 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; }