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 45882207 authored by qinsoon's avatar qinsoon

impl fake_mu_thread (not tested at all!!!)

going to test it with test_jit suite
parent 8f4e6891
Pipeline #122 canceled with stage
......@@ -84,3 +84,30 @@ begin_func exception_restore
movq %rdx, %rsp
jmpq *%rdi
end_func exception_restore
# fake_swap_mu_thread(old_sp_loc: Address)
# %rdi
# (we do not actually swap stack, but we make the stack the same
# as if they are native stack that have been swapped out, so that
# when THREADEXIT (swap_back_to_native_stack) is called, we won't panic
# this function is untested!!!
begin_func fake_swap_mu_thread
# save return address
movq (%rsp), %rax
pushq %rbp
movq %rsp, %rbp
pushq %rbx
pushq %r12
pushq %r13
pushq %r14
pushq %r15
# save old sp to thread field
movq %rsp, 0(%rdi)
# return to caller, but preserve those pushed values (since THREADEXIT will pick them up)
pushq %rax
ret
\ No newline at end of file
......@@ -30,9 +30,9 @@ impl_mu_entity!(MuStack);
#[repr(C)]
pub struct MuStack {
pub hdr: MuEntityHeader,
func_addr: ValueLocation,
func_id: MuID,
// address, id
func: Option<(ValueLocation, MuID)>,
size: ByteSize,
// lo addr hi addr
......@@ -50,11 +50,9 @@ pub struct MuStack {
bp : Address,
ip : Address,
exception_obj : Option<Address>,
state: MuStackState,
#[allow(dead_code)]
mmap : memmap::Mmap
mmap : Option<memmap::Mmap>
}
impl MuStack {
......@@ -87,8 +85,7 @@ impl MuStack {
MuStack {
hdr: MuEntityHeader::unnamed(id),
func_addr: func_addr,
func_id: func.id(),
func: Some((func_addr, func.id())),
state: MuStackState::Ready(func.sig.arg_tys.clone()),
......@@ -102,9 +99,7 @@ impl MuStack {
bp: upper_bound,
ip: unsafe {Address::zero()},
exception_obj: None,
mmap: anon_mmap
mmap: Some(anon_mmap)
}
}
......@@ -245,6 +240,7 @@ extern "C" {
#[link(name = "swap_stack")]
extern "C" {
fn swap_to_mu_stack(new_sp: Address, entry: Address, old_sp_loc: Address);
fn fake_swap_mu_thread(old_sp_loc: Address);
fn muentry_swap_back_to_native_stack(sp_loc: Address);
pub fn get_current_frame_rbp() -> Address;
pub fn exception_restore(dest: Address, callee_saved: *const Word, rsp: Address) -> !;
......@@ -276,6 +272,72 @@ impl MuThread {
muentry_get_thread_local().to_ptr_mut::<MuThread>().as_mut().unwrap()
}
}
pub unsafe fn current_thread_as_mu_thread(threadlocal: Address, vm: Arc<VM>) {
use std::usize;
let user_tls = {
if threadlocal.is_zero() {
None
} else {
Some(threadlocal)
}
};
// fake a stack for current thread
let fake_mu_stack_for_cur = Box::new(MuStack {
hdr: MuEntityHeader::unnamed(vm.next_id()),
func: None,
state: MuStackState::Active,
// we do not know anything about current stack
// treat it as max size
size: usize::MAX,
overflow_guard: unsafe {Address::zero()},
lower_bound: unsafe {Address::zero()},
upper_bound: unsafe {Address::max()},
underflow_guard: unsafe {Address::max()},
// these will only be used when stack is not active (we still save to these fields)
// their values do not matter now
sp: unsafe {Address::zero()},
bp: unsafe {Address::zero()},
ip: unsafe {Address::zero()},
// we are not responsible for keeping the memory alive
mmap: None,
});
let fake_mu_thread = MuThread {
hdr: MuEntityHeader::unnamed(vm.next_id()),
// valid allocator and stack
allocator: mm::new_mutator(),
stack: Some(fake_mu_stack_for_cur),
// we do not need native_sp_loc (we do not expect the thread to call
native_sp_loc: unsafe {Address::zero()},
user_tls: user_tls,
vm: vm,
exception_obj: unsafe {Address::zero()}
};
let ptr_fake_mu_thread : *mut MuThread = Box::into_raw(Box::new(fake_mu_thread));
// set thread local
unsafe {set_thread_local(ptr_fake_mu_thread)};
// let addr = unsafe {muentry_get_thread_local()};
// let sp_threadlocal_loc = addr.plus(*NATIVE_SP_LOC_OFFSET);
//
// unsafe {
// fake_swap_mu_thread(sp_threadlocal_loc);
// }
debug!("returned to Rust thread (fake muthread)");
}
pub fn new_thread_normal(mut stack: Box<MuStack>, threadlocal: Address, vals: Vec<ValueLocation>, vm: Arc<VM>) -> JoinHandle<()> {
let user_tls = {
......@@ -290,13 +352,13 @@ impl MuThread {
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: Arc<VM>) -> JoinHandle<()> {
let new_sp = stack.sp;
let entry = runtime::resolve_symbol(vm.name_of(stack.func_id));
let entry = runtime::resolve_symbol(vm.name_of(stack.func.as_ref().unwrap().1));
debug!("entry : 0x{:x}", entry);
match thread::Builder::new().name(format!("Mu Thread #{}", id)).spawn(move || {
......
......@@ -58,6 +58,7 @@ fn link_dylib_internal (files: Vec<PathBuf>, out: PathBuf) -> PathBuf {
for obj in object_files {
gcc.arg(obj.as_os_str());
}
gcc.arg("-o");
gcc.arg(out.as_os_str());
......
......@@ -86,6 +86,11 @@ impl Address {
pub unsafe fn zero() -> Address {
Address(0)
}
#[inline(always)]
pub unsafe fn max() -> Address {
use std::usize;
Address(usize::MAX)
}
}
impl PartialOrd for Address {
......
......@@ -7,6 +7,8 @@ use self::mu::ast::ir::*;
use self::mu::ast::inst::*;
use self::mu::vm::*;
use self::mu::compiler::*;
use self::mu::runtime::thread::MuThread;
use self::mu::utils::Address;
use std::sync::Arc;
use std::sync::RwLock;
......@@ -38,6 +40,43 @@ fn test_instruction_new() {
aot::execute(executable);
}
#[allow(dead_code)]
//#[test]
// The test won't work, since the generated dylib wants to use 'alloc_slow'.
// but in current process, there is no 'alloc_slow' (rust mangles it)
// The solution would be starting mu vm with libmu.so, then create IR from there.
// test_jit should contains a test for it. So I do not test it here
fn test_instruction_new_on_cur_thread() {
VM::start_logging_trace();
// compile
let vm = Arc::new(alloc_new());
let compiler = Compiler::new(CompilerPolicy::default(), vm.clone());
let func_id = vm.id_of("alloc_new");
{
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.cur_ver.unwrap()).unwrap().write().unwrap();
compiler.compile(&mut func_ver);
}
backend::emit_context(&vm);
// link
let libname = &format!("liballoc_new_on_cur_thraed.dylib");
let dylib = aot::link_dylib(vec![Mu("alloc_new")], libname);
let lib = libloading::Library::new(dylib.as_os_str()).unwrap();
unsafe {
MuThread::current_thread_as_mu_thread(Address::zero(), vm.clone());
let func : libloading::Symbol<unsafe extern fn() -> ()> = lib.get(b"alloc_new").unwrap();
func();
}
}
#[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