Commit 913aed14 authored by qinsoon's avatar qinsoon

[wip] add Arc<VM> to TLS, working on exception

parent 5fbf8fa4
......@@ -664,7 +664,7 @@ impl CodeGenerator for ASMCodeGen {
ValueLocation::Relocatable(RegGroup::GPR, func_symbol)
}
fn finish_code(&mut self, func_name: MuName) -> (Box<MachineCode>, ValueLocation) {
fn finish_code(&mut self, func_name: MuName) -> (Box<MachineCode + Sync + Send>, ValueLocation) {
let func_end_symbol = {
let mut symbol = symbol(func_name.clone());
symbol.push_str("_end");
......
......@@ -6,7 +6,7 @@ use compiler::machine_code::MachineCode;
pub trait CodeGenerator {
fn start_code(&mut self, func_name: MuName) -> ValueLocation;
fn finish_code(&mut self, func_name: MuName) -> (Box<MachineCode>, ValueLocation);
fn finish_code(&mut self, func_name: MuName) -> (Box<MachineCode + Sync + Send>, ValueLocation);
fn print_cur_code(&self);
......
......@@ -13,7 +13,7 @@ pub struct CompiledFunction {
pub temps: HashMap<MuID, MuID>, // assumes one temperary maps to one register
// not emitting this
pub mc: Option<Box<MachineCode>>,
pub mc: Option<Box<MachineCode + Send + Sync>>,
pub frame: Frame,
pub start: ValueLocation,
......@@ -67,7 +67,7 @@ impl Decodable for CompiledFunction {
}
impl CompiledFunction {
pub fn mc(&self) -> &Box<MachineCode> {
pub fn mc(&self) -> &Box<MachineCode + Send + Sync> {
match self.mc {
Some(ref mc) => mc,
None => panic!("trying to get mc from a compiled function.
......@@ -76,7 +76,7 @@ impl CompiledFunction {
}
}
pub fn mc_mut(&mut self) -> &mut Box<MachineCode> {
pub fn mc_mut(&mut self) -> &mut Box<MachineCode + Send + Sync> {
match self.mc {
Some(ref mut mc) => mc,
None => panic!("no mc found from a compiled function")
......
use utils::Address;
use runtime::thread;
#[no_mangle]
#[cfg(target_arch = "x86_64")]
pub extern fn mu_throw_exception(exception_obj: Address) {
trace!("throwing exception: {}", exception_obj);
thread::MuThread::current_mut().exception_obj = exception_obj;
}
\ No newline at end of file
......@@ -8,12 +8,12 @@ extern void mu_main(char* vm);
extern void mu_trace_level_log();
int main() {
mu_trace_level_log();
printf("main(), going to launch mu_main()\n");
char* serialize_vm = (char*) &vm;
printf("%s\n", serialize_vm);
mu_trace_level_log();
mu_main(serialize_vm);
printf("main(), going to launch mu_main()\n");
char* serialize_vm = (char*) &vm;
printf("%s\n", serialize_vm);
mu_main(serialize_vm);
}
......@@ -16,6 +16,7 @@ use std::sync::Arc;
pub extern crate gc as mm;
pub mod thread;
pub mod entrypoints;
pub mod exception;
// consider using libloading crate instead of the raw c functions for dynalic libraries
// however i am not sure if libloading can load symbols from current process (not from an actual dylib)
......@@ -173,7 +174,7 @@ pub extern fn mu_main(serialized_vm : *const c_char) {
// FIXME: currently assumes no user defined thread local
// will need to fix this after we can serialize heap object
let thread = vm.new_thread_normal(stack, unsafe{Address::zero()}, args);
let thread = thread::MuThread::new_thread_normal(stack, unsafe{Address::zero()}, args, vm.clone());
thread.join().unwrap();
}
......
......@@ -16,6 +16,7 @@ use utils::mem::memsec;
use std::mem;
use std::thread;
use std::thread::JoinHandle;
use std::sync::Arc;
pub const STACK_SIZE : ByteSize = (4 << 20); // 4mb
......@@ -209,7 +210,10 @@ pub struct MuThread {
stack: Option<Box<MuStack>>,
native_sp_loc: Address,
user_tls: Option<Address>
user_tls: Option<Address>,
vm: Arc<VM>,
exception_obj: Address
}
// this depends on the layout of MuThread
......@@ -219,6 +223,12 @@ lazy_static! {
+ mem::size_of::<Option<Box<MuStack>>>();
pub static ref ALLOCATOR_OFFSET : usize = mem::size_of::<MuEntityHeader>();
pub static ref VM_OFFSET : usize = mem::size_of::<MuEntityHeader>()
+ mem::size_of::<Box<mm::Mutator>>()
+ mem::size_of::<Option<Box<MuStack>>>()
+ mem::size_of::<Address>()
+ mem::size_of::<Option<Address>>();
}
#[cfg(target_arch = "x86_64")]
......@@ -238,35 +248,54 @@ extern "C" {
}
impl MuThread {
pub fn new(id: MuID, allocator: mm::Mutator, stack: Box<MuStack>, user_tls: Option<Address>) -> MuThread {
pub fn new(id: MuID, allocator: mm::Mutator, stack: Box<MuStack>, user_tls: Option<Address>, vm: Arc<VM>) -> MuThread {
MuThread {
hdr: MuEntityHeader::unnamed(id),
allocator: allocator,
stack: Some(stack),
native_sp_loc: unsafe {Address::zero()},
user_tls: user_tls
user_tls: user_tls,
vm: vm,
exception_obj: unsafe {Address::zero()}
}
}
pub fn fake_thread(id: MuID, allocator: mm::Mutator) -> MuThread {
MuThread {
hdr: MuEntityHeader::unnamed(id),
allocator: allocator,
stack: None,
native_sp_loc: unsafe {Address::zero()},
user_tls: None
pub fn current() -> &'static MuThread {
unsafe{
get_thread_local().to_ptr::<MuThread>().as_ref().unwrap()
}
}
pub fn current_mut() -> &'static mut MuThread {
unsafe{
get_thread_local().to_ptr_mut::<MuThread>().as_mut().unwrap()
}
}
pub fn new_thread_normal(mut stack: Box<MuStack>, threadlocal: Address, vals: Vec<ValueLocation>, vm: Arc<VM>) -> JoinHandle<()> {
let user_tls = {
if threadlocal.is_zero() {
None
} else {
Some(threadlocal)
}
};
// set up arguments on stack
stack.runtime_load_args(vals);
MuThread::mu_thread_launch(vm.next_id(), stack, user_tls, vm)
}
#[no_mangle]
#[allow(unused_variables)]
pub extern fn mu_thread_launch(id: MuID, stack: Box<MuStack>, user_tls: Option<Address>, vm: &VM) -> JoinHandle<()> {
pub extern fn mu_thread_launch(id: MuID, stack: Box<MuStack>, user_tls: Option<Address>, vm: Arc<VM>) -> JoinHandle<()> {
let new_sp = stack.sp;
let entry = runtime::resolve_symbol(vm.name_of(stack.func_id));
debug!("entry : 0x{:x}", entry);
match thread::Builder::new().name(format!("Mu Thread #{}", id)).spawn(move || {
let muthread : *mut MuThread = Box::into_raw(Box::new(MuThread::new(id, mm::new_mutator(), stack, user_tls)));
let muthread : *mut MuThread = Box::into_raw(Box::new(MuThread::new(id, mm::new_mutator(), stack, user_tls, vm)));
// set thread local
unsafe {set_thread_local(muthread)};
......
......@@ -17,6 +17,7 @@ use runtime::mm as gc;
use rustc_serialize::{Encodable, Encoder, Decodable, Decoder};
use std::path;
use std::sync::Arc;
use std::sync::RwLock;
use std::sync::atomic::{AtomicUsize, AtomicBool, ATOMIC_BOOL_INIT, ATOMIC_USIZE_INIT, Ordering};
use std::thread::JoinHandle;
......@@ -549,21 +550,6 @@ impl <'a> VM {
*guard = Some(MuPrimordialThread{func_id: func_id, args: args});
}
pub fn new_thread_normal(&self, mut stack: Box<MuStack>, threadlocal: Address, vals: Vec<ValueLocation>) -> JoinHandle<()> {
let user_tls = {
if threadlocal.is_zero() {
None
} else {
Some(threadlocal)
}
};
// set up arguments on stack
stack.runtime_load_args(vals);
MuThread::mu_thread_launch(self.next_id(), stack, user_tls, self)
}
#[allow(unused_variables)]
pub fn make_boot_image(self, output: &path::Path) {
use rustc_serialize::json;
......
......@@ -43,20 +43,6 @@ fn test_instruction_new() {
aot::execute(executable);
}
#[allow(dead_code)]
fn fake_mutator_for_cur_thread(vm: &VM) {
// init gc
const IMMIX_SPACE_SIZE : ByteSize = 500 << 20;
const LO_SPACE_SIZE : ByteSize = 500 << 20;
mm::gc_init(IMMIX_SPACE_SIZE, LO_SPACE_SIZE, 8);
let mutator = mm::new_mutator();
let muthread : *mut MuThread = Box::into_raw(Box::new(MuThread::fake_thread(vm.next_id(), mutator)));
unsafe {thread::set_thread_local(muthread)};
}
#[allow(unused_variables)]
pub fn alloc_new() -> VM {
let vm = VM::new();
......
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