Commit 94024436 authored by qinsoon's avatar qinsoon

[wip] working on make_boot_image

parent 82a97dfe
......@@ -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