WARNING! Access to this system is limited to authorised users only.
Unauthorised users may be subject to prosecution.
Unauthorised access to this system is a criminal offence under Australian law (Federal Crimes Act 1914 Part VIA)
It is a criminal offence to:
(1) Obtain access to data without authority. -Penalty 2 years imprisonment.
(2) Damage, delete, alter or insert data without authority. -Penalty 10 years imprisonment.
User activity is monitored and recorded. Anyone using this system expressly consents to such monitoring and recording.

To protect your data, the CISO officer has suggested users to enable 2FA as soon as possible.
Currently 2.7% of users enabled 2FA.

Commit 7fa67a5f authored by qinsoon's avatar qinsoon
Browse files

detecting infinite loop when eliminating jump-to-jump. This seems to

reveal a rodal bug.
parent 8a1a2d3f
......@@ -155,12 +155,25 @@ impl PeepholeOptimization {
let orig_inst = inst;
// the destination we will rewrite the instruction to branch to
let final_dest: Option<MuName> = {
use std::collections::HashSet;
let mut cur_inst = inst;
let mut last_dest = None;
let mut visited_labels = HashSet::new();
loop {
let opt_dest = mc.is_jmp(cur_inst);
match opt_dest {
Some(ref dest) => {
// if we have already visited this instruction
// this means we met an infinite loop, we need to break
if visited_labels.contains(dest) {
warn!("met an infinite loop in removing jump-to-jump");
warn!("we are not optimizing this case");
return;
}
// get the block for destination
let first_inst = mc.get_block_range(dest).unwrap().start;
debug_assert!(
......@@ -179,6 +192,8 @@ impl PeepholeOptimization {
// its a jump-to-jump case
cur_inst = first_inst;
last_dest = Some(dest2.clone());
visited_labels.insert(dest2.clone());
debug!("visited {}", dest2);
}
None => break
}
......@@ -190,19 +205,7 @@ impl PeepholeOptimization {
};
if let Some(dest) = final_dest {
let first_inst = {
let start = mc.get_block_range(&dest).unwrap().start;
match mc.get_next_inst(start) {
Some(i) => i,
None => {
panic!(
"we are jumping to a block {}\
that does not have instructions?",
dest
)
}
}
};
let first_inst = mc.get_block_range(&dest).unwrap().start;
info!(
"inst {} chain jumps to {}, rewrite as branching to {} (successor: {})",
......
......@@ -405,7 +405,7 @@ macro_rules! inst {
target: $dest.id(),
args: {
let mut i =0;
vec![$($arg.clone()),*].iter().map(|_| {
vec![$($arg.clone()),*].iter().map(|_: &Arc<TreeNode>| {
let ret = DestArg::Normal(i); i+=1; ret
}).collect()
}
......
......@@ -30,3 +30,4 @@ mod test_inline;
mod test_convop;
mod test_int128;
mod test_misc;
mod test_opt;
\ No newline at end of file
......@@ -8,6 +8,7 @@ use self::mu::ast::inst::*;
use self::mu::vm::*;
use self::mu::linkutils;
use self::mu::utils::LinkedHashMap;
use std::sync::Arc;
#[test]
fn test_mov_minus_one_to_int8() {
......
// Copyright 2017 The Australian National University
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
extern crate libloading;
use mu::ast::types::*;
use mu::ast::ir::*;
use mu::ast::ptr::*;
use mu::ast::inst::*;
use mu::ast::op::*;
use mu::vm::*;
use mu::compiler::*;
use std::sync::Arc;
use mu::linkutils;
use mu::linkutils::aot;
use mu::utils::LinkedHashMap;
#[test]
#[should_panic]
fn test_infinite_loop1() {
VM::start_logging_trace();
let vm = Arc::new(infinite_loop1());
let func_id = vm.id_of("infinite_loop1");
let func_handle = vm.handle_from_func(func_id);
let test_name = "test_infinite_loop1";
vm.make_boot_image(
vec![func_id],
Some(&func_handle),
None,
None,
vec![],
vec![],
vec![],
vec![],
test_name.to_string()
);
}
fn infinite_loop1() -> VM {
let vm = VM::new();
funcsig! ((vm) sig = () -> ());
funcdecl! ((vm) <sig> infinite_loop1);
funcdef! ((vm) <sig> infinite_loop1 VERSION infinite_loop1_v1);
// entry:
block! ((vm, infinite_loop1_v1) blk_entry);
block! ((vm, infinite_loop1_v1) blk_loop);
inst! ((vm, infinite_loop1_v1) blk_entry_branch:
BRANCH blk_loop ()
);
define_block!((vm, infinite_loop1_v1) blk_entry() {
blk_entry_branch
});
// loop
inst! ((vm, infinite_loop1_v1) blk_loop_branch:
BRANCH blk_loop ()
);
define_block!((vm, infinite_loop1_v1) blk_loop() {
blk_loop_branch
});
define_func_ver!((vm) infinite_loop1_v1 (entry: blk_entry) {
blk_entry, blk_loop
});
vm
}
#[test]
#[should_panic]
fn test_infinite_loop2() {
VM::start_logging_trace();
let vm = Arc::new(infinite_loop2());
let func_id = vm.id_of("infinite_loop2");
let func_handle = vm.handle_from_func(func_id);
let test_name = "test_infinite_loop2";
vm.make_boot_image(
vec![func_id],
Some(&func_handle),
None,
None,
vec![],
vec![],
vec![],
vec![],
test_name.to_string()
);
}
fn infinite_loop2() -> VM {
let vm = VM::new();
funcsig! ((vm) sig = () -> ());
funcdecl! ((vm) <sig> infinite_loop2);
funcdef! ((vm) <sig> infinite_loop2 VERSION infinite_loop2_v1);
// entry:
block! ((vm, infinite_loop2_v1) blk_entry);
block! ((vm, infinite_loop2_v1) blk_a);
block! ((vm, infinite_loop2_v1) blk_b);
inst! ((vm, infinite_loop2_v1) blk_entry_branch:
BRANCH blk_a ()
);
define_block!((vm, infinite_loop2_v1) blk_entry() {
blk_entry_branch
});
// blk a
inst! ((vm, infinite_loop2_v1) blk_a_branch:
BRANCH blk_b ()
);
define_block!((vm, infinite_loop2_v1) blk_a() {
blk_a_branch
});
// blk b
inst! ((vm, infinite_loop2_v1) blk_b_branch:
BRANCH blk_a ()
);
define_block!((vm, infinite_loop2_v1) blk_b() {
blk_b_branch
});
define_func_ver!((vm) infinite_loop2_v1 (entry: blk_entry) {
blk_entry, blk_a, blk_b
});
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