Commit 55aa2fe5 authored by qinsoon's avatar qinsoon

[wip] added a test for set_global_by_api, gonna implement persisting

global
parent 3cf9c947
Pipeline #241 failed with stage
in 24 minutes and 4 seconds
extern crate gc;
pub use self::gc::*;
use utils::ByteSize;
use utils::ObjectReference;
use ast::ir::*;
use ast::ptr::*;
use compiler::backend::RegGroup;
use vm::VM;
use runtime::ValueLocation;
use runtime::thread::MuThread;
fn allocate(size: ByteSize, align: ByteSize) -> ObjectReference {
let allocator = (&mut MuThread::current_mut().allocator) as *mut Mutator;
if size > LARGE_OBJECT_THRESHOLD {
muentry_alloc_large(allocator, size, align)
} else {
alloc(allocator, size, align)
}
}
pub fn allocate_value(value: P<Value>, vm: &VM) -> ValueLocation {
let tyid = value.ty.id();
let backend_ty = vm.get_backend_type_info(tyid);
let addr = allocate(backend_ty.size, backend_ty.alignment).to_address();
ValueLocation::Direct(RegGroup::GPR, addr)
}
\ No newline at end of file
......@@ -12,7 +12,7 @@ use std::ffi::CString;
use std::ffi::CStr;
use std::sync::Arc;
pub extern crate gc as mm;
pub mod mm;
pub mod thread;
pub mod math;
pub mod entrypoints;
......
......@@ -200,7 +200,7 @@ pub enum MuStackState {
// do not change the layout (unless change the offset of fields correspondingly)
pub struct MuThread {
pub hdr: MuEntityHeader,
allocator: mm::Mutator,
pub allocator: mm::Mutator,
pub stack: Option<Box<MuStack>>,
native_sp_loc: Address,
......@@ -277,6 +277,11 @@ impl MuThread {
pub unsafe fn current_thread_as_mu_thread(threadlocal: Address, vm: Arc<VM>) {
use std::usize;
if ! unsafe{muentry_get_thread_local()}.is_zero() {
warn!("current thread has a thread local (has a muthread to it)");
return;
}
// fake a stack for current thread
let fake_mu_stack_for_cur = Box::new(MuStack {
hdr: MuEntityHeader::unnamed(vm.next_id()),
......@@ -328,8 +333,6 @@ impl MuThread {
// 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<()> {
......
......@@ -4,6 +4,8 @@ use compiler::*;
use ast::ir::*;
use vm::*;
use std::sync::Arc;
use runtime::thread::MuThread;
use utils::Address;
use std::process::Command;
use std::process::Output;
......
......@@ -41,6 +41,7 @@ pub struct VM {
constants: RwLock<HashMap<MuID, P<Value>>>,
// 6
globals: RwLock<HashMap<MuID, P<Value>>>,
global_locations: RwLock<HashMap<MuID, ValueLocation>>,
// 7
func_sigs: RwLock<HashMap<MuID, P<MuFuncSig>>>,
// 8
......@@ -357,6 +358,7 @@ impl Decodable for VM {
backend_type_info: RwLock::new(backend_type_info),
constants: RwLock::new(constants),
globals: RwLock::new(globals),
global_locations: RwLock::new(hashmap!{}),
func_sigs: RwLock::new(func_sigs),
funcs: RwLock::new(funcs),
func_vers: RwLock::new(func_vers),
......@@ -400,6 +402,7 @@ impl <'a> VM {
backend_type_info: RwLock::new(HashMap::new()),
globals: RwLock::new(HashMap::new()),
global_locations: RwLock::new(hashmap!{}),
func_sigs: RwLock::new(HashMap::new()),
func_vers: RwLock::new(HashMap::new()),
......@@ -554,6 +557,7 @@ impl <'a> VM {
debug_assert!(!constants.contains_key(&id));
let ret = P(Value{hdr: MuEntityHeader::unnamed(id), ty: ty, v: Value_::Constant(val)});
trace!("declare const #{} = {}", id, ret);
constants.insert(id, ret.clone());
ret
......@@ -570,12 +574,17 @@ impl <'a> VM {
pub fn declare_global(&self, id: MuID, ty: P<MuType>) -> P<Value> {
let global = P(Value{
hdr: MuEntityHeader::unnamed(id),
ty: P(MuType::new(self.next_id(), MuType_::iref(ty.clone()))),
ty: self.declare_type(self.next_id(), MuType_::iref(ty.clone())),
v: Value_::Global(ty)
});
let mut globals = self.globals.write().unwrap();
globals.insert(id, global.clone());
// allocate global
let loc = gc::allocate_value(global.clone(), self);
let mut global_locs = self.global_locations.write().unwrap();
global_locs.insert(id, loc);
global
}
......@@ -585,7 +594,8 @@ impl <'a> VM {
let mut types = self.types.write().unwrap();
debug_assert!(!types.contains_key(&id));
trace!("declare type #{} = {}", ty.id(), ty);
types.insert(ty.id(), ty.clone());
ty
......
......@@ -52,6 +52,13 @@ macro_rules! constdef {
}
}
macro_rules! globaldef {
(($vm: expr) <$ty: ident> $name: ident) => {
let $name = $vm.declare_global($vm.next_id(), $ty.clone());
$vm.set_name($name.as_entity(), Mu(stringify!($name)));
}
}
macro_rules! funcsig {
(($vm: expr) $name: ident = ($($arg_ty: ident),*) -> ($($ret_ty: ident),*)) => {
let $name = $vm.declare_func_sig($vm.next_id(), vec![$($ret_ty.clone()),*], vec![$($arg_ty.clone()),*]);
......@@ -121,6 +128,12 @@ macro_rules! consta {
}
}
macro_rules! global {
(($vm: expr, $fv: ident) $name: ident = $g: ident) => {
let $name = $fv.new_global($g.clone());
}
}
macro_rules! inst {
// NEW
(($vm: expr, $fv: ident) $name: ident: $value: ident = NEW <$ty: ident>) => {
......
#[macro_use]
extern crate mu;
#[macro_use]
extern crate utils;
#[macro_use]
extern crate log;
#[macro_use]
extern crate maplit;
......
extern crate mu;
extern crate log;
extern crate libloading;
use test_ir::test_ir::global_access;
use self::mu::compiler::*;
use self::mu::vm::VM;
use self::mu::runtime::thread::MuThread;
use self::mu::ast::types::*;
use self::mu::ast::ir::*;
use self::mu::ast::inst::*;
use self::mu::ast::op::*;
use utils::Address;
use utils::LinkedHashMap;
use mu::testutil;
use std::sync::RwLock;
use std::sync::Arc;
#[test]
fn test_global_access() {
VM::start_logging_trace();
let vm = Arc::new(global_access());
let vm = Arc::new(VM::new());
unsafe {
MuThread::current_thread_as_mu_thread(Address::zero(), vm.clone());
}
global_access(&vm);
let compiler = Compiler::new(CompilerPolicy::default(), vm.clone());
{
let func_id = vm.id_of("global_access");
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);
}
#[test]
fn test_set_global_by_api() {
VM::start_logging_trace();
let vm = Arc::new(VM::new());
unsafe {
MuThread::current_thread_as_mu_thread(Address::zero(), vm.clone());
}
set_global_by_api(&vm);
let compiler = Compiler::new(CompilerPolicy::default(), vm.clone());
{
let func_id = vm.id_of("set_global_by_api");
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);
}
// set global by api here
// then emit context (global will be put into context.s
backend::emit_context(&vm);
// link
let lib = {
let libname = &testutil::get_dylib_name("set_global_by_api");
let dylib = testutil::aot::link_dylib(vec![Mu("set_global_by_api")], libname, &vm);
libloading::Library::new(dylib.as_os_str()).unwrap()
};
unsafe {
let set_global_by_api : libloading::Symbol<unsafe extern fn () -> u64> = lib.get(b"set_global_by_api").unwrap();
let res = set_global_by_api();
println!("set_global_by_api() = {}", res);
assert!(res == 1);
}
}
fn set_global_by_api(vm: &VM) {
typedef! ((vm) int64 = mu_int(64));
typedef! ((vm) iref_int64 = mu_iref(int64));
globaldef! ((vm) <int64> a);
funcsig! ((vm) sig = () -> (int64));
funcdecl! ((vm) <sig> set_global_by_api);
funcdef! ((vm) <sig> set_global_by_api VERSION set_global_by_api_v1);
// blk entry
block! ((vm, set_global_by_api_v1) blk_entry);
ssa! ((vm, set_global_by_api_v1) <int64> val);
global! ((vm, set_global_by_api_v1) blk_entry_a = a);
inst! ((vm, set_global_by_api_v1) blk_entry_load:
val = LOAD blk_entry_a (is_ptr: false, order: MemoryOrder::SeqCst)
);
inst! ((vm, set_global_by_api_v1) blk_entry_ret:
RET (val)
);
define_block! ((vm, set_global_by_api_v1) blk_entry() {
blk_entry_load, blk_entry_ret
});
define_func_ver!((vm) set_global_by_api_v1 (entry: blk_entry) {
blk_entry
});
}
\ No newline at end of file
......@@ -8,6 +8,7 @@ use self::mu::vm::*;
use self::mu::utils::LinkedHashMap;
use std::sync::RwLock;
use std::sync::Arc;
#[test]
#[allow(unused_variables)]
......@@ -381,13 +382,20 @@ pub fn factorial() -> VM {
#[test]
#[allow(unused_variables)]
fn test_global_access() {
let vm = global_access();
use utils::Address;
use mu::runtime::thread::MuThread;
let vm = Arc::new(VM::new());
unsafe {
MuThread::current_thread_as_mu_thread(Address::zero(), vm.clone());
}
global_access(&vm);
}
#[allow(unused_variables)]
pub fn global_access() -> VM {
let vm = VM::new();
pub fn global_access(vm: &VM) {
// .typedef @int64 = int<64>
// .typedef @iref_int64 = iref<int<64>>
let type_def_int64 = vm.declare_type(vm.next_id(), MuType_::int(64));
......@@ -451,7 +459,7 @@ pub fn global_access() -> VM {
mem_loc: 0
}
});
let blk_0_term = func_ver.new_inst(Instruction{
hdr: MuEntityHeader::unnamed(vm.next_id()),
value: None,
......@@ -477,6 +485,4 @@ pub fn global_access() -> VM {
});
vm.define_func_version(func_ver);
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