Commit 5c288947 authored by Isaac Oscar Gariano's avatar Isaac Oscar Gariano

Merge branch 'swapstack' of gitlab.anu.edu.au:mu/mu-impl-fast into swapstack

parents 5d84eaa1 b5262087
image: "qinsoon/ubuntu-zebu-test:latest"
stages:
- build
- test
- rustfmt
before_script:
- export PATH=$PATH:/root/.cargo/bin
- export MU_ZEBU=$CI_PROJECT_DIR
- export ZEBU_BUILD=release
- export CARGO_HOME=.cargo
- export CC=clang
- source /home/gitlab-runner/ci/bin/activate
build:
stage: build
......@@ -117,4 +115,4 @@ testjit:som:
rustfmt:
stage: rustfmt
script:
- rustup run nightly cargo fmt -- --write-mode=diff src/ast/src/lib.rs src/gc/src/lib.rs src/utils/src/lib.rs --verbose
- CARGO_HOME=/home/gitlab-runner/.cargo rustup run nightly-2017-07-19 cargo fmt -- --write-mode=diff src/ast/src/lib.rs src/gc/src/lib.rs src/utils/src/lib.rs --verbose
......@@ -77,7 +77,52 @@ impl Instruction {
SwapStackKill { .. } |
Switch { .. } |
ExnInstruction { .. } => true,
_ => false,
BinOp(_, _, _) |
BinOpWithStatus(_, _, _, _) |
CmpOp(_, _, _) |
ConvOp { .. } |
ExprCall { .. } |
ExprCCall { .. } |
Load { .. } |
Store { .. } |
CmpXchg { .. } |
AtomicRMW { .. } |
New(_) |
AllocA(_) |
NewHybrid(_, _) |
AllocAHybrid(_, _) |
NewStack(_) |
NewThread(_, _) |
NewThreadExn(_, _) |
NewFrameCursor(_) |
GetIRef(_) |
GetFieldIRef { .. } |
GetElementIRef { .. } |
ShiftIRef { .. } |
GetVarPartIRef { .. } |
Select { .. } |
Fence(_) |
CommonInst_GetThreadLocal |
CommonInst_SetThreadLocal(_) |
CommonInst_Pin(_) |
CommonInst_Unpin(_) |
CommonInst_GetAddr(_) |
CommonInst_Tr64IsFp(_) |
CommonInst_Tr64IsInt(_) |
CommonInst_Tr64IsRef(_) |
CommonInst_Tr64FromFp(_) |
CommonInst_Tr64FromInt(_) |
CommonInst_Tr64FromRef(_, _) |
CommonInst_Tr64ToFp(_) |
CommonInst_Tr64ToInt(_) |
CommonInst_Tr64ToRef(_) |
CommonInst_Tr64ToTag(_) |
Move(_) |
PrintHex(_) |
SetRetval(_) |
KillStack(_) |
CurrentStack |
SwapStackExpr { .. } => false
}
}
......@@ -94,17 +139,66 @@ impl Instruction {
use inst::Instruction_::*;
match self.v {
ExprCall { .. } | ExprCCall { .. } | Load { .. } | Store { .. } | CmpXchg { .. } | AtomicRMW { .. } |
New(_) | AllocA(_) | NewHybrid(_, _) | AllocAHybrid(_, _) | NewStack(_) | NewThread(_, _) |
NewThreadExn(_, _) | NewFrameCursor(_) | Fence(_) | Return(_) | ThreadExit | KillStack(_) |
ExprCall { .. } |
ExprCCall { .. } |
Load { .. } |
Store { .. } |
CmpXchg { .. } |
AtomicRMW { .. } |
New(_) |
AllocA(_) |
NewHybrid(_, _) |
AllocAHybrid(_, _) |
NewStack(_) |
NewThread(_, _) |
NewThreadExn(_, _) |
NewFrameCursor(_) |
Fence(_) |
Return(_) |
ThreadExit |
Throw(_) |
TailCall(_) | Branch1(_) | Branch2 { .. } | Watchpoint { .. } | WPBranch { .. } |
Call { .. } | CCall { .. }| SwapStackExpr{..}| SwapStackExc { .. } | SwapStackKill { .. } | Switch { .. } | ExnInstruction { .. } |
CommonInst_GetThreadLocal | CommonInst_SetThreadLocal(_) | CommonInst_Pin(_) | CommonInst_Unpin(_) |
CommonInst_GetAddr(_) | PrintHex(_) | SetRetval(_) |
CurrentStack // Just heir to prevent interferance with swapstacks
=> true,
_ => false
TailCall(_) |
Branch1(_) |
Branch2 { .. } |
Watchpoint { .. } |
WPBranch { .. } |
Call { .. } |
CCall { .. } |
SwapStackExpr { .. } |
SwapStackExc { .. } |
SwapStackKill { .. } |
Switch { .. } |
ExnInstruction { .. } |
CommonInst_GetThreadLocal |
CommonInst_SetThreadLocal(_) |
CommonInst_Pin(_) |
CommonInst_Unpin(_) |
CommonInst_GetAddr(_) |
PrintHex(_) |
SetRetval(_) |
KillStack(_) |
CurrentStack => true,
BinOp(_, _, _) |
BinOpWithStatus(_, _, _, _) |
CmpOp(_, _, _) |
ConvOp { .. } |
GetIRef(_) |
GetFieldIRef { .. } |
GetElementIRef { .. } |
ShiftIRef { .. } |
GetVarPartIRef { .. } |
Select { .. } |
CommonInst_Tr64IsFp(_) |
CommonInst_Tr64IsInt(_) |
CommonInst_Tr64IsRef(_) |
CommonInst_Tr64FromFp(_) |
CommonInst_Tr64FromInt(_) |
CommonInst_Tr64FromRef(_, _) |
CommonInst_Tr64ToFp(_) |
CommonInst_Tr64ToInt(_) |
CommonInst_Tr64ToRef(_) |
CommonInst_Tr64ToTag(_) |
Move(_) => false
}
}
......@@ -117,9 +211,63 @@ impl Instruction {
Watchpoint { .. } |
Call { .. } |
CCall { .. } |
SwapStackExc {..} |
SwapStackExc { .. } |
ExnInstruction { .. } => true,
_ => false,
BinOp(_, _, _) |
BinOpWithStatus(_, _, _, _) |
CmpOp(_, _, _) |
ConvOp { .. } |
ExprCall { .. } |
ExprCCall { .. } |
Load { .. } |
Store { .. } |
CmpXchg { .. } |
AtomicRMW { .. } |
New(_) |
AllocA(_) |
NewHybrid(_, _) |
AllocAHybrid(_, _) |
NewStack(_) |
NewThread(_, _) |
NewThreadExn(_, _) |
NewFrameCursor(_) |
GetIRef(_) |
GetFieldIRef { .. } |
GetElementIRef { .. } |
ShiftIRef { .. } |
GetVarPartIRef { .. } |
Fence(_) |
Return(_) |
ThreadExit |
Throw(_) |
TailCall(_) |
Branch1(_) |
Branch2 { .. } |
Select { .. } |
WPBranch { .. } |
Switch { .. } |
CommonInst_GetThreadLocal |
CommonInst_SetThreadLocal(_) |
CommonInst_Pin(_) |
CommonInst_Unpin(_) |
CommonInst_GetAddr(_) |
CommonInst_Tr64IsFp(_) |
CommonInst_Tr64IsInt(_) |
CommonInst_Tr64IsRef(_) |
CommonInst_Tr64FromFp(_) |
CommonInst_Tr64FromInt(_) |
CommonInst_Tr64FromRef(_, _) |
CommonInst_Tr64ToFp(_) |
CommonInst_Tr64ToInt(_) |
CommonInst_Tr64ToRef(_) |
CommonInst_Tr64ToTag(_) |
Move(_) |
PrintHex(_) |
SetRetval(_) |
KillStack(_) |
CurrentStack |
SwapStackExpr { .. } |
SwapStackKill { .. } => false
}
}
......@@ -136,9 +284,63 @@ impl Instruction {
Watchpoint { ref resume, .. } |
Call { ref resume, .. } |
CCall { ref resume, .. } |
SwapStackExc { ref resume, ..} |
SwapStackExc { ref resume, .. } |
ExnInstruction { ref resume, .. } => Some(resume.exn_dest.target),
_ => None
BinOp(_, _, _) |
BinOpWithStatus(_, _, _, _) |
CmpOp(_, _, _) |
ConvOp { .. } |
ExprCall { .. } |
ExprCCall { .. } |
Load { .. } |
Store { .. } |
CmpXchg { .. } |
AtomicRMW { .. } |
New(_) |
AllocA(_) |
NewHybrid(_, _) |
AllocAHybrid(_, _) |
NewStack(_) |
NewThread(_, _) |
NewThreadExn(_, _) |
NewFrameCursor(_) |
GetIRef(_) |
GetFieldIRef { .. } |
GetElementIRef { .. } |
ShiftIRef { .. } |
GetVarPartIRef { .. } |
Fence(_) |
Return(_) |
ThreadExit |
Throw(_) |
TailCall(_) |
Branch1(_) |
Branch2 { .. } |
Select { .. } |
WPBranch { .. } |
Switch { .. } |
CommonInst_GetThreadLocal |
CommonInst_SetThreadLocal(_) |
CommonInst_Pin(_) |
CommonInst_Unpin(_) |
CommonInst_GetAddr(_) |
CommonInst_Tr64IsFp(_) |
CommonInst_Tr64IsInt(_) |
CommonInst_Tr64IsRef(_) |
CommonInst_Tr64FromFp(_) |
CommonInst_Tr64FromInt(_) |
CommonInst_Tr64FromRef(_, _) |
CommonInst_Tr64ToFp(_) |
CommonInst_Tr64ToInt(_) |
CommonInst_Tr64ToRef(_) |
CommonInst_Tr64ToTag(_) |
Move(_) |
PrintHex(_) |
SetRetval(_) |
KillStack(_) |
CurrentStack |
SwapStackExpr { .. } |
SwapStackKill { .. } => None
}
}
......@@ -249,10 +451,10 @@ pub enum Instruction_ {
/// args: functionref of the entry function
NewStack(OpIndex),
/// Kills the given Mu stack
/// args: stackref to kill
/// kill the given Mu stack
KillStack(OpIndex),
/// return stackref for the current stack
CurrentStack,
/// create a new Mu thread, yields thread reference
......@@ -361,7 +563,7 @@ pub enum Instruction_ {
resume: ResumptionData
},
// A swap stack with an exception clause (i.e. uses the RET_WITH form)
/// A swap stack with an exception clause (i.e. uses the RET_WITH form)
SwapStackExc {
stack: OpIndex,
is_exception: bool,
......@@ -369,20 +571,21 @@ pub enum Instruction_ {
resume: ResumptionData
},
// A swap stack without an exception clause that is not a terminator (i.e. uses the RET_WITH form)
/// A swap stack without an exception clause that is not a terminator
/// (i.e. uses the RET_WITH form)
SwapStackExpr {
stack: OpIndex,
is_exception: bool,
args: Vec<OpIndex>,
args: Vec<OpIndex>
},
// A swapstack without an exception clause that is a terminator (i.e. one with KILL_OLD)
/// A swapstack without an exception clause that is a terminator (i.e. one with KILL_OLD)
SwapStackKill {
stack: OpIndex,
is_exception: bool,
args: Vec<OpIndex>,
args: Vec<OpIndex>
},
/// a multiway branch
Switch {
cond: OpIndex,
......@@ -630,14 +833,14 @@ impl Instruction_ {
ref data,
ref resume
} => format!("CALL {} {}", data.debug_str(ops), resume.debug_str(ops)),
&Instruction_::CCall {
&Instruction_::CCall {
ref data,
ref resume
} => format!("CCALL {} {}", data.debug_str(ops), resume.debug_str(ops)),
&Instruction_::SwapStackExpr {
stack,
is_exception,
ref args,
ref args
} => {
format!(
"SWAPSTACK {} {} {}",
......@@ -664,7 +867,7 @@ impl Instruction_ {
&Instruction_::SwapStackKill {
stack,
is_exception,
ref args,
ref args
} => {
format!(
"SWAPSTACK {} {} {}",
......@@ -673,7 +876,7 @@ impl Instruction_ {
op_vector_str(args, ops),
)
}
&Instruction_::Switch {
cond,
ref default,
......
......@@ -935,7 +935,6 @@ impl TreeNode {
TreeNode_::Value(ref pv) => pv.ty.clone()
}
}
}
impl fmt::Display for TreeNode {
......@@ -1069,7 +1068,7 @@ impl Value {
}
const DISPLAY_ID: bool = true;
const DISPLAY_TYPE: bool = false;
const DISPLAY_TYPE: bool = true;
const PRINT_ABBREVIATE_NAME: bool = true;
impl fmt::Debug for Value {
......
......@@ -13,8 +13,7 @@
// limitations under the License.
#[derive(Copy, Clone, Debug, PartialEq)]
pub
enum BinOp {
pub enum BinOp {
// BinOp Int(n) Int(n) -> Int(n)
Add,
Sub,
......@@ -44,11 +43,7 @@ impl BinOp {
pub fn is_fp(self) -> bool {
use op::BinOp::*;
match self {
FAdd |
FSub |
FMul |
FDiv |
FRem => true,
FAdd | FSub | FMul | FDiv | FRem => true,
_ => false
}
}
......@@ -188,19 +183,21 @@ impl CmpOp {
}
}
pub fn is_fp_cmp(self) -> bool { !self.is_int_cmp() }
pub fn is_fp_cmp(self) -> bool {
!self.is_int_cmp()
}
pub fn is_eq_cmp(self) -> bool {
use op::CmpOp::*;
match self {
EQ | NE => true,
EQ | NE => true,
_ => false
}
}
pub fn is_ult_cmp(self) -> bool {
use op::CmpOp::*;
match self {
UGE | UGT | ULE | ULT => true,
_ => false
UGE | UGT | ULE | ULT => true,
_ => false
}
}
......
......@@ -1584,12 +1584,16 @@ impl<'a> InstructionSelection {
// get thread local and add offset to get sp_loc
let tl = self.emit_get_threadlocal(Some(node), f_content, f_context, vm);
self.backend
.emit_add_r_imm(&tl, *thread::NATIVE_SP_LOC_OFFSET as i32);
self.emit_load_base_offset(
&tl,
&tl,
*thread::NATIVE_SP_LOC_OFFSET as i32,
vm
);
// emit a call to swap_back_to_native_stack(sp_loc: Address)
self.emit_runtime_entry(
&entrypoints::SWAP_BACK_TO_NATIVE_STACK,
&entrypoints::MUENTRY_THREAD_EXIT,
vec![tl.clone()],
None,
Some(node),
......
......@@ -42,6 +42,7 @@ use ast::ptr::P;
use ast::ir::*;
use ast::types::*;
use compiler::backend::RegGroup;
use vm::VM;
use utils::LinkedHashMap;
use std::collections::HashMap;
......@@ -654,7 +655,9 @@ pub fn estimate_insts_for_ir(inst: &Instruction) -> usize {
// runtime call
New(_) | NewHybrid(_, _) => 10,
NewStack(_) | NewThread(_, _) | NewThreadExn(_, _) | NewFrameCursor(_) => 10,
ThreadExit => 10, CurrentStack => 10, KillStack(_) => 10,
ThreadExit => 10,
CurrentStack => 10,
KillStack(_) => 10,
Throw(_) => 10,
SwapStackExpr { .. } | SwapStackExc { .. } | SwapStackKill { .. } => 10,
CommonInst_GetThreadLocal | CommonInst_SetThreadLocal(_) => 10,
......
......@@ -138,6 +138,13 @@ impl HeapDump {
let field_addr = base + *offset;
let edge = unsafe { field_addr.load::<Address>() };
trace!(
"object reference from {} -> {} at +[{}]",
base,
edge,
offset
);
if !edge.is_zero() && !self.objects.contains_key(&edge) {
work_queue.push(edge);
}
......
......@@ -655,8 +655,8 @@ pub fn run_test_2f(vm: &VM, test_name: &str, dep_name: &str, tester_name: &str)
let output_name = test_name.to_string() + "_" + tester_name;
let executable = link_test_primordial(
vec![
test_name.to_string(),
dep_name.to_string(),
test_name.to_string(),
tester_name.to_string(),
],
output_name.as_str(),
......
......@@ -16,7 +16,7 @@
# swap_stack_to(new_sp: Address, entry: Address, old_sp_loc: Address)
# %rdi %rsi %rdx
begin_func swap_to_mu_stack
begin_func muthread_start_pass
# -- on old stack --
# C calling convention
pushq %rbp
......@@ -63,7 +63,7 @@ begin_func swap_to_mu_stack
# push entry function and start it
pushq %rax
ret
end_func swap_to_mu_stack
end_func muthread_start_pass
# _swap_back_to_native_stack(sp_loc: Address)
# %rdi
......
......@@ -26,7 +26,6 @@ macro_rules! assert_ir {
($ cond : expr , $ ( $ arg : tt ) + ) => { debug_assert!($cond, $($arg)+)};
}
pub struct MuIRBuilder {
/// ref to MuVM
mvm: *const MuVM,
......@@ -2429,7 +2428,8 @@ impl<'lb, 'lvm> BundleLoader<'lb, 'lvm> {
let impl_opnd2 = self.get_treenode(fcb, opnd2);
assert_ir!(
impl_opnd1.ty() == impl_opnd2.ty() && impl_opnd1.ty() == impl_ty,
"Invalid instruction {:?}: Operand types {} and {} are not what was expected {}",
"Invalid instruction {:?}: Operand types {} and {} \
are not what was expected {}",
inst,
impl_opnd1.ty(),
impl_opnd2.ty(),
......@@ -3442,7 +3442,8 @@ impl<'lb, 'lvm> BundleLoader<'lb, 'lvm> {
self.build_destination(fcb, ecnode.exc, &mut ops, &[], blocks);
assert_ir!(match **cur_stack_clause {
NodeCurrentStackClause::KillOld { .. } => false, // Can't have an exception
// Can't have an exception
NodeCurrentStackClause::KillOld { .. } => false,
// clause
_ => true
});
......@@ -3832,7 +3833,8 @@ impl<'lb, 'lvm> BundleLoader<'lb, 'lvm> {
}
CMU_CI_UVM_NEW_STACK => {
assert_ir!(
tys.is_empty() && flags.is_empty() && exc_clause.is_none() && keepalives.is_none()
tys.is_empty() && flags.is_empty() && exc_clause.is_none() &&
keepalives.is_none()
);
assert!(sigs.len() == 1);
......@@ -3843,15 +3845,14 @@ impl<'lb, 'lvm> BundleLoader<'lb, 'lvm> {
let impl_sig = self.ensure_sig_rec(sigs[0]);
assert_ir!(impl_sig.ret_tys.is_empty()); // The function isn't supposed to return
assert_ir!(
match impl_opnd.ty().v {
MuType_::FuncRef(ref sig) => *sig == impl_sig,
_ => false
}
);
assert_ir!(match impl_opnd.ty().v {
MuType_::FuncRef(ref sig) => *sig == impl_sig,
_ => false
});
let impl_stackref = self.ensure_stackref();
let impl_rv = self.new_ssa(fcb, result_ids[0], impl_stackref).clone_value();
let impl_rv = self.new_ssa(fcb, result_ids[0], impl_stackref)
.clone_value();
Instruction {
hdr: hdr,
......@@ -3863,13 +3864,15 @@ impl<'lb, 'lvm> BundleLoader<'lb, 'lvm> {
CMU_CI_UVM_CURRENT_STACK => {
assert_ir!(
tys.is_empty() && args.is_empty() && sigs.is_empty() && flags.is_empty() &&
exc_clause.is_none() && keepalives.is_none()
exc_clause.is_none() &&
keepalives.is_none()
);
assert!(result_ids.len() == 1);
let impl_stackref = self.ensure_stackref();
let impl_rv = self.new_ssa(fcb, result_ids[0], impl_stackref).clone_value();
let impl_rv = self.new_ssa(fcb, result_ids[0], impl_stackref)
.clone_value();
Instruction {
hdr: hdr,
......@@ -3880,8 +3883,9 @@ impl<'lb, 'lvm> BundleLoader<'lb, 'lvm> {
}
CMU_CI_UVM_KILL_STACK => {
assert_ir!(
tys.is_empty() && sigs.is_empty() && flags.is_empty() && exc_clause.is_none() && keepalives.is_none()
&& result_ids.is_empty()
tys.is_empty() && sigs.is_empty() && flags.is_empty() &&
exc_clause.is_none() && keepalives.is_none() &&
result_ids.is_empty()
);
assert!(args.len() == 1);
......
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