From dec3db285e8336820a700da0b8974a884cdd9aaf Mon Sep 17 00:00:00 2001 From: oyvindln Date: Sun, 15 Oct 2017 19:15:49 +0200 Subject: [PATCH] Add `no_c_export` feature to disable no_mangle so we don't need objcopy for benching Also fixes name of linked library in performance.sh --- Cargo.toml | 5 +-- benches/bench.rs | 84 ++++++++++++++++++++++++++---------------------- performance.sh | 2 +- src/build.rs | 17 ++++++---- src/lib.rs | 60 ++++++++++++++-------------------- src/tdef.rs | 14 +++----- src/tinfl.rs | 5 ++- src/unmangle.rs | 22 +++++++++++++ 8 files changed, 115 insertions(+), 94 deletions(-) mode change 100644 => 100755 benches/bench.rs mode change 100644 => 100755 src/tinfl.rs create mode 100644 src/unmangle.rs diff --git a/Cargo.toml b/Cargo.toml index 3b7acc11..cd1c2bba 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -30,10 +30,11 @@ cc = "1.0" [features] default = [] miniz_zip = ["build_stub_miniz"] -fuzzing = ["build_orig_miniz"] -benching = ["build_orig_miniz"] +fuzzing = ["build_orig_miniz", "no_c_export"] +benching = ["build_orig_miniz", "no_c_export"] build_orig_miniz = [] build_stub_miniz = [] +no_c_export = [] [profile.dev] panic = "abort" diff --git a/benches/bench.rs b/benches/bench.rs old mode 100644 new mode 100755 index 3c49f07c..410e4d38 --- a/benches/bench.rs +++ b/benches/bench.rs @@ -14,8 +14,7 @@ use libc::{c_int, c_void}; use miniz_oxide::deflate::compress_to_vec; use miniz_oxide::deflate::core::{create_comp_flags_from_zip_params, CompressorOxide}; -use miniz_oxide_c_api::{miniz_def_free_func, tdefl_compress_mem_to_heap, - tinfl_decompress_mem_to_heap}; +use miniz_oxide_c_api::miniz_def_free_func; /// Safe wrapper around a buffer. pub struct HeapBuf { @@ -35,22 +34,6 @@ fn w(buf: *mut c_void) -> HeapBuf { HeapBuf { buf: buf } } -extern "C" { - fn c_tinfl_decompress_mem_to_heap( - src_buf: *const c_void, - src_buf_len: usize, - out_len: *mut usize, - flags: c_int, - ) -> *mut c_void; - - fn c_tdefl_compress_mem_to_heap( - src_buf: *const c_void, - src_buf_len: usize, - out_len: *mut usize, - flags: c_int, - ) -> *mut c_void; -} - fn get_test_file_data(name: &str) -> Vec { use std::fs::File; let mut input = Vec::new(); @@ -69,7 +52,7 @@ macro_rules! decompress_bench { let mut out_len: usize = 0; b.iter(|| unsafe { - ::w(::$decompress_func( + ::w($decompress_func( compressed.as_ptr() as *mut ::c_void, compressed.len(), &mut out_len, @@ -89,7 +72,7 @@ macro_rules! compress_bench { let mut out_len: usize = 0; let flags = ::create_comp_flags_from_zip_params($level, -15, 0) as i32; b.iter(|| unsafe { - ::w(::$compress_func( + ::w($compress_func( input.as_ptr() as *mut ::c_void, input.len(), &mut out_len, @@ -101,6 +84,8 @@ macro_rules! compress_bench { } mod oxide { + use miniz_oxide_c_api::{tdefl_compress_mem_to_heap, tinfl_decompress_mem_to_heap}; + compress_bench!( compress_bin_lvl_1, tdefl_compress_mem_to_heap, @@ -217,116 +202,139 @@ mod oxide { } mod miniz { + use libc::{c_void, c_int}; + + /// Functions from miniz + /// We add the link attribute to make sure + /// these are linked to the miniz ones rather than + /// picking up the rust versions (as they may be exported). + #[link(name = "miniz")] + extern "C" { + fn tinfl_decompress_mem_to_heap( + src_buf: *const c_void, + src_buf_len: usize, + out_len: *mut usize, + flags: c_int, + ) -> *mut c_void; + + fn tdefl_compress_mem_to_heap( + src_buf: *const c_void, + src_buf_len: usize, + out_len: *mut usize, + flags: c_int, + ) -> *mut c_void; + } + compress_bench!( compress_bin_lvl_1, - c_tdefl_compress_mem_to_heap, + tdefl_compress_mem_to_heap, 1, "benches/data/bin" ); compress_bench!( compress_bin_lvl_6, - c_tdefl_compress_mem_to_heap, + tdefl_compress_mem_to_heap, 6, "benches/data/bin" ); compress_bench!( compress_bin_lvl_9, - c_tdefl_compress_mem_to_heap, + tdefl_compress_mem_to_heap, 9, "benches/data/bin" ); compress_bench!( compress_code_lvl_1, - c_tdefl_compress_mem_to_heap, + tdefl_compress_mem_to_heap, 1, "benches/data/code" ); compress_bench!( compress_code_lvl_6, - c_tdefl_compress_mem_to_heap, + tdefl_compress_mem_to_heap, 6, "benches/data/code" ); compress_bench!( compress_code_lvl_9, - c_tdefl_compress_mem_to_heap, + tdefl_compress_mem_to_heap, 9, "benches/data/code" ); compress_bench!( compress_compressed_lvl_1, - c_tdefl_compress_mem_to_heap, + tdefl_compress_mem_to_heap, 1, "benches/data/compressed" ); compress_bench!( compress_compressed_lvl_6, - c_tdefl_compress_mem_to_heap, + tdefl_compress_mem_to_heap, 6, "benches/data/compressed" ); compress_bench!( compress_compressed_lvl_9, - c_tdefl_compress_mem_to_heap, + tdefl_compress_mem_to_heap, 9, "benches/data/compressed" ); decompress_bench!( decompress_bin_lvl_1, - c_tinfl_decompress_mem_to_heap, + tinfl_decompress_mem_to_heap, 1, "benches/data/bin" ); decompress_bench!( decompress_bin_lvl_6, - c_tinfl_decompress_mem_to_heap, + tinfl_decompress_mem_to_heap, 6, "benches/data/bin" ); decompress_bench!( decompress_bin_lvl_9, - c_tinfl_decompress_mem_to_heap, + tinfl_decompress_mem_to_heap, 9, "benches/data/bin" ); decompress_bench!( decompress_code_lvl_1, - c_tinfl_decompress_mem_to_heap, + tinfl_decompress_mem_to_heap, 1, "benches/data/code" ); decompress_bench!( decompress_code_lvl_6, - c_tinfl_decompress_mem_to_heap, + tinfl_decompress_mem_to_heap, 6, "benches/data/code" ); decompress_bench!( decompress_code_lvl_9, - c_tinfl_decompress_mem_to_heap, + tinfl_decompress_mem_to_heap, 9, "benches/data/code" ); decompress_bench!( decompress_compressed_lvl_1, - c_tinfl_decompress_mem_to_heap, + tinfl_decompress_mem_to_heap, 1, "benches/data/compressed" ); decompress_bench!( decompress_compressed_lvl_6, - c_tinfl_decompress_mem_to_heap, + tinfl_decompress_mem_to_heap, 6, "benches/data/compressed" ); decompress_bench!( decompress_compressed_lvl_9, - c_tinfl_decompress_mem_to_heap, + tinfl_decompress_mem_to_heap, 9, "benches/data/compressed" ); diff --git a/performance.sh b/performance.sh index 6eff4bfd..6583150d 100755 --- a/performance.sh +++ b/performance.sh @@ -5,7 +5,7 @@ set -e ./build.sh --release mkdir -p bin -g++ tests/miniz_tester.cpp tests/timer.cpp -o bin/miniz_tester -I. -O2 -L. -lminiz_oxide -lutil -ldl -lrt -lpthread -lgcc_s -lc -lm -lrt -lpthread -lutil +g++ tests/miniz_tester.cpp tests/timer.cpp -o bin/miniz_tester -I. -O2 -L. -lminiz_oxide_c_api -lutil -ldl -lrt -lpthread -lgcc_s -lc -lm -lrt -lpthread -lutil #g++ tests/miniz_tester.cpp tests/timer.cpp miniz/* -o bin/miniz_tester -I. -O2 mkdir -p test_scratch diff --git a/src/build.rs b/src/build.rs index 429591b5..8f9428d8 100644 --- a/src/build.rs +++ b/src/build.rs @@ -1,4 +1,4 @@ -#[cfg(feature = "build_stub_miniz")] +#[cfg(any(feature = "build_stub_miniz", feature = "build_orig_miniz"))] extern crate cc; #[cfg(not(any(feature = "build_stub_miniz", feature = "build_orig_miniz")))] @@ -20,9 +20,14 @@ fn main() { #[cfg(feature = "build_orig_miniz")] fn main() { - use std::process::Command; - - Command::new("./build_orig_miniz.sh").status().unwrap(); - println!("cargo:rustc-link-search=native=bin"); - println!("cargo:rustc-link-lib=static=miniz"); + cc::Build::new() + .files( + &[ + "miniz/miniz.c", + "miniz/miniz_zip.c", + "miniz/miniz_tinfl.c", + "miniz/miniz_tdef.c", + ], + ) + .compile("libminiz.a"); } diff --git a/src/lib.rs b/src/lib.rs index 198e1159..1e2f3e0c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -16,17 +16,22 @@ pub use miniz_oxide::mz_adler32_oxide; use miniz_oxide::deflate::CompressionLevel; use miniz_oxide::deflate::core::CompressionStrategy; +#[macro_use] +mod unmangle; + pub mod lib_oxide; use lib_oxide::*; mod tinfl; -pub use tinfl::{tinfl_decompress, tinfl_decompress_mem_to_heap, tinfl_decompress_mem_to_mem, tinfl_decompressor}; +pub use tinfl::{tinfl_decompress, tinfl_decompress_mem_to_heap, + tinfl_decompress_mem_to_mem, tinfl_decompressor}; mod tdef; pub use tdef::{tdefl_compress, tdefl_compress_buffer, tdefl_compress_mem_to_heap, tdefl_compress_mem_to_mem, tdefl_compress_mem_to_output, tdefl_create_comp_flags_from_zip_params, tdefl_get_prev_return_status, tdefl_init, tdefl_get_adler32}; + pub use tdef::flush_modes::*; pub use tdef::strategy::*; @@ -49,7 +54,7 @@ fn as_c_return_code(r: MZResult) -> c_int { } } -#[no_mangle] +unmangle!( pub unsafe extern "C" fn miniz_def_alloc_func( _opaque: *mut c_void, items: size_t, @@ -58,12 +63,10 @@ pub unsafe extern "C" fn miniz_def_alloc_func( libc::malloc(items * size) } -#[no_mangle] pub unsafe extern "C" fn miniz_def_free_func(_opaque: *mut c_void, address: *mut c_void) { libc::free(address) } -#[no_mangle] pub unsafe extern "C" fn miniz_def_realloc_func( _opaque: *mut c_void, address: *mut c_void, @@ -73,7 +76,6 @@ pub unsafe extern "C" fn miniz_def_realloc_func( libc::realloc(address, items * size) } -#[no_mangle] pub unsafe extern "C" fn mz_adler32(adler: c_ulong, ptr: *const u8, buf_len: usize) -> c_ulong { ptr.as_ref().map_or(MZ_ADLER32_INIT, |r| { let data = slice::from_raw_parts(r, buf_len); @@ -81,18 +83,17 @@ pub unsafe extern "C" fn mz_adler32(adler: c_ulong, ptr: *const u8, buf_len: usi }) } -#[no_mangle] pub unsafe extern "C" fn mz_crc32(crc: c_ulong, ptr: *const u8, buf_len: size_t) -> c_ulong { ptr.as_ref().map_or(MZ_CRC32_INIT, |r| { let data = slice::from_raw_parts(r, buf_len); mz_crc32_oxide(crc as c_uint, data) as c_ulong }) } +); macro_rules! oxidize { ($mz_func:ident, $mz_func_oxide:ident; $($arg_name:ident: $type_name:ident),*) => { - #[no_mangle] - #[allow(bad_style)] + unmangle!( pub unsafe extern "C" fn $mz_func(stream: *mut mz_stream, $($arg_name: $type_name),*) -> c_int { match stream.as_mut() { @@ -113,7 +114,7 @@ macro_rules! oxidize { } } } - } + }); }; } @@ -131,9 +132,7 @@ oxidize!(mz_inflate, mz_inflate_oxide; flush: c_int); oxidize!(mz_inflateEnd, mz_inflate_end_oxide;); - -#[no_mangle] -#[allow(bad_style)] +unmangle!( pub unsafe extern "C" fn mz_deflateInit(stream: *mut mz_stream, level: c_int) -> c_int { mz_deflateInit2( stream, @@ -145,7 +144,6 @@ pub unsafe extern "C" fn mz_deflateInit(stream: *mut mz_stream, level: c_int) -> ) } -#[no_mangle] pub unsafe extern "C" fn mz_compress( dest: *mut u8, dest_len: *mut c_ulong, @@ -161,20 +159,6 @@ pub unsafe extern "C" fn mz_compress( ) } -#[cfg(target_bit_width = "64")] -#[inline] -fn buffer_too_large(source_len: c_ulong, dest_len: c_ulong) -> bool { - (source_len | dest_len) > 0xFFFFFFFF -} - -#[cfg(not(target_bit_width = "64"))] -#[inline] -fn buffer_too_large(_source_len: c_ulong, _dest_len: c_ulong) -> bool { - false -} - - -#[no_mangle] pub unsafe extern "C" fn mz_compress2( dest: *mut u8, dest_len: *mut c_ulong, @@ -203,8 +187,6 @@ pub unsafe extern "C" fn mz_compress2( ) } -#[no_mangle] -#[allow(bad_style)] pub extern "C" fn mz_deflateBound(_stream: *mut mz_stream, source_len: c_ulong) -> c_ulong { cmp::max( 128 + (source_len * 110) / 100, @@ -212,14 +194,10 @@ pub extern "C" fn mz_deflateBound(_stream: *mut mz_stream, source_len: c_ulong) ) } - -#[no_mangle] -#[allow(bad_style)] pub unsafe extern "C" fn mz_inflateInit(stream: *mut mz_stream) -> c_int { mz_inflateInit2(stream, MZ_DEFAULT_WINDOW_BITS) } -#[no_mangle] pub unsafe extern "C" fn mz_uncompress( dest: *mut u8, dest_len: *mut c_ulong, @@ -247,8 +225,20 @@ pub unsafe extern "C" fn mz_uncompress( ) } -#[no_mangle] -#[allow(bad_style)] pub extern "C" fn mz_compressBound(source_len: c_ulong) -> c_ulong { mz_deflateBound(ptr::null_mut(), source_len) } + +); + +#[cfg(target_bit_width = "64")] +#[inline] +fn buffer_too_large(source_len: c_ulong, dest_len: c_ulong) -> bool { + (source_len | dest_len) > 0xFFFFFFFF +} + +#[cfg(not(target_bit_width = "64"))] +#[inline] +fn buffer_too_large(_source_len: c_ulong, _dest_len: c_ulong) -> bool { + false +} diff --git a/src/tdef.rs b/src/tdef.rs index f27f2d19..d59c4638 100644 --- a/src/tdef.rs +++ b/src/tdef.rs @@ -64,7 +64,8 @@ impl tdefl_compressor { } } -#[no_mangle] + +unmangle!( pub unsafe extern "C" fn tdefl_compress( d: Option<&mut tdefl_compressor>, in_buf: *const c_void, @@ -127,7 +128,6 @@ pub unsafe extern "C" fn tdefl_compress( } } -#[no_mangle] pub unsafe extern "C" fn tdefl_compress_buffer( d: Option<&mut tdefl_compressor>, in_buf: *const c_void, @@ -137,7 +137,6 @@ pub unsafe extern "C" fn tdefl_compress_buffer( tdefl_compress(d, in_buf, Some(&mut in_size), ptr::null_mut(), None, flush) } -#[no_mangle] pub unsafe extern "C" fn tdefl_init( d: Option<&mut tdefl_compressor>, put_buf_func: PutBufFuncPtr, @@ -157,19 +156,16 @@ pub unsafe extern "C" fn tdefl_init( } } -#[no_mangle] pub unsafe extern "C" fn tdefl_get_prev_return_status( d: Option<&mut tdefl_compressor>, ) -> TDEFLStatus { d.map_or(TDEFLStatus::Okay, |d| d.inner.prev_return_status()) } -#[no_mangle] pub unsafe extern "C" fn tdefl_get_adler32(d: Option<&mut tdefl_compressor>) -> c_uint { d.map_or(::MZ_ADLER32_INIT as u32, |d| d.inner.adler32()) } -#[no_mangle] pub unsafe extern "C" fn tdefl_compress_mem_to_output( buf: *const c_void, buf_len: usize, @@ -197,6 +193,7 @@ pub unsafe extern "C" fn tdefl_compress_mem_to_output( false } } +); struct BufferUser { pub size: usize, @@ -250,7 +247,7 @@ pub unsafe extern "C" fn output_buffer_putter( } } -#[no_mangle] +unmangle!( pub unsafe extern "C" fn tdefl_compress_mem_to_heap( src_buf: *const c_void, src_buf_len: usize, @@ -285,7 +282,6 @@ pub unsafe extern "C" fn tdefl_compress_mem_to_heap( } } -#[no_mangle] pub unsafe extern "C" fn tdefl_compress_mem_to_mem( out_buf: *mut c_void, out_buf_len: usize, @@ -317,7 +313,6 @@ pub unsafe extern "C" fn tdefl_compress_mem_to_mem( } } -#[no_mangle] pub extern "C" fn tdefl_create_comp_flags_from_zip_params( level: c_int, window_bits: c_int, @@ -325,3 +320,4 @@ pub extern "C" fn tdefl_create_comp_flags_from_zip_params( ) -> c_uint { create_comp_flags_from_zip_params(level, window_bits, strategy) } +); diff --git a/src/tinfl.rs b/src/tinfl.rs old mode 100644 new mode 100755 index 27a2fc5b..1959dca9 --- a/src/tinfl.rs +++ b/src/tinfl.rs @@ -9,7 +9,7 @@ pub use miniz_oxide::inflate::core::DecompressorOxide as tinfl_decompressor; pub const TINFL_DECOMPRESS_MEM_TO_MEM_FAILED: size_t = usize::MAX; -#[no_mangle] +unmangle!( pub unsafe extern "C" fn tinfl_decompress( r: *mut tinfl_decompressor, in_buf: *const u8, @@ -35,7 +35,6 @@ pub unsafe extern "C" fn tinfl_decompress( status as i32 } -#[no_mangle] pub unsafe extern "C" fn tinfl_decompress_mem_to_mem( p_out_buf: *mut c_void, out_buf_len: size_t, @@ -61,7 +60,6 @@ pub unsafe extern "C" fn tinfl_decompress_mem_to_mem( } } -#[no_mangle] /// Decompress data from `p_src_buf` to a continuously growing heap-allocated buffer. /// /// Sets `p_out_len` to the length of the returned buffer. @@ -143,6 +141,7 @@ pub unsafe extern "C" fn tinfl_decompress_mem_to_heap( p_buf } +); #[cfg(test)] mod test { diff --git a/src/unmangle.rs b/src/unmangle.rs new file mode 100644 index 00000000..209bcaeb --- /dev/null +++ b/src/unmangle.rs @@ -0,0 +1,22 @@ +/// Unmangle the wrapped functions if no_c_export is not defined. +/// For benchmarks, and other comparisons where we want to have both the miniz and miniz_oxide +/// functions available, functions shouldn not be marked `no_mangle` since that will cause +/// conflicts. +#[cfg(not(feature = "no_c_export"))] +#[macro_export] +macro_rules! unmangle { + ($($it:item)*) => {$( + #[no_mangle] + #[allow(bad_style)] + $it + )*} +} + +#[cfg(feature = "no_c_export")] +#[macro_export] +macro_rules! unmangle { + ($($it:item)*) => {$( + #[allow(bad_style)] + $it + )*} +}