GitLab will continue to be upgraded from 11.4.5-ce.0 on November 25th 2019 at 4.00pm (AEDT) to 5.00pm (AEDT) due to Critical Security Patch Availability. During the update, GitLab and Mattermost services will not be available.

Commit 94024436 authored by qinsoon's avatar qinsoon

[wip] working on make_boot_image

parent 82a97dfe
Pipeline #274 failed with stage
in 33 minutes and 53 seconds
......@@ -109,6 +109,7 @@ pub struct MuFunctionVersion {
orig_content: Option<FunctionContent>,
pub content: Option<FunctionContent>,
is_defined: bool,
is_compiled: bool,
pub context: FunctionContext,
......@@ -150,6 +151,7 @@ impl MuFunctionVersion {
orig_content: None,
content: None,
is_defined: false,
is_compiled: false,
context: FunctionContext::new(),
block_trace: None,
force_inline: false
......@@ -164,6 +166,7 @@ impl MuFunctionVersion {
orig_content: Some(content.clone()),
content: Some(content),
is_defined: true,
is_compiled: false,
context: context,
block_trace: None,
force_inline: false
......@@ -184,6 +187,13 @@ impl MuFunctionVersion {
self.content = Some(content);
}
pub fn is_compiled(&self) -> bool {
self.is_compiled
}
pub fn set_compiled(&mut self) {
self.is_compiled = true;
}
pub fn new_ssa(&mut self, id: MuID, ty: P<MuType>) -> P<TreeNode> {
let val = P(Value{
hdr: MuEntityHeader::unnamed(id),
......
......@@ -13,13 +13,13 @@ pub mod machine_code;
pub use compiler::passes::CompilerPass;
pub struct Compiler {
pub struct Compiler<'vm> {
policy: RefCell<CompilerPolicy>,
vm: Arc<VM>
vm: &'vm VM
}
impl Compiler {
pub fn new(policy: CompilerPolicy, vm: Arc<VM>) -> Compiler {
impl <'vm> Compiler<'vm> {
pub fn new(policy: CompilerPolicy, vm: &VM) -> Compiler {
Compiler{
policy: RefCell::new(policy),
vm: vm
......@@ -37,13 +37,15 @@ impl Compiler {
for pass in passes.iter_mut() {
let _p = hprof::enter(pass.name());
pass.execute(&self.vm, func);
pass.execute(self.vm, func);
drop(_p);
}
drop(_p);
hprof::profiler().print_timing();
func.set_compiled();
}
pub fn get_policy(&self) -> &RefCell<CompilerPolicy> {
......
......@@ -4,10 +4,10 @@
#include <string.h>
extern void* vm;
extern void mu_main(char* vm);
extern void mu_main(char*, int, char**);
extern void mu_trace_level_log();
int main() {
int main(int argc, char** argv) {
mu_trace_level_log();
printf("main(), going to launch mu_main()\n");
......@@ -15,5 +15,5 @@ int main() {
printf("%s\n", serialize_vm);
mu_main(serialize_vm);
mu_main(serialize_vm, argc, argv);
}
......@@ -6,6 +6,7 @@ use compiler::backend::RegGroup;
use utils::Address;
use std::fmt;
use std::os::raw::c_int;
use std::os::raw::c_char;
use std::os::raw::c_void;
use std::ffi::CString;
......@@ -192,7 +193,7 @@ pub extern fn mu_trace_level_log() {
}
#[no_mangle]
pub extern fn mu_main(serialized_vm : *const c_char) {
pub extern fn mu_main(serialized_vm : *const c_char, argc: c_int, argv: *const *const c_char) {
debug!("mu_main() started...");
let str_vm = unsafe{CStr::from_ptr(serialized_vm)}.to_str().unwrap();
......@@ -207,8 +208,22 @@ pub extern fn mu_main(serialized_vm : *const c_char) {
// create mu stack
let stack = vm.new_stack(primordial.func_id);
let args : Vec<ValueLocation> = primordial.args.iter().map(|arg| ValueLocation::from_constant(arg.clone())).collect();
// if the primordial named some const arguments, we use the const args
// otherwise we push 'argc' and 'argv' to new stack
let args : Vec<ValueLocation> = if primordial.has_const_args {
primordial.args.iter().map(|arg| ValueLocation::from_constant(arg.clone())).collect()
} else {
let mut args = vec![];
// 1st arg: argc
args.push(ValueLocation::from_constant(Constant::Int(argc as u64)));
// 2nd arg: argv
args.push(ValueLocation::from_constant(Constant::Int(argv as u64)));
args
};
// FIXME: currently assumes no user defined thread local
// will need to fix this after we can serialize heap object
......
......@@ -417,5 +417,7 @@ impl MuThread {
#[derive(Debug, RustcEncodable, RustcDecodable)]
pub struct MuPrimordialThread {
pub func_id: MuID,
pub has_const_args: bool,
pub args: Vec<Constant>
}
......@@ -62,7 +62,7 @@ pub fn compile_fnc<'a>(fnc_name: &'static str, build_fnc: &'a Fn() -> VM) -> ll:
VM::start_logging_trace();
let vm = Arc::new(build_fnc());
let compiler = Compiler::new(CompilerPolicy::default(), vm.clone());
let compiler = Compiler::new(CompilerPolicy::default(), &vm);
let func_id = vm.id_of(fnc_name);
{
let funcs = vm.funcs().read().unwrap();
......@@ -81,7 +81,7 @@ pub fn compile_fncs<'a>(entry: &'static str, fnc_names: Vec<&'static str>, build
VM::start_logging_trace();
let vm = Arc::new(build_fnc());
let compiler = Compiler::new(CompilerPolicy::default(), vm.clone());
let compiler = Compiler::new(CompilerPolicy::default(), &vm);
for func in fnc_names.iter() {
let func_id = vm.id_of(func);
......
......@@ -80,7 +80,7 @@ impl MuVM {
use compiler::*;
use testutil::aot;
let compiler = Compiler::new(CompilerPolicy::default(), self.vm.clone());
let compiler = Compiler::new(CompilerPolicy::default(), &self.vm);
let funcs = self.vm.funcs().read().unwrap();
let mut func_names = vec![];
// NOTE: this fails because load() API call is not properly implemented yet.
......
......@@ -5,6 +5,7 @@ use ast::ir::*;
use ast::inst::*;
use ast::types;
use ast::types::*;
use compiler::{Compiler, CompilerPolicy};
use compiler::backend;
use compiler::backend::BackendTypeInfo;
use compiler::machine_code::CompiledFunction;
......@@ -937,16 +938,49 @@ impl <'a> VM {
Box::new(MuStack::new(self.next_id(), self.resolve_function_address(func_id), func))
}
pub fn make_primordial_thread(&self, func_id: MuID, args: Vec<Constant>) {
pub fn make_primordial_thread(&self, func_id: MuID, has_const_args: bool, args: Vec<Constant>) {
let mut guard = self.primordial.write().unwrap();
*guard = Some(MuPrimordialThread{func_id: func_id, args: args});
*guard = Some(MuPrimordialThread{func_id: func_id, has_const_args: has_const_args, args: args});
}
#[allow(unused_variables)]
pub fn make_boot_image(self, output: &path::Path) {
pub fn make_boot_image(&mut self,
whitelist: Vec<MuID>,
primordial_func: Option<&APIHandle>, primordial_stack: Option<&APIHandle>,
primordial_threadlocal: Option<&APIHandle>,
sym_fields: Vec<&APIHandle>, sym_strings: Vec<String>,
reloc_fields: Vec<&APIHandle>, reloc_strings: Vec<String>,
output_file: String) {
use rustc_serialize::json;
let compiler = Compiler::new(CompilerPolicy::default(), self);
let funcs = self.funcs().write().unwrap();
let func_vers = self.func_vers().write().unwrap();
// make sure all functions in whitelist are compiled
for &id in whitelist.iter() {
if let Some(f) = funcs.get(&id) {
let f : &MuFunction = &f.read().unwrap();
match f.cur_ver {
Some(fv_id) => {
let mut func_ver = func_vers.get(&fv_id).unwrap().write().unwrap();
if !func_ver.is_compiled() {
compiler.compile(&mut func_ver);
}
}
None => panic!("whitelist function {} has no version defined", f)
}
}
}
// make sure only one of primordial_func or primoridial_stack is set
assert!(
(primordial_func.is_some() && primordial_stack.is_none())
|| (primordial_func.is_none() && primordial_stack.is_some())
);
let serialized = json::encode(&self).unwrap();
let serialized = json::encode(self).unwrap();
unimplemented!()
}
......
......@@ -22,7 +22,7 @@ fn test_instruction_new() {
let vm = Arc::new(alloc_new());
let compiler = Compiler::new(CompilerPolicy::default(), vm.clone());
let compiler = Compiler::new(CompilerPolicy::default(), &vm);
let func_id = vm.id_of("alloc_new");
{
......@@ -34,7 +34,7 @@ fn test_instruction_new() {
compiler.compile(&mut func_ver);
}
vm.make_primordial_thread(func_id, vec![]);
vm.make_primordial_thread(func_id, true, vec![]);
backend::emit_context(&vm);
let executable = aot::link_primordial(vec!["alloc_new".to_string()], "alloc_new_test", &vm);
......@@ -52,7 +52,7 @@ fn test_instruction_new_on_cur_thread() {
// compile
let vm = Arc::new(alloc_new());
let compiler = Compiler::new(CompilerPolicy::default(), vm.clone());
let compiler = Compiler::new(CompilerPolicy::default(), &vm);
let func_id = vm.id_of("alloc_new");
{
let funcs = vm.funcs().read().unwrap();
......
......@@ -16,7 +16,7 @@ fn test_ccall_exit() {
let vm = Arc::new(ccall_exit());
let compiler = Compiler::new(CompilerPolicy::default(), vm.clone());
let compiler = Compiler::new(CompilerPolicy::default(), &vm);
let func_id = vm.id_of("ccall_exit");
{
......@@ -28,7 +28,7 @@ fn test_ccall_exit() {
compiler.compile(&mut func_ver);
}
vm.make_primordial_thread(func_id, vec![]);
vm.make_primordial_thread(func_id, true, vec![]);
backend::emit_context(&vm);
let executable = aot::link_primordial(vec!["ccall_exit".to_string()], "ccall_exit_test", &vm);
......
......@@ -19,7 +19,7 @@ fn test_exception_simple_throw_catch() {
VM::start_logging_trace();
let vm = Arc::new(simple_throw_catch());
let compiler = Compiler::new(CompilerPolicy::default(), vm.clone());
let compiler = Compiler::new(CompilerPolicy::default(), &vm);
let func_throw = vm.id_of("throw_exception");
let func_catch = vm.id_of("catch_exception");
......@@ -41,7 +41,7 @@ fn test_exception_simple_throw_catch() {
}
}
vm.make_primordial_thread(func_catch, vec![]);
vm.make_primordial_thread(func_catch, true, vec![]);
backend::emit_context(&vm);
let executable = aot::link_primordial(vec![Mu("throw_exception"), Mu("catch_exception")], "simple_throw_catch_test", &vm);
......
......@@ -30,7 +30,7 @@ fn test_global_access() {
}
global_access(&vm);
let compiler = Compiler::new(CompilerPolicy::default(), vm.clone());
let compiler = Compiler::new(CompilerPolicy::default(), &vm);
{
let func_id = vm.id_of("global_access");
......@@ -54,7 +54,7 @@ fn test_set_global_by_api() {
}
set_global_by_api(&vm);
let compiler = Compiler::new(CompilerPolicy::default(), vm.clone());
let compiler = Compiler::new(CompilerPolicy::default(), &vm);
let func_id = vm.id_of("set_global_by_api");
{
......@@ -78,7 +78,7 @@ fn test_set_global_by_api() {
}
// then emit context (global will be put into context.s
vm.make_primordial_thread(func_id, vec![]);
vm.make_primordial_thread(func_id, true, vec![]);
backend::emit_context(&vm);
// link
......@@ -136,7 +136,7 @@ fn test_get_global_in_dylib() {
}
get_global_in_dylib(&vm);
let compiler = Compiler::new(CompilerPolicy::default(), vm.clone());
let compiler = Compiler::new(CompilerPolicy::default(), &vm);
let func_id = vm.id_of("get_global_in_dylib");
{
......@@ -218,7 +218,7 @@ fn test_persist_linked_list() {
}
persist_linked_list(&vm);
let compiler = Compiler::new(CompilerPolicy::default(), vm.clone());
let compiler = Compiler::new(CompilerPolicy::default(), &vm);
let func_id = vm.id_of("persist_linked_list");
{
......@@ -267,7 +267,7 @@ fn test_persist_linked_list() {
}
// then emit context (global will be put into context.s
vm.make_primordial_thread(func_id, vec![]);
vm.make_primordial_thread(func_id, true, vec![]);
backend::emit_context(&vm);
// link
......@@ -429,7 +429,7 @@ fn test_persist_hybrid() {
}
persist_hybrid(&vm);
let compiler = Compiler::new(CompilerPolicy::default(), vm.clone());
let compiler = Compiler::new(CompilerPolicy::default(), &vm);
let func_id = vm.id_of("persist_hybrid");
{
......@@ -476,7 +476,7 @@ fn test_persist_hybrid() {
}
// then emit context (global will be put into context.s
vm.make_primordial_thread(func_id, vec![Constant::Int(HYBRID_LENGTH as u64)]);
vm.make_primordial_thread(func_id, true, vec![Constant::Int(HYBRID_LENGTH as u64)]);
backend::emit_context(&vm);
// link
......
......@@ -18,7 +18,7 @@ fn test_instsel_fac() {
Box::new(passes::ControlFlowAnalysis::new()),
Box::new(passes::TraceGen::new()),
Box::new(backend::inst_sel::InstructionSelection::new())
]), vm.clone());
]), &vm);
let func_id = vm.id_of("fac");
let funcs = vm.funcs().read().unwrap();
......
......@@ -18,7 +18,7 @@ fn test_struct() {
let vm = Arc::new(struct_insts_macro());
let compiler = Compiler::new(CompilerPolicy::default(), vm.clone());
let compiler = Compiler::new(CompilerPolicy::default(), &vm);
let func_id = vm.id_of("struct_insts");
{
......@@ -30,7 +30,7 @@ fn test_struct() {
compiler.compile(&mut func_ver);
}
vm.make_primordial_thread(func_id, vec![]);
vm.make_primordial_thread(func_id, true, vec![]);
backend::emit_context(&vm);
let executable = aot::link_primordial(vec!["struct_insts".to_string()], "struct_insts_test", &vm);
......@@ -392,7 +392,7 @@ fn test_hybrid_fix_part() {
let vm = Arc::new(hybrid_fix_part_insts());
let compiler = Compiler::new(CompilerPolicy::default(), vm.clone());
let compiler = Compiler::new(CompilerPolicy::default(), &vm);
let func_id = vm.id_of("hybrid_fix_part_insts");
{
......@@ -404,7 +404,7 @@ fn test_hybrid_fix_part() {
compiler.compile(&mut func_ver);
}
vm.make_primordial_thread(func_id, vec![]);
vm.make_primordial_thread(func_id, true, vec![]);
backend::emit_context(&vm);
let executable = aot::link_primordial(vec!["hybrid_fix_part_insts".to_string()], "hybrid_fix_part_insts_test", &vm);
......@@ -672,7 +672,7 @@ fn test_hybrid_var_part() {
let vm = Arc::new(hybrid_var_part_insts());
let compiler = Compiler::new(CompilerPolicy::default(), vm.clone());
let compiler = Compiler::new(CompilerPolicy::default(), &vm);
let func_id = vm.id_of("hybrid_var_part_insts");
{
......@@ -684,7 +684,7 @@ fn test_hybrid_var_part() {
compiler.compile(&mut func_ver);
}
vm.make_primordial_thread(func_id, vec![]);
vm.make_primordial_thread(func_id, true, vec![]);
backend::emit_context(&vm);
let executable = aot::link_primordial(vec!["hybrid_var_part_insts".to_string()], "hybrid_var_part_insts_test", &vm);
......
......@@ -15,7 +15,7 @@ fn test_use_count() {
let vm = Arc::new(factorial());
let compiler = Compiler::new(CompilerPolicy::new(
vec![Box::new(passes::DefUse::new())]
), vm.clone());
), &vm);
let func_id = vm.id_of("fac");
let funcs = vm.funcs().read().unwrap();
......@@ -42,7 +42,7 @@ fn test_build_tree() {
let compiler = Compiler::new(CompilerPolicy::new(
vec![Box::new(passes::DefUse::new()),
Box::new(passes::TreeGen::new())]
), vm.clone());
), &vm);
let func_id = vm.id_of("fac");
let funcs = vm.funcs().read().unwrap();
......@@ -116,7 +116,7 @@ fn test_cfa_factorial() {
Box::new(passes::TreeGen::new()),
Box::new(passes::GenMovPhi::new()),
Box::new(passes::ControlFlowAnalysis::new())
]), vm.clone());
]), &vm);
let func_id = vm.id_of("fac");
let funcs = vm.funcs().read().unwrap();
......@@ -162,7 +162,7 @@ fn test_cfa_sum() {
Box::new(passes::TreeGen::new()),
Box::new(passes::GenMovPhi::new()),
Box::new(passes::ControlFlowAnalysis::new())
]), vm.clone());
]), &vm);
let func_id = vm.id_of("sum");
let funcs = vm.funcs().read().unwrap();
......@@ -228,7 +228,7 @@ fn test_trace_factorial() {
Box::new(passes::GenMovPhi::new()),
Box::new(passes::ControlFlowAnalysis::new()),
Box::new(passes::TraceGen::new())
]), vm.clone());
]), &vm);
let func_id = vm.id_of("fac");
let funcs = vm.funcs().read().unwrap();
......@@ -255,7 +255,7 @@ fn test_trace_sum() {
Box::new(passes::GenMovPhi::new()),
Box::new(passes::ControlFlowAnalysis::new()),
Box::new(passes::TraceGen::new())
]), vm.clone());
]), &vm);
let func_id = vm.id_of("sum");
let funcs = vm.funcs().read().unwrap();
......
......@@ -44,7 +44,7 @@ fn test_ir_liveness_fac() {
Box::new(passes::ControlFlowAnalysis::new()),
Box::new(passes::TraceGen::new()),
Box::new(backend::inst_sel::InstructionSelection::new()),
]), vm.clone());
]), &vm);
let func_id = vm.id_of("fac");
let funcs = vm.funcs().read().unwrap();
......@@ -96,7 +96,7 @@ fn test_spill1() {
let vm = Arc::new(create_spill1());
let compiler = Compiler::new(CompilerPolicy::default(), vm.clone());
let compiler = Compiler::new(CompilerPolicy::default(), &vm);
let func_id = vm.id_of("spill1");
{
......@@ -298,7 +298,7 @@ fn test_simple_spill() {
let vm = Arc::new(create_simple_spill());
let compiler = Compiler::new(CompilerPolicy::default(), vm.clone());
let compiler = Compiler::new(CompilerPolicy::default(), &vm);
let func_id = vm.id_of("simple_spill");
{
......@@ -591,7 +591,7 @@ fn test_coalesce_branch_moves() {
let vm = Arc::new(coalesce_branch_moves());
let compiler = Compiler::new(CompilerPolicy::default(), vm.clone());
let compiler = Compiler::new(CompilerPolicy::default(), &vm);
let func_id = vm.id_of("coalesce_branch_moves");
{
......@@ -659,7 +659,7 @@ fn test_coalesce_args() {
let vm = Arc::new(coalesce_args());
let compiler = Compiler::new(CompilerPolicy::default(), vm.clone());
let compiler = Compiler::new(CompilerPolicy::default(), &vm);
let func_id = vm.id_of("coalesce_args");
{
......@@ -719,7 +719,7 @@ fn test_coalesce_branch2_moves() {
let vm = Arc::new(coalesce_branch2_moves());
let compiler = Compiler::new(CompilerPolicy::default(), vm.clone());
let compiler = Compiler::new(CompilerPolicy::default(), &vm);
let func_id = vm.id_of("coalesce_branch2_moves");
{
......
......@@ -20,7 +20,7 @@ fn test_thread_create() {
let vm = Arc::new(primordial_main());
let compiler = Compiler::new(CompilerPolicy::default(), vm.clone());
let compiler = Compiler::new(CompilerPolicy::default(), &vm);
let func_id = vm.id_of("primordial_main");
{
......@@ -32,7 +32,7 @@ fn test_thread_create() {
compiler.compile(&mut func_ver);
}
vm.make_primordial_thread(func_id, vec![]);
vm.make_primordial_thread(func_id, true, vec![]);
backend::emit_context(&vm);
let executable = aot::link_primordial(vec!["primordial_main".to_string()], "primordial_main_test", &vm);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment