Commit 9e67a38d authored by Javad Ebrahimian Amiri's avatar Javad Ebrahimian Amiri

Merge branch 'rtmu-dev' into 'master'

rtmu dev

See merge request !59
parents 6f647556 c6557f98
......@@ -7,20 +7,26 @@ stages:
before_script:
- export MU_ZEBU=$CI_PROJECT_DIR
- export ZEBU_BUILD=release
- export ZEBU_CARGO_ARG="--release"
- export CARGO_HOME=.cargo
- export CC=clang
- export CXX=clang++
- export RUST_TEST_THREADS=1
- export LD_LIBRARY_PATH=$MU_ZEBU/target/$ZEBU_BUILD/deps/:$LD_LIBRARY_PATH
- export PYTHONPATH=mu-client-pypy
- source /home/gitlab-runner/ci/bin/activate
build:
stage: build
script:
- rustup run 1.30.1-x86_64-unknown-linux-gnu cargo clean
- time rustup run 1.30.1-x86_64-unknown-linux-gnu cargo test -j6 --release --no-run --color=always
- rustc --version
- cargo clean
- time cargo test -j6 $ZEBU_CARGO_ARG --no-run --color=always
artifacts:
paths:
- target/debug/deps/libmu.so
- target/debug/deps/libmu.a
- target/debug/deps/lib-*
- target/release/deps/libmu.so
- target/release/deps/libmu.a
- target/release/deps/lib-*
......@@ -28,22 +34,22 @@ build:
test:cargo:api:
stage: test
script:
- rustup run 1.30.1-x86_64-unknown-linux-gnu cargo test test_api --release 2> /dev/null
- cargo test test_api $ZEBU_CARGO_ARG 2> /dev/null
test:cargo:ir:
stage: test
script:
- rustup run 1.30.1-x86_64-unknown-linux-gnu cargo test test_ir --release 2> /dev/null
- cargo test test_ir $ZEBU_CARGO_ARG 2> /dev/null
test:cargo:compiler:
stage: test
script:
- rustup run 1.30.1-x86_64-unknown-linux-gnu cargo test test_compiler --release 2> /dev/null
- cargo test test_compiler $ZEBU_CARGO_ARG 2> /dev/null
test:cargo:runtime:
stage: test
script:
- rustup run 1.30.1-x86_64-unknown-linux-gnu cargo test test_runtime --release 2> /dev/null
- cargo test test_runtime $ZEBU_CARGO_ARG 2> /dev/null
.build_muc: &build_muc |
if [ -d "tests/test_muc/mu-tool-compiler" ]; then rm -Rf tests/test_muc/mu-tool-compiler; fi
......@@ -53,7 +59,7 @@ test:cargo:runtime:
export ANTLR_HOME=/home/gitlab-runner/antlr4/runtime/Cpp/run
mkdir lib
cp -r $ANTLR_HOME/usr/local/lib/* $PWD/lib/
cp -r $MU_ZEBU/target/release/deps/* $PWD/lib/
cp -r $MU_ZEBU/target/$ZEBU_BUILD/deps/* $PWD/lib/
export CC=clang
export CXX=clang++
make
......@@ -159,7 +165,7 @@ testjit:som:
mubench:
stage: mubench
script:
- cp ./target/release/deps/libmu.so ./target/release/libmu.so
- cp $MU_ZEBU/target/$ZEBU_BUILD/deps/libmu.so ./target/$ZEBU_BUILD/libmu.so
- deactivate
- git clone https://gitlab.anu.edu.au/mu/mu-perf-benchmarks.git
- git clone https://gitlab.anu.edu.au/mu/mu-client-pypy.git
......@@ -179,3 +185,4 @@ rustfmt:
stage: rustfmt
script:
- cargo-fmt -- --check --verbose -- src/lib.rs src/ast/src/lib.rs src/gc/src/lib.rs src/utils/src/lib.rs
allow_failure: true
......@@ -15,7 +15,7 @@
[package]
name = "mu"
version = "0.0.1"
authors = [ "Your name <you@example.com>" ]
authors = [ "Your name <you@example.com>", "Javad Amiri <javad.amiri@anu.edu.au>" ]
build = "build.rs"
[lib]
......@@ -26,6 +26,7 @@ doctest = false
default = ["aot"]
aot = []
jit = []
realtime = ["mu_ast/realtime", "mu_utils/realtime", "mu_gc/realtime"]
[build-dependencies]
cc = "*"
......@@ -34,7 +35,7 @@ built = "*"
[dependencies]
mu_ast = {path = "src/ast"}
mu_utils = {path = "src/utils"}
rodal = { git = "https://gitlab.anu.edu.au/mu/rodal", branch = "rust-1.30.1", version = "^0.3.18" }
rodal = { git = "https://gitlab.anu.edu.au/mu/rodal", branch = "master", version = "^0.4.0" }
libc="*"
field-offset = "*"
......@@ -46,7 +47,8 @@ num = "*"
hprof = "*"
memmap = "*"
memsec = "0.1.9"
serde = "*"
serde = { version = "*", features = ["derive"]}
bincode = "*"
serde_derive = "*"
time = "*"
maplit = "*"
......@@ -56,3 +58,4 @@ extprim = "*"
num-traits = "*"
built = "*"
mu_gc = { path = "src/gc"}
cfg-if = "*"
......@@ -53,5 +53,6 @@ fn main() {
}
fn built() {
built::write_built_file().expect("Failed to acquire build-time information");
built::write_built_file()
.expect("Failed to acquire build-time information");
}
#trailing_comma = "Never"
max_width = 80
wrap_comments = true
trailing_comma = "Never"
......@@ -15,16 +15,22 @@
[package]
name = "mu_ast"
version = "0.0.1"
authors = ["qinsoon <qinsoon@gmail.com>"]
authors = ["qinsoon <qinsoon@gmail.com>", "Javad Amiri <javad.amiri@anu.edu.au>"]
[features]
realtime = []
[lib]
crate-type = ["rlib"]
[build-dependencies]
log = "*"
[dependencies]
mu_utils = {path = "../utils"}
lazy_static = "0.2.11"
log = "*"
simple_logger = "*"
regex = "0.2.2"
rodal = { git = "https://gitlab.anu.edu.au/mu/rodal", branch = "rust-1.30.1", version = "^0.3.18" }
#rodal = { path = "../../rodal", version = "*" }
rodal = { git = "https://gitlab.anu.edu.au/mu/rodal", branch = "master", version = "^0.4.0" }
libc = "*"
\ No newline at end of file
......@@ -29,10 +29,11 @@ pub struct Instruction {
pub value: Option<Vec<P<Value>>>,
/// ops field list all the children nodes,
/// and in Instruction_, the children nodes are referred by indices
/// This design makes it easy for the compiler to iterate through all the children
/// This design makes it easy for the compiler to iterate through all the
/// children
pub ops: Vec<P<TreeNode>>,
/// used for pattern matching
pub v: Instruction_,
pub v: Instruction_
}
// Instruction implements MuEntity
......@@ -46,8 +47,11 @@ impl Instruction {
clone
}
// RTMU add new rt instructions to various spec functions here
/// is this instruction the terminal inst of its block?
/// Terminal instructions end Mu blocks, and Mu block ends with a terminal instruction.
/// Terminal instructions end Mu blocks, and Mu block ends with a terminal
/// instruction.
pub fn is_terminal_inst(&self) -> bool {
use inst::Instruction_::*;
......@@ -82,6 +86,26 @@ impl Instruction {
| AllocAHybrid(_, _)
| NewStack(_)
| NewThread { .. }
| NewRTThread { .. }
| AllocAU(_)
| NewReg(_)
| DeleteReg(_)
| rAlloc(_, _)
| rAllocHybrid(_, _, _)
// | rAllocT(_)
| eAlloc(_)
| eAllocHybrid(_, _)
// | eAllocT(_)
| eDelete(_)
// | eDeleteT(_)
| NotifyThread(_) // TODO remove - not needed anymore
| SetPriority(_,_)
| GetPriority(_)
| AffinitySet(_,_)
| AffinityClear(_,_)
| AffinityEqual(_,_)
| AffinityIsset(_,_)
| AffinityZero(_)
| NewFrameCursor(_)
| GetIRef(_)
| GetFieldIRef { .. }
......@@ -107,6 +131,7 @@ impl Instruction {
| CommonInst_Tr64ToTag(_)
| Move(_)
| PrintHex(_)
| PrintBool(_)
| SetRetval(_)
| GetVMThreadLocal
| KillStack(_)
......@@ -121,8 +146,8 @@ impl Instruction {
}
/// does this instruction has side effect?
/// An instruction has side effect if it affects something other than its result operands.
/// e.g. affecting memory, stack, thread, etc.
/// An instruction has side effect if it affects something other than its
/// result operands. e.g. affecting memory, stack, thread, etc.
// FIXME: need to check correctness
pub fn has_side_effect(&self) -> bool {
use inst::Instruction_::*;
......@@ -138,8 +163,25 @@ impl Instruction {
| AllocA(_)
| NewHybrid(_, _)
| AllocAHybrid(_, _)
| AllocAU(_)
| NewReg(_)
| DeleteReg(_)
| rAlloc(_, _)
| rAllocHybrid(_,_,_)
// | rAllocT(_)
| eAlloc(_)
| eAllocHybrid(_,_)
// | eAllocT(_)
| eDelete(_)
// | eDeleteT(_)
| NewStack(_)
| NewThread { .. }
| NewRTThread { .. }
| NotifyThread(_)
| SetPriority(_, _)
| AffinityClear(_, _)
| AffinitySet(_, _)
| AffinityZero(_)
| NewFrameCursor(_)
| Fence(_)
| Return(_)
......@@ -163,6 +205,7 @@ impl Instruction {
| CommonInst_Unpin(_)
| CommonInst_GetAddr(_)
| PrintHex(_)
| PrintBool(_)
| SetRetval(_)
| KillStack(_) => true,
BinOp(_, _, _)
......@@ -187,7 +230,10 @@ impl Instruction {
| CommonInst_Tr64ToTag(_)
| Move(_)
| CurrentStack
| GetVMThreadLocal => false,
| GetVMThreadLocal
| GetPriority(_)
| AffinityIsset(_, _)
| AffinityEqual(_, _) => false,
}
}
......@@ -217,7 +263,27 @@ impl Instruction {
| NewHybrid(_, _)
| AllocAHybrid(_, _)
| NewStack(_)
| AllocAU(_)
| NewReg(_)
| DeleteReg(_)
| rAlloc(_, _)
| rAllocHybrid(_,_, _)
// | rAllocT(_)
| eAlloc(_)
| eAllocHybrid(_,_)
// | eAllocT(_)
| eDelete(_)
// | eDeleteT(_)
| NewThread { .. }
| NewRTThread { .. }
| NotifyThread(_)
| SetPriority(_, _)
| GetPriority(_)
| AffinityZero(_)
| AffinityClear(_, _)
| AffinitySet(_, _)
| AffinityEqual(_, _)
| AffinityIsset(_, _)
| NewFrameCursor(_)
| GetIRef(_)
| GetFieldIRef { .. }
......@@ -251,6 +317,7 @@ impl Instruction {
| CommonInst_Tr64ToTag(_)
| Move(_)
| PrintHex(_)
| PrintBool(_)
| SetRetval(_)
| GetVMThreadLocal
| KillStack(_)
......@@ -288,9 +355,29 @@ impl Instruction {
| New(_)
| AllocA(_)
| NewHybrid(_, _)
| AllocAU(_)
| NewReg(_)
| DeleteReg(_)
| rAlloc(_, _)
| rAllocHybrid(_,_,_)
// | rAllocT(_)
| eAlloc(_)
| eAllocHybrid(_,_)
// | eAllocT(_)
| eDelete(_)
// | eDeleteT(_)
| AllocAHybrid(_, _)
| NewStack(_)
| NewThread { .. }
| NewRTThread { .. }
| NotifyThread(_)
| SetPriority(_,_) // FIXME - Not sure about these
| GetPriority(_)
| AffinityClear(_,_)
| AffinityEqual(_,_)
| AffinityIsset(_,_)
| AffinitySet(_,_)
| AffinityZero(_)
| NewFrameCursor(_)
| GetIRef(_)
| GetFieldIRef { .. }
......@@ -324,6 +411,7 @@ impl Instruction {
| CommonInst_Tr64ToTag(_)
| Move(_)
| PrintHex(_)
| PrintBool(_)
| SetRetval(_)
| GetVMThreadLocal
| KillStack(_)
......@@ -366,6 +454,9 @@ impl Instruction {
AllocAHybrid(_, _) |
NewStack(_) |
NewThread { .. } |
NewRTThread { .. } |
NotifyThread(_) |
SetPriority(_,_) |
NewFrameCursor(_) |
GetIRef(_) |
GetFieldIRef { .. } |
......@@ -398,6 +489,7 @@ impl Instruction {
CommonInst_Tr64ToTag(_) |
Move(_) |
PrintHex(_) |
PrintBool(_) |
SetRetval(_) |
GetVMThreadLocal |
KillStack(_) |
......@@ -428,8 +520,11 @@ impl Instruction {
operation,
ref from_ty,
ref to_ty,
operand,
} => format!("{} <{} {}> {}", operation, from_ty, to_ty, ops[operand]),
operand
} => format!(
"{} <{} {}> {}",
operation, from_ty, to_ty, ops[operand]
),
&Instruction_::ExprCall { ref data, is_abort } => {
if is_abort {
panic!("ABORT is not supported");
......@@ -445,7 +540,7 @@ impl Instruction {
&Instruction_::Load {
is_ptr,
mem_loc,
order,
order
} => {
let ptr = select_value!(is_ptr, " PTR", "");
format!(
......@@ -460,7 +555,7 @@ impl Instruction {
value,
is_ptr,
mem_loc,
order,
order
} => {
let ptr = select_value!(is_ptr, " PTR", "");
format!(
......@@ -479,7 +574,7 @@ impl Instruction {
fail_order,
mem_loc,
expected_value,
desired_value,
desired_value
} => {
let ptr = select_value!(is_ptr, " PTR", "");
let weak = select_value!(is_weak, " WEAK", "");
......@@ -500,7 +595,7 @@ impl Instruction {
order,
op,
mem_loc,
value,
value
} => {
let ptr = select_value!(is_ptr, " PTR", "");
format!(
......@@ -526,21 +621,112 @@ impl Instruction {
ops[func].ty().get_sig().unwrap(),
ops[func]
),
&Instruction_::NewReg(size) => {
format!("COMMINST @uvm.new_region({})", ops[size])
}
&Instruction_::DeleteReg(regref) => {
format!("COMMINST @uvm.delete_region({})", ops[regref])
}
&Instruction_::AllocAU(ref ty) => {
format!("COMMINST @uvm.AllocAU({})", ty.id())
}
&Instruction_::rAlloc(regref, ref ty) => {
format!("COMMINST @uvm.rAlloc({}, {})", ops[regref], ty.id())
}
&Instruction_::rAllocHybrid(regref, ref ty, var_len) => format!(
"COMMINST @uvm.rAllocHybrid({}, {}, {})",
ops[regref],
ty.id(),
ops[var_len]
),
// &Instruction_::rAllocT(regref, ty) => format!(
// "COMMINST @uvm.rAllocT({}, {})",
// ops[regref],
// ops[ty]
// ),
&Instruction_::eAlloc(ref ty) => {
format!("COMMINST @uvm.eAlloc({})", ty.id())
}
&Instruction_::eAllocHybrid(ref ty, var_len) => format!(
"COMMINST @uvm.eAllocHybrid({}, {})",
ty.id(),
ops[var_len]
),
// &Instruction_::eAllocT( ty) => format!(
// "COMMINST @uvm.eAllocT({})",
// ops[ty]
// ),
&Instruction_::eDelete(obj) => {
format!("COMMINST @uvm.eDelete({})", ops[obj])
}
// &Instruction_::eDeleteT( obj) => format!(
// "COMMINST @uvm.eDeleteT({})",
// ops[obj]
// ),
&Instruction_::NewThread {
stack,
thread_local,
is_exception,
ref args,
ref args
} => {
let new_stack_clause = format_new_stack_clause(is_exception, args, ops);
let new_stack_clause =
format_new_stack_clause(is_exception, args, ops);
let thread_local = thread_local
.map(|t| format!(" THREADLOCAL({})", ops[t]))
.unwrap_or("".to_string());
format!(
"NEWSTACK {}{} {}",
"NEWTHREAD {}{} {}",
ops[stack], thread_local, new_stack_clause,
)
}
&Instruction_::NewRTThread {
attr,
stack,
thread_local,
is_exception,
ref args
} => {
let new_stack_clause =
format_new_stack_clause(is_exception, args, ops);
let thread_local = thread_local
.map(|t| format!(" THREADLOCAL({})", ops[t]))
.unwrap_or("".to_string());
format!(
"NEWRTTHREAD {}, {}, {}, {}",
ops[attr], ops[stack], thread_local, new_stack_clause,
)
}
&Instruction_::NotifyThread(thread) => {
format!("COMMINST @uvm.notifythread({})", ops[thread])
}
&Instruction_::SetPriority(thread, priority) => format!(
"COMMINST @uvm.setpriority({}, {})",
ops[thread], ops[priority]
),
&Instruction_::GetPriority(thread) => {
format!("COMMINST @uvm.getpriority({})", ops[thread])
}
&Instruction_::AffinityClear(thread, cpu) => format!(
"COMMINST @uvm.affinityclear({}, {})",
ops[thread], ops[cpu]
),
&Instruction_::AffinitySet(thread, cpu) => format!(
"COMMINST @uvm.affinityset({}, {})",
ops[thread], ops[cpu]
),
&Instruction_::AffinityEqual(thread1, thread2) => format!(
"COMMINST @uvm.affinityequal({}, {})",
ops[thread1], ops[thread2]
),
&Instruction_::AffinityIsset(thread, cpu) => format!(
"COMMINST @uvm.affinityisset({}, {})",
ops[thread], ops[cpu]
),
&Instruction_::AffinityZero(thread) => {
format!("COMMINST @uvm.affinityzero({})", ops[thread])
}
&Instruction_::NewFrameCursor(stack) => {
format!("COMMINST @uvm.meta.new_cursor({})", ops[stack])
}
......@@ -552,7 +738,7 @@ impl Instruction {
&Instruction_::GetFieldIRef {
is_ptr,
base,
index,
index
} => {
let ptr = select_value!(is_ptr, " PTR", "");
format!(
......@@ -566,7 +752,7 @@ impl Instruction {
&Instruction_::GetElementIRef {
is_ptr,
base,
index,
index
} => {
let ptr = select_value!(is_ptr, " PTR", "");
format!(
......@@ -581,7 +767,7 @@ impl Instruction {
&Instruction_::ShiftIRef {
is_ptr,
base,
offset,
offset
} => {
let ptr = select_value!(is_ptr, " PTR", "");
format!(
......@@ -614,12 +800,22 @@ impl Instruction {
format!("RET ({})", op_vector_str(vals, ops))
}
}
&Instruction_::ThreadExit => "COMMINST @uvm.thread_exit".to_string(),
&Instruction_::CurrentStack => "COMMINST @uvm.current_stack".to_string(),
&Instruction_::KillStack(s) => format!("COMMINST @uvm.kill_stack({})", ops[s]),
&Instruction_::ThreadExit => {
"COMMINST @uvm.thread_exit".to_string()
}
&Instruction_::CurrentStack => {
"COMMINST @uvm.current_stack".to_string()
}
&Instruction_::KillStack(s) => {
format!("COMMINST @uvm.kill_stack({})", ops[s])
}
&Instruction_::Throw(exn_obj) => format!("THROW {}", ops[exn_obj]),
&Instruction_::TailCall(ref call) => format!("TAILCALL{}", call.debug_str(ops)),
&Instruction_::Branch1(ref dest) => format!("BRANCH {}", dest.debug_str(ops)),
&Instruction_::TailCall(ref call) => {
format!("TAILCALL{}", call.debug_str(ops))
}
&Instruction_::Branch1(ref dest) => {
format!("BRANCH {}", dest.debug_str(ops))
}
&Instruction_::Branch2 {
cond,
ref true_dest,
......@@ -634,7 +830,7 @@ impl Instruction {
&Instruction_::Select {
cond,
true_val,
false_val,
false_val
} => format!(
"SELECT<{} {}> {} {} {}",
ops[cond].ty(),
......@@ -646,7 +842,7 @@ impl Instruction {
&Instruction_::Watchpoint {
id,
ref disable_dest,
ref resume,
ref resume
} => {
match id {
Some(id) => {
......@@ -665,13 +861,13 @@ impl Instruction {
"TRAP<{}> {}",
format_value_types(&self.value),
resume.debug_str(ops)
),
)
}
}
&Instruction_::WPBranch {
wp,
ref disable_dest,
ref enable_dest,
ref enable_dest
} => format!(
"WPBRANCH {} {} {}",
wp,
......@@ -680,16 +876,22 @@ impl Instruction {
),
&Instruction_::Call {
ref data,
ref resume,
} => format!("CALL{} {}", data.debug_str(ops), resume.debug_str(ops)),
ref resume
} => {
format!("CALL{} {}", data.debug_str(ops), resume.debug_str(ops))
}
&Instruction_::CCall {
ref data,
ref resume,
} => format!("CCALL{} {}", data.debug_str(ops), resume.debug_str(ops)),
ref resume
} => format!(
"CCALL{} {}",
data.debug_str(ops),
resume.debug_str(ops)
),
&Instruction_::SwapStackExpr {
stack,
is_exception,
ref args,
ref args
} => format!(
"SWAPSTACK {} RET_WITH<{}> {}",
ops[stack],
......@@ -700,7 +902,7 @@ impl Instruction {
stack,
is_exception,
ref args,
ref resume,
ref resume
} => format!(
"SWAPSTACK {} RET_WITH<{}> {} {}",
ops[stack],
......@@ -712,7 +914,7 @@ impl Instruction {
&Instruction_::SwapStackKill {
stack,
is_exception,
ref args,
ref args
} => format!(
"SWAPSTACK {} KILL_OLD {}",
ops[stack],
......@@ -722,7 +924,7 @@ impl Instruction {
&Instruction_::Switch {
cond,
ref default,
ref branches,
ref branches
} => {
//SWITCH < T > opnd default { ( value dest ) rep }
let mut ret = format!(
......@@ -733,7 +935,9 @@ impl Instruction {
);
for i in 0..branches.len() {
let (op, ref dest) = branches[i];
ret.push_str(format!("{} {}", ops[op], dest.debug_str(ops)).as_str());
ret.push_str(
format!("{} {}", ops[op], dest.debug_str(ops)).as_str()
);
if i != branches.len() - 1 {
ret.push_str(" ");
}
......@@ -744,21 +948,27 @@ impl Instruction {