diff options
Diffstat (limited to 'test')
| -rw-r--r-- | test/bench.rs | 163 | 
1 files changed, 163 insertions, 0 deletions
| diff --git a/test/bench.rs b/test/bench.rs new file mode 100644 index 0000000..1d7414d --- /dev/null +++ b/test/bench.rs @@ -0,0 +1,163 @@ +#![feature(test)] + +extern crate test; +extern crate yaxpeax_x86; + +use std::ffi::c_void; + +use std::io::Write; + +use test::Bencher; + +use yaxpeax_x86::{Instruction, Opcode, decode_one}; + +fn decode(bytes: &[u8]) -> Option<Instruction> { +    let mut instr = Instruction::invalid(); +    match decode_one(bytes, &mut instr) { +        Some(()) => Some(instr), +        None => None +    } +} + +#[bench] +fn bench_102000_instrs(b: &mut Bencher) { +    b.iter(|| { +        for i in (0..3000) { +            test::black_box(do_decode_swathe()); +        } +    }) +} + +#[cfg(feature = "capstone_bench")] +#[bench] +fn bench_102000_intrs_capstone(b: &mut Bencher) { +    let handle = get_cs_handle(); +//    panic!("Allocating.."); +    let mut instr: *mut c_void = unsafe { cs_malloc(handle) }; +//    panic!("Allocated..."); +    b.iter(|| { +        for i in (0..3000) { +            test::black_box(do_capstone_decode_swathe(handle, instr)); +        } +    }) +} + +const decode_data: [u8; 130] = [ +    0x48, 0xc7, 0x04, 0x24, 0x00, 0x00, 0x00, 0x00, +    0x48, 0x89, 0x44, 0x24, 0x08, +    0x48, 0x89, 0x43, 0x18, +    0x48, 0xc7, 0x43, 0x10, 0x00, 0x00, 0x00, 0x00, +    0x49, 0x89, 0x4e, 0x08, +    0x48, 0x8b, 0x32, +    0x49, 0x89, 0x46, 0x10, +    0x4d, 0x0f, 0x43, 0xec, 0x49, +    0x0f, 0xb6, 0x06, +    0x0f, 0xb7, 0x06, +    0x66, 0x41, 0x50, +    0x66, 0x41, 0x31, 0xc0, +    0x66, 0x41, 0x32, 0xc0, +    0x40, 0x32, 0xc5, +    0x73, 0x31, +    0x72, 0x5a, +    0x0f, 0x86, 0x8b, 0x01, 0x00, 0x00, +    0x74, 0x47, +    0xff, 0x15, 0x7e, 0x72, 0x24, 0x00, +    0xc3, +    0x48, 0x3d, 0x01, 0xf0, 0xff, 0xff, +    0x3d, 0x01, 0xf0, 0xff, 0xff, +    0x48, 0x83, 0xf8, 0xff, +    0x48, 0x39, 0xc6, +    0x48, 0x8d, 0xa4, 0xc7, 0x20, 0x00, 0x00, 0x12, +    0x33, 0xc0, +    0x48, 0x8d, 0x53, 0x08, +    0x31, 0xc9, +    0x48, 0x29, 0xc8, +    0x48, 0x03, 0x0b, +    0x5b, +    0x41, 0x5e, +    0x48, 0x8d, 0x0c, 0x12, +    0xf6, 0xc2, 0x18 +]; + +fn do_decode_swathe() { +    let mut buf = [0u8; 128]; +    let mut iter = decode_data.iter(); +    let mut result = yaxpeax_x86::Instruction::invalid(); +    loop { +        match yaxpeax_x86::decode_one(&mut iter, &mut result) { +            Some(_) => { +                #[cfg(feature = "capstone_bench")] +                test::black_box(write!(&mut buf[..], "{}", result)); +                test::black_box(&result); +            }, +            None => { +                println!("done."); +                break; +            } +        } +    } +} + +#[cfg(feature = "capstone_bench")] +extern "C" { +    pub fn cs_open(arch: u32, mode: u32, handle: *mut usize) -> usize; +} + +#[cfg(feature = "capstone_bench")] +extern "C" { +    pub fn cs_malloc(handle: usize) -> *mut c_void; +} + +#[cfg(feature = "capstone_bench")] +extern "C" { +    pub fn cs_disasm_iter( +        arch: usize, +        code: *mut *const u8, +        size: *mut usize, +        address: *mut u64, +        insn: *mut c_void +    ) -> bool; +} + +#[cfg(feature = "capstone_bench")] +fn get_cs_handle() -> usize { +    let mut handle: usize = 0; +    let res = unsafe { cs_open(3, 4, &mut handle as *mut usize) }; +    handle +} + +#[cfg(feature = "capstone_bench")] +fn get_instr(handle: usize) -> *mut c_void { +    unsafe { cs_malloc(handle) as *mut c_void } +} + +#[cfg(feature = "capstone_bench")] +fn do_capstone_decode_swathe(cs: usize, instr: *mut c_void) { +    unsafe { +        let mut code = &decode_data as *const u8; +        let mut len = decode_data.len(); +        let mut addr = 0u64; +        loop { +            let result = cs_disasm_iter( +                cs, +                &mut code as *mut *const u8, +                &mut len as *mut usize, +                &mut addr as *mut u64, +                instr +            ); +            //panic!("at least one succeeded"); +            if result == false { +                return; +            } +        } +    } +} + +//#[bench] +//#[ignore] +// VEX prefixes are not supported at the moment, in any form +//fn test_avx() { +//    assert_eq!(&format!("{}", decode( +//        &[0xc5, 0xf8, 0x10, 0x00] +//    ).unwrap()), "vmovups xmm0, xmmword [rax]"); +//} | 
