Commit 36df60dc authored by qinsoon's avatar qinsoon

[wip] totally lost on what I am doing

parent f3670528
...@@ -19,4 +19,5 @@ nalgebra = "0.8.2" ...@@ -19,4 +19,5 @@ nalgebra = "0.8.2"
linked-hash-map = "0.0.10" linked-hash-map = "0.0.10"
hprof = "0.1.3" hprof = "0.1.3"
memmap = "0.4.0" memmap = "0.4.0"
memsec = "0.1.9" memsec = "0.1.9"
\ No newline at end of file rustc-serialize = "0.3"
\ No newline at end of file
...@@ -1156,6 +1156,15 @@ pub fn emit_context(vm: &VM) { ...@@ -1156,6 +1156,15 @@ pub fn emit_context(vm: &VM) {
file.write("\n".as_bytes()).unwrap(); file.write("\n".as_bytes()).unwrap();
} }
// serialize vm
unimplemented!();
// main_thread
let primordial = vm.primordial.read().unwrap();
if primordial.is_some() {
let primordial = primordial.as_ref().unwrap();
}
debug!("---finish---"); debug!("---finish---");
} }
......
...@@ -5,11 +5,14 @@ pub mod code_emission; ...@@ -5,11 +5,14 @@ pub mod code_emission;
use utils::ByteSize; use utils::ByteSize;
pub type Word = usize;
pub const WORD_SIZE : ByteSize = 8;
// X86_64 // X86_64
#[cfg(target_arch = "x86_64")] #[cfg(target_arch = "x86_64")]
#[path = "arch/x86_64/mod.rs"] #[path = "arch/x86_64/mod.rs"]
mod x86_64; pub mod x86_64;
#[cfg(target_arch = "x86_64")] #[cfg(target_arch = "x86_64")]
pub use compiler::backend::x86_64::init_machine_regs_for_func; pub use compiler::backend::x86_64::init_machine_regs_for_func;
......
...@@ -3,11 +3,30 @@ pub extern crate immix_rust as gc; ...@@ -3,11 +3,30 @@ pub extern crate immix_rust as gc;
pub use gc::common::Address; pub use gc::common::Address;
pub use gc::common::ObjectReference; pub use gc::common::ObjectReference;
pub type Word = usize;
pub mod thread; pub mod thread;
pub enum RuntimeValue { use ast::ir::*;
Pointer(Address), use compiler::backend::Word;
Value(Word) use compiler::backend::RegGroup;
#[derive(Clone, Copy, Debug)]
pub enum ValueLocation {
Register(RegGroup, MuID),
Direct(RegGroup, Address),
Indirect(RegGroup, Address),
Constant(RegGroup, Word),
Relocatable(RegGroup, MuName)
}
impl ValueLocation {
pub fn load_value(&self) -> (RegGroup, Word) {
match self {
&ValueLocation::Register(_, _)
| &ValueLocation::Direct(_, _)
| &ValueLocation::Indirect(_, _)
| &ValueLocation::Constant(_, _) => unimplemented!(),
&ValueLocation::Relocatable(_, _) => panic!("expect a runtime value")
}
}
} }
\ No newline at end of file
...@@ -3,6 +3,8 @@ ...@@ -3,6 +3,8 @@
__thread void* mu_tls; __thread void* mu_tls;
void* init_thread_local(void* local) { void* init_thread_local(void** local) {
return NULL; mu_tls = *local;
return &mu_tls;
} }
...@@ -4,7 +4,7 @@ use ast::ir::*; ...@@ -4,7 +4,7 @@ use ast::ir::*;
use ast::ptr::*; use ast::ptr::*;
use ast::types::*; use ast::types::*;
use vm::VM; use vm::VM;
use runtime::RuntimeValue; use runtime::ValueLocation;
use runtime::gc; use runtime::gc;
use utils::ByteSize; use utils::ByteSize;
...@@ -27,9 +27,8 @@ impl_mu_entity!(MuStack); ...@@ -27,9 +27,8 @@ impl_mu_entity!(MuStack);
pub struct MuStack { pub struct MuStack {
pub hdr: MuEntityHeader, pub hdr: MuEntityHeader,
func_id: MuID, func_addr: ValueLocation,
func_id: MuID,
state: MuStackState,
size: ByteSize, size: ByteSize,
// lo addr hi addr // lo addr hi addr
...@@ -49,12 +48,13 @@ pub struct MuStack { ...@@ -49,12 +48,13 @@ pub struct MuStack {
exception_obj : Option<Address>, exception_obj : Option<Address>,
state: MuStackState,
#[allow(dead_code)] #[allow(dead_code)]
mmap : memmap::Mmap mmap : memmap::Mmap
} }
impl MuStack { impl MuStack {
pub fn new(id: MuID, func: &MuFunction) -> MuStack { pub fn new(id: MuID, func_addr: ValueLocation, func: &MuFunction) -> MuStack {
let total_size = PAGE_SIZE * 2 + STACK_SIZE; let total_size = PAGE_SIZE * 2 + STACK_SIZE;
let anon_mmap = match memmap::Mmap::anonymous(total_size, memmap::Protection::ReadWrite) { let anon_mmap = match memmap::Mmap::anonymous(total_size, memmap::Protection::ReadWrite) {
...@@ -83,6 +83,7 @@ impl MuStack { ...@@ -83,6 +83,7 @@ impl MuStack {
MuStack { MuStack {
hdr: MuEntityHeader::unnamed(id), hdr: MuEntityHeader::unnamed(id),
func_addr: func_addr,
func_id: func.id(), func_id: func.id(),
state: MuStackState::Ready(func.sig.arg_tys.clone()), state: MuStackState::Ready(func.sig.arg_tys.clone()),
...@@ -102,6 +103,61 @@ impl MuStack { ...@@ -102,6 +103,61 @@ impl MuStack {
mmap: anon_mmap mmap: anon_mmap
} }
} }
#[cfg(target_arch = "x86_64")]
pub fn runtime_load_args(&mut self, vals: Vec<ValueLocation>) {
use compiler::backend::Word;
use compiler::backend::WORD_SIZE;
use compiler::backend::RegGroup;
use compiler::backend::x86_64;
let mut gpr_used = vec![];
let mut fpr_used = vec![];
for i in 0..vals.len() {
let ref val = vals[i];
let (reg_group, word) = val.load_value();
match reg_group {
RegGroup::GPR => gpr_used.push(word),
RegGroup::FPR => fpr_used.push(word),
}
}
let mut stack_ptr = self.sp;
for i in 0..x86_64::ARGUMENT_FPRs.len() {
stack_ptr = stack_ptr.sub(WORD_SIZE);
let val = {
if i < fpr_used.len() {
fpr_used[i]
} else {
0 as Word
}
};
debug!("store {} to {}", val, stack_ptr);
unsafe {stack_ptr.store(val);}
}
for i in 0..x86_64::ARGUMENT_GPRs.len() {
stack_ptr = stack_ptr.sub(WORD_SIZE);
let val = {
if i < gpr_used.len() {
gpr_used[i]
} else {
0 as Word
}
};
debug!("store {} to {}", val, stack_ptr);
unsafe {stack_ptr.store(val);}
}
// should have put 6 + 6 words on the stack
debug_assert!(self.sp.diff(stack_ptr) == 12 * WORD_SIZE);
// save it back
self.sp = stack_ptr;
}
} }
pub enum MuStackState { pub enum MuStackState {
...@@ -118,6 +174,13 @@ pub struct MuThread { ...@@ -118,6 +174,13 @@ pub struct MuThread {
user_tls: Option<Address> user_tls: Option<Address>
} }
#[cfg(target_arch = "x86_64")]
#[cfg(target_os = "macos")]
#[link(name = "runtime")]
extern "C" {
fn init_thread_local(thread: &Box<MuThread>) -> Address;
}
impl MuThread { impl MuThread {
pub fn new(id: MuID, allocator: Box<gc::Mutator>, stack: Box<MuStack>, user_tls: Option<Address>) -> MuThread { pub fn new(id: MuID, allocator: Box<gc::Mutator>, stack: Box<MuStack>, user_tls: Option<Address>) -> MuThread {
MuThread { MuThread {
...@@ -128,10 +191,15 @@ impl MuThread { ...@@ -128,10 +191,15 @@ impl MuThread {
} }
} }
pub fn launch(id: MuID, stack: Box<MuStack>, user_tls: Option<Address>, vals: Vec<RuntimeValue>, vm: &VM) -> JoinHandle<()> { #[no_mangle]
pub extern fn mu_thread_launch(id: MuID, stack: Box<MuStack>, user_tls: Option<Address>, vm: &VM) -> JoinHandle<()> {
match thread::Builder::new().name(format!("Mu Thread #{}", id)).spawn(move || { match thread::Builder::new().name(format!("Mu Thread #{}", id)).spawn(move || {
let mut muthread = Box::new(MuThread::new(id, gc::new_mutator(), stack, user_tls)); let muthread = Box::new(MuThread::new(id, gc::new_mutator(), stack, user_tls));
MuThread::thread_entry(muthread, vm);
// set thread local
let addr = unsafe {init_thread_local(&muthread)};
MuThread::thread_entry(muthread);
}) { }) {
Ok(handle) => handle, Ok(handle) => handle,
Err(_) => panic!("failed to create a thread") Err(_) => panic!("failed to create a thread")
...@@ -139,7 +207,14 @@ impl MuThread { ...@@ -139,7 +207,14 @@ impl MuThread {
} }
/// entry function for launching a mu thread /// entry function for launching a mu thread
pub fn thread_entry(mu_thread: Box<MuThread>, vm: &VM) -> ! { pub fn thread_entry(mu_thread: Box<MuThread>) -> ! {
let ref stack = mu_thread.stack;
unimplemented!()
} }
}
pub struct MuPrimordialThread {
pub func_id: MuID,
pub args: Vec<Constant>
} }
\ No newline at end of file
...@@ -8,9 +8,8 @@ use compiler::backend::BackendTypeInfo; ...@@ -8,9 +8,8 @@ use compiler::backend::BackendTypeInfo;
use vm::machine_code::CompiledFunction; use vm::machine_code::CompiledFunction;
use vm::vm_options::VMOptions; use vm::vm_options::VMOptions;
use runtime::gc; use runtime::gc;
use runtime::thread::MuStack; use runtime::thread::*;
use runtime::RuntimeValue; use runtime::ValueLocation;
use runtime::thread::MuThread;
use utils::Address; use utils::Address;
use std::sync::RwLock; use std::sync::RwLock;
...@@ -38,7 +37,8 @@ pub struct VM { ...@@ -38,7 +37,8 @@ pub struct VM {
compiled_funcs: RwLock<HashMap<MuID, RwLock<CompiledFunction>>>, compiled_funcs: RwLock<HashMap<MuID, RwLock<CompiledFunction>>>,
threads: RwLock<Vec<JoinHandle<()>>> threads: RwLock<Vec<JoinHandle<()>>>,
pub primordial: RwLock<Option<MuPrimordialThread>>
} }
impl <'a> VM { impl <'a> VM {
...@@ -62,7 +62,8 @@ impl <'a> VM { ...@@ -62,7 +62,8 @@ impl <'a> VM {
funcs: RwLock::new(HashMap::new()), funcs: RwLock::new(HashMap::new()),
compiled_funcs: RwLock::new(HashMap::new()), compiled_funcs: RwLock::new(HashMap::new()),
threads: RwLock::new(vec!()) threads: RwLock::new(vec!()),
primordial: RwLock::new(None)
}; };
ret.is_running.store(false, Ordering::SeqCst); ret.is_running.store(false, Ordering::SeqCst);
...@@ -240,14 +241,31 @@ impl <'a> VM { ...@@ -240,14 +241,31 @@ impl <'a> VM {
&self.func_sigs &self.func_sigs
} }
pub fn resolve_function_address(&self, func_id: MuID) -> ValueLocation {
let funcs = self.funcs.read().unwrap();
let func : &MuFunction = &funcs.get(&func_id).unwrap().read().unwrap();
if self.is_running() {
unimplemented!()
} else {
ValueLocation::Relocatable(backend::RegGroup::GPR, func.name().unwrap())
}
}
pub fn new_stack(&self, func_id: MuID) -> Box<MuStack> { pub fn new_stack(&self, func_id: MuID) -> Box<MuStack> {
let funcs = self.funcs.read().unwrap(); let funcs = self.funcs.read().unwrap();
let func : &MuFunction = &funcs.get(&func_id).unwrap().read().unwrap(); let func : &MuFunction = &funcs.get(&func_id).unwrap().read().unwrap();
Box::new(MuStack::new(self.next_id(), func)) 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>) {
let mut guard = self.primordial.write().unwrap();
*guard = Some(MuPrimordialThread{func_id: func_id, args: args});
} }
pub fn new_thread_normal(&self, stack: Box<MuStack>, threadlocal: Address, vals: Vec<RuntimeValue>) { #[deprecated]
pub fn new_thread_normal(&self, mut stack: Box<MuStack>, threadlocal: Address, vals: Vec<ValueLocation>) {
let user_tls = { let user_tls = {
if threadlocal.is_zero() { if threadlocal.is_zero() {
None None
...@@ -257,8 +275,11 @@ impl <'a> VM { ...@@ -257,8 +275,11 @@ impl <'a> VM {
}; };
// set up arguments on stack // set up arguments on stack
unimplemented!(); stack.runtime_load_args(vals);
let handle = MuThread::mu_thread_launch(self.next_id(), stack, user_tls, self);
MuThread::launch(self.next_id(), stack, user_tls, vals, self); let mut threads = self.threads.write().unwrap();
threads.push(handle);
} }
} }
mod test_ir; mod test_ir;
mod test_compiler; mod test_compiler;
mod test_vm;
#[macro_use] #[macro_use]
mod common { mod common {
......
...@@ -27,9 +27,9 @@ fn test_global_access() { ...@@ -27,9 +27,9 @@ fn test_global_access() {
let func_id = vm.id_of("global_access"); let func_id = vm.id_of("global_access");
let funcs = vm.funcs().read().unwrap(); let funcs = vm.funcs().read().unwrap();
let func = funcs.get(&func_id).unwrap().borrow(); let func = funcs.get(&func_id).unwrap().read().unwrap();
let func_vers = vm.func_vers().read().unwrap(); let func_vers = vm.func_vers().read().unwrap();
let mut func_ver = func_vers.get(&(func.id(), func.cur_ver.unwrap())).unwrap().borrow_mut(); let mut func_ver = func_vers.get(&(func.id(), func.cur_ver.unwrap())).unwrap().write().unwrap();
compiler.compile(&mut func_ver); compiler.compile(&mut func_ver);
backend::emit_context(&vm); backend::emit_context(&vm);
......
...@@ -24,9 +24,9 @@ fn test_instsel_fac() { ...@@ -24,9 +24,9 @@ fn test_instsel_fac() {
let func_id = vm.id_of("fac"); let func_id = vm.id_of("fac");
let funcs = vm.funcs().read().unwrap(); let funcs = vm.funcs().read().unwrap();
let func = funcs.get(&func_id).unwrap().borrow(); let func = funcs.get(&func_id).unwrap().read().unwrap();
let func_vers = vm.func_vers().read().unwrap(); let func_vers = vm.func_vers().read().unwrap();
let mut func_ver = func_vers.get(&(func.id(), func.cur_ver.unwrap())).unwrap().borrow_mut(); let mut func_ver = func_vers.get(&(func.id(), func.cur_ver.unwrap())).unwrap().write().unwrap();
compiler.compile(&mut func_ver); compiler.compile(&mut func_ver);
} }
...@@ -21,9 +21,9 @@ fn test_use_count() { ...@@ -21,9 +21,9 @@ fn test_use_count() {
let func_id = vm.id_of("fac"); let func_id = vm.id_of("fac");
let funcs = vm.funcs().read().unwrap(); let funcs = vm.funcs().read().unwrap();
let func = funcs.get(&func_id).unwrap().borrow(); let func = funcs.get(&func_id).unwrap().read().unwrap();
let func_vers = vm.func_vers().read().unwrap(); let func_vers = vm.func_vers().read().unwrap();
let mut func_ver = func_vers.get(&(func.id(), func.cur_ver.unwrap())).unwrap().borrow_mut(); let mut func_ver = func_vers.get(&(func.id(), func.cur_ver.unwrap())).unwrap().write().unwrap();
compiler.compile(&mut func_ver); compiler.compile(&mut func_ver);
...@@ -48,9 +48,9 @@ fn test_build_tree() { ...@@ -48,9 +48,9 @@ fn test_build_tree() {
let func_id = vm.id_of("fac"); let func_id = vm.id_of("fac");
let funcs = vm.funcs().read().unwrap(); let funcs = vm.funcs().read().unwrap();
let func = funcs.get(&func_id).unwrap().borrow(); let func = funcs.get(&func_id).unwrap().read().unwrap();
let func_vers = vm.func_vers().read().unwrap(); let func_vers = vm.func_vers().read().unwrap();
let mut func_ver = func_vers.get(&(func.id(), func.cur_ver.unwrap())).unwrap().borrow_mut(); let mut func_ver = func_vers.get(&(func.id(), func.cur_ver.unwrap())).unwrap().write().unwrap();
compiler.compile(&mut func_ver); compiler.compile(&mut func_ver);
} }
...@@ -68,9 +68,9 @@ fn test_cfa_factorial() { ...@@ -68,9 +68,9 @@ fn test_cfa_factorial() {
let func_id = vm.id_of("fac"); let func_id = vm.id_of("fac");
let funcs = vm.funcs().read().unwrap(); let funcs = vm.funcs().read().unwrap();
let func = funcs.get(&func_id).unwrap().borrow(); let func = funcs.get(&func_id).unwrap().read().unwrap();
let func_vers = vm.func_vers().read().unwrap(); let func_vers = vm.func_vers().read().unwrap();
let mut func_ver = func_vers.get(&(func.id(), func.cur_ver.unwrap())).unwrap().borrow_mut(); let mut func_ver = func_vers.get(&(func.id(), func.cur_ver.unwrap())).unwrap().write().unwrap();
compiler.compile(&mut func_ver); compiler.compile(&mut func_ver);
...@@ -108,9 +108,9 @@ fn test_cfa_sum() { ...@@ -108,9 +108,9 @@ fn test_cfa_sum() {
let func_id = vm.id_of("sum"); let func_id = vm.id_of("sum");
let funcs = vm.funcs().read().unwrap(); let funcs = vm.funcs().read().unwrap();
let func = funcs.get(&func_id).unwrap().borrow(); let func = funcs.get(&func_id).unwrap().read().unwrap();
let func_vers = vm.func_vers().read().unwrap(); let func_vers = vm.func_vers().read().unwrap();
let mut func_ver = func_vers.get(&(func.id(), func.cur_ver.unwrap())).unwrap().borrow_mut(); let mut func_ver = func_vers.get(&(func.id(), func.cur_ver.unwrap())).unwrap().write().unwrap();
compiler.compile(&mut func_ver); compiler.compile(&mut func_ver);
...@@ -159,9 +159,9 @@ fn test_trace_factorial() { ...@@ -159,9 +159,9 @@ fn test_trace_factorial() {
let func_id = vm.id_of("fac"); let func_id = vm.id_of("fac");
let funcs = vm.funcs().read().unwrap(); let funcs = vm.funcs().read().unwrap();
let func = funcs.get(&func_id).unwrap().borrow(); let func = funcs.get(&func_id).unwrap().read().unwrap();
let func_vers = vm.func_vers().read().unwrap(); let func_vers = vm.func_vers().read().unwrap();
let mut func_ver = func_vers.get(&(func.id(), func.cur_ver.unwrap())).unwrap().borrow_mut(); let mut func_ver = func_vers.get(&(func.id(), func.cur_ver.unwrap())).unwrap().write().unwrap();
compiler.compile(&mut func_ver); compiler.compile(&mut func_ver);
...@@ -182,9 +182,9 @@ fn test_trace_sum() { ...@@ -182,9 +182,9 @@ fn test_trace_sum() {
let func_id = vm.id_of("sum"); let func_id = vm.id_of("sum");
let funcs = vm.funcs().read().unwrap(); let funcs = vm.funcs().read().unwrap();
let func = funcs.get(&func_id).unwrap().borrow(); let func = funcs.get(&func_id).unwrap().read().unwrap();
let func_vers = vm.func_vers().read().unwrap(); let func_vers = vm.func_vers().read().unwrap();
let mut func_ver = func_vers.get(&(func.id(), func.cur_ver.unwrap())).unwrap().borrow_mut(); let mut func_ver = func_vers.get(&(func.id(), func.cur_ver.unwrap())).unwrap().write().unwrap();
compiler.compile(&mut func_ver); compiler.compile(&mut func_ver);
......
...@@ -25,14 +25,14 @@ fn test_ir_liveness_fac() { ...@@ -25,14 +25,14 @@ fn test_ir_liveness_fac() {
let func_id = vm.id_of("fac"); let func_id = vm.id_of("fac");
let funcs = vm.funcs().read().unwrap(); let funcs = vm.funcs().read().unwrap();
let func = funcs.get(&func_id).unwrap().borrow(); let func = funcs.get(&func_id).unwrap().read().unwrap();
let func_vers = vm.func_vers().read().unwrap(); let func_vers = vm.func_vers().read().unwrap();
let mut func_ver = func_vers.get(&(func.id(), func.cur_ver.unwrap())).unwrap().borrow_mut(); let mut func_ver = func_vers.get(&(func.id(), func.cur_ver.unwrap())).unwrap().write().unwrap();
compiler.compile(&mut func_ver); compiler.compile(&mut func_ver);
let cf_lock = vm.compiled_funcs().read().unwrap(); let cf_lock = vm.compiled_funcs().read().unwrap();
let cf = cf_lock.get(&func_ver.id()).unwrap().borrow(); let cf = cf_lock.get(&func_ver.id()).unwrap().read().unwrap();
// block 0 // block 0
...@@ -74,9 +74,9 @@ fn test_regalloc_fac() { ...@@ -74,9 +74,9 @@ fn test_regalloc_fac() {
let func_id = vm.id_of("fac"); let func_id = vm.id_of("fac");
let funcs = vm.funcs().read().unwrap(); let funcs = vm.funcs().read().unwrap();
let func = funcs.get(&func_id).unwrap().borrow(); let func = funcs.get(&func_id).unwrap().read().unwrap();
let func_vers = vm.func_vers().read().unwrap(); let func_vers = vm.func_vers().read().unwrap();
let mut func_ver = func_vers.get(&(func.id(), func.cur_ver.unwrap())).unwrap().borrow_mut(); let mut func_ver = func_vers.get(&(func.id(), func.cur_ver.unwrap())).unwrap().write().unwrap();
compiler.compile(&mut func_ver); compiler.compile(&mut func_ver);
} }
mod test_thread;
\ No newline at end of file
extern crate mu;
extern crate log;
extern crate simple_logger;
use self::mu::ast::types::*;
use self::mu::ast::ir::*;
use self::mu::ast::inst::*;
use self::mu::ast::op::*;
use self::mu::vm::*;
use self::mu::compiler::*;
use self::mu::utils::Address;
use self::mu::runtime::ValueLocation;
use test_ir::test_ir::factorial;
use std::sync::Arc;
#[test]
fn test_thread_create() {
let vm = Arc::new(factorial());
let compiler = Compiler::new(CompilerPolicy::default(), vm.clone());
let func_id = vm.id_of("fac");
let funcs = vm.funcs().read().unwrap();
let func = funcs.get(&func_id).unwrap().read().unwrap();
let func_vers = vm.func_vers().read().unwrap();
let mut func_ver = func_vers.get(&(func.id(), func.cur_ver.unwrap())).unwrap().write().unwrap();
compiler.compile(&mut func_ver);
vm.make_primordial_thread(func_id, vec![Constant::Int(5)]);
backend::emit_context(&vm);
}
\ No newline at end of file
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