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"
linked-hash-map = "0.0.10"
hprof = "0.1.3"
memmap = "0.4.0"
memsec = "0.1.9"
\ No newline at end of file
memsec = "0.1.9"
rustc-serialize = "0.3"
\ No newline at end of file
......@@ -1156,6 +1156,15 @@ pub fn emit_context(vm: &VM) {
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---");
}
......
......@@ -5,11 +5,14 @@ pub mod code_emission;
use utils::ByteSize;
pub type Word = usize;
pub const WORD_SIZE : ByteSize = 8;
// X86_64
#[cfg(target_arch = "x86_64")]
#[path = "arch/x86_64/mod.rs"]
mod x86_64;
pub mod x86_64;
#[cfg(target_arch = "x86_64")]
pub use compiler::backend::x86_64::init_machine_regs_for_func;
......
......@@ -3,11 +3,30 @@ pub extern crate immix_rust as gc;
pub use gc::common::Address;
pub use gc::common::ObjectReference;
pub type Word = usize;
pub mod thread;
pub enum RuntimeValue {
Pointer(Address),
Value(Word)
use ast::ir::*;
use compiler::backend::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 @@
__thread void* mu_tls;
void* init_thread_local(void* local) {
return NULL;
void* init_thread_local(void** local) {
mu_tls = *local;
return &mu_tls;
}
......@@ -4,7 +4,7 @@ use ast::ir::*;
use ast::ptr::*;
use ast::types::*;
use vm::VM;
use runtime::RuntimeValue;
use runtime::ValueLocation;
use runtime::gc;
use utils::ByteSize;
......@@ -27,9 +27,8 @@ impl_mu_entity!(MuStack);
pub struct MuStack {
pub hdr: MuEntityHeader,
func_id: MuID,
state: MuStackState,
func_addr: ValueLocation,
func_id: MuID,
size: ByteSize,
// lo addr hi addr
......@@ -49,12 +48,13 @@ pub struct MuStack {
exception_obj : Option<Address>,
state: MuStackState,
#[allow(dead_code)]
mmap : memmap::Mmap
}
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 anon_mmap = match memmap::Mmap::anonymous(total_size, memmap::Protection::ReadWrite) {
......@@ -83,6 +83,7 @@ impl MuStack {
MuStack {
hdr: MuEntityHeader::unnamed(id),
func_addr: func_addr,
func_id: func.id(),
state: MuStackState::Ready(func.sig.arg_tys.clone()),
......@@ -102,6 +103,61 @@ impl MuStack {
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 {
......@@ -118,6 +174,13 @@ pub struct MuThread {
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 {
pub fn new(id: MuID, allocator: Box<gc::Mutator>, stack: Box<MuStack>, user_tls: Option<Address>) -> MuThread {
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 || {
let mut muthread = Box::new(MuThread::new(id, gc::new_mutator(), stack, user_tls));
MuThread::thread_entry(muthread, vm);
let muthread = Box::new(MuThread::new(id, gc::new_mutator(), stack, user_tls));
// set thread local
let addr = unsafe {init_thread_local(&muthread)};
MuThread::thread_entry(muthread);
}) {
Ok(handle) => handle,
Err(_) => panic!("failed to create a thread")
......@@ -139,7 +207,14 @@ impl MuThread {
}
/// 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;
use vm::machine_code::CompiledFunction;
use vm::vm_options::VMOptions;
use runtime::gc;
use runtime::thread::MuStack;
use runtime::RuntimeValue;
use runtime::thread::MuThread;
use runtime::thread::*;
use runtime::ValueLocation;
use utils::Address;
use std::sync::RwLock;
......@@ -38,7 +37,8 @@ pub struct VM {
compiled_funcs: RwLock<HashMap<MuID, RwLock<CompiledFunction>>>,
threads: RwLock<Vec<JoinHandle<()>>>
threads: RwLock<Vec<JoinHandle<()>>>,
pub primordial: RwLock<Option<MuPrimordialThread>>
}
impl <'a> VM {
......@@ -62,7 +62,8 @@ impl <'a> VM {
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);
......@@ -240,14 +241,31 @@ impl <'a> VM {
&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> {
let funcs = self.funcs.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 = {
if threadlocal.is_zero() {
None
......@@ -257,8 +275,11 @@ impl <'a> VM {
};
// 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_compiler;
mod test_vm;
#[macro_use]
mod common {
......
......@@ -27,9 +27,9 @@ fn test_global_access() {
let func_id = vm.id_of("global_access");
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 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);
backend::emit_context(&vm);
......
......@@ -24,9 +24,9 @@ fn test_instsel_fac() {
let func_id = vm.id_of("fac");
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 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);
}
......@@ -21,9 +21,9 @@ fn test_use_count() {
let func_id = vm.id_of("fac");
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 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);
......@@ -48,9 +48,9 @@ fn test_build_tree() {
let func_id = vm.id_of("fac");
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 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);
}
......@@ -68,9 +68,9 @@ fn test_cfa_factorial() {
let func_id = vm.id_of("fac");
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 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);
......@@ -108,9 +108,9 @@ fn test_cfa_sum() {
let func_id = vm.id_of("sum");
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 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);
......@@ -159,9 +159,9 @@ fn test_trace_factorial() {
let func_id = vm.id_of("fac");
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 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);
......@@ -182,9 +182,9 @@ fn test_trace_sum() {
let func_id = vm.id_of("sum");
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 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);
......
......@@ -25,14 +25,14 @@ fn test_ir_liveness_fac() {
let func_id = vm.id_of("fac");
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 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);
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
......@@ -74,9 +74,9 @@ fn test_regalloc_fac() {
let func_id = vm.id_of("fac");
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 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);
}
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