From 4df42b41bb6ec238cdd0f62090354603b234d606 Mon Sep 17 00:00:00 2001 From: Cameron Bytheway Date: Tue, 4 Jun 2024 13:52:52 -0600 Subject: [PATCH] add more inlines for better optimization --- examples/boolean-tree/src/lib.rs | 36 ++++++++++++++- lib/bolero-engine/src/panic.rs | 54 +++++++++++++++-------- lib/bolero-engine/src/test.rs | 20 ++++++--- lib/bolero-generator/src/driver/macros.rs | 23 ++++------ 4 files changed, 92 insertions(+), 41 deletions(-) diff --git a/examples/boolean-tree/src/lib.rs b/examples/boolean-tree/src/lib.rs index 5378ea7..2e64e2a 100644 --- a/examples/boolean-tree/src/lib.rs +++ b/examples/boolean-tree/src/lib.rs @@ -1,4 +1,5 @@ use bolero_generator::TypeGenerator; +use core::fmt; thread_local! { static SHOULD_PANIC: bool = { @@ -13,24 +14,55 @@ thread_local! { #[cfg(test)] mod tests; +#[derive(Copy, Clone)] +pub struct Shape<'a>(&'a Expr); + +impl<'a> fmt::Debug for Shape<'a> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self.0 { + Expr::Value(_) => write!(f, "Value"), + Expr::And(a, b) => f + .debug_tuple("And") + .field(&Shape(a)) + .field(&Shape(b)) + .finish(), + Expr::Or(a, b) => f + .debug_tuple("Or") + .field(&Shape(a)) + .field(&Shape(b)) + .finish(), + Expr::Xor(a, b) => f + .debug_tuple("Xor") + .field(&Shape(a)) + .field(&Shape(b)) + .finish(), + Expr::Not(a) => f.debug_tuple("Not").field(&Shape(a)).finish(), + } + } +} + #[derive(Clone, Debug, TypeGenerator)] pub enum Expr { Value(bool), And(Box, Box), Or(Box, Box), Xor(Box, Box), - Nand(Box, Box), Not(Box), } impl Expr { + #[inline] + pub fn shape(&self) -> Shape { + Shape(self) + } + + #[inline] pub fn eval(&self) -> bool { match self { Expr::Value(value) => *value, Expr::And(a, b) => a.eval() && b.eval(), Expr::Or(a, b) => a.eval() || b.eval(), Expr::Xor(a, b) => a.eval() ^ b.eval(), - Expr::Nand(a, b) => !(a.eval() && b.eval()), Expr::Not(_) if SHOULD_PANIC.with(|v| *v) => unreachable!(), Expr::Not(a) => !a.eval(), } diff --git a/lib/bolero-engine/src/panic.rs b/lib/bolero-engine/src/panic.rs index 2a0c160..efad2bd 100644 --- a/lib/bolero-engine/src/panic.rs +++ b/lib/bolero-engine/src/panic.rs @@ -82,32 +82,44 @@ impl PanicError { } } -pub fn catch Output, Output>(fun: F) -> Result { - catch_unwind(AssertUnwindSafe(|| __panic_marker_start__(fun))).map_err(|err| { - if let Some(err) = take_panic() { - return err; - } - macro_rules! try_downcast { - ($ty:ty, $fmt:expr) => { - if let Some(err) = err.downcast_ref::<$ty>() { - return PanicError::new(format!($fmt, err)); - } - }; +#[inline] +pub fn catch Result, Output>( + fun: F, +) -> Result { + let res = catch_unwind(AssertUnwindSafe(|| __panic_marker_start__(fun))); + match res { + Ok(Ok(v)) => Ok(v), + Ok(Err(err)) => Err(err), + Err(err) => { + if let Some(err) = take_panic() { + return Err(err); + } + macro_rules! try_downcast { + ($ty:ty, $fmt:expr) => { + if let Some(err) = err.downcast_ref::<$ty>() { + return Err(PanicError::new(format!($fmt, err))); + } + }; + } + try_downcast!(PanicInfo, "{}"); + try_downcast!(anyhow::Error, "{}"); + try_downcast!(String, "{}"); + try_downcast!(&'static str, "{}"); + try_downcast!(Box, "{}"); + try_downcast!(Box, "{:?}"); + Err(PanicError::new( + "thread panicked with an unknown error".to_string(), + )) } - try_downcast!(PanicInfo, "{}"); - try_downcast!(anyhow::Error, "{}"); - try_downcast!(String, "{}"); - try_downcast!(&'static str, "{}"); - try_downcast!(Box, "{}"); - try_downcast!(Box, "{:?}"); - PanicError::new("thread panicked with an unknown error".to_string()) - }) + } } +#[inline] pub fn take_panic() -> Option { ERROR.with(|error| error.borrow_mut().take()) } +#[inline] pub fn capture_backtrace(value: bool) -> bool { CAPTURE_BACKTRACE.with(|cell| { let prev = *cell.borrow(); @@ -116,6 +128,7 @@ pub fn capture_backtrace(value: bool) -> bool { }) } +#[inline] pub fn forward_panic(value: bool) -> bool { FORWARD_PANIC.with(|cell| { let prev = *cell.borrow(); @@ -124,14 +137,17 @@ pub fn forward_panic(value: bool) -> bool { }) } +#[inline] pub fn set_hook() { *PANIC_HOOK } +#[inline] pub fn rust_backtrace() -> bool { *RUST_BACKTRACE } +#[inline] pub fn thread_name() -> String { THREAD_NAME.with(|cell| cell.clone()) } diff --git a/lib/bolero-engine/src/test.rs b/lib/bolero-engine/src/test.rs index 4e6bdf9..6794446 100644 --- a/lib/bolero-engine/src/test.rs +++ b/lib/bolero-engine/src/test.rs @@ -37,6 +37,7 @@ where { type Value = SliceDebug>; + #[inline] fn test>>( &mut self, input: &mut T, @@ -48,10 +49,11 @@ where Ok(()) => Ok(true), Err(err) => Err(err), } - })? + }) }) } + #[inline] fn generate_value>(&self, input: &mut T) -> Self::Value { input.with_slice(&mut |slice| SliceDebug(slice.to_vec())) } @@ -73,6 +75,7 @@ where { type Value = SliceDebug>; + #[inline] fn test>>( &mut self, input: &mut T, @@ -84,10 +87,11 @@ where Ok(()) => Ok(true), Err(err) => Err(err), } - })? + }) }) } + #[inline] fn generate_value>(&self, input: &mut T) -> Self::Value { input.with_slice(&mut |slice| SliceDebug(slice.to_vec())) } @@ -109,6 +113,7 @@ where { type Value = SliceDebug>; + #[inline] fn test>>( &mut self, input: &mut T, @@ -121,10 +126,11 @@ where Ok(()) => Ok(true), Err(err) => Err(err), } - })? + }) }) } + #[inline] fn generate_value>(&self, input: &mut T) -> Self::Value { input.with_slice(&mut |slice| SliceDebug(slice.to_vec())) } @@ -186,6 +192,7 @@ where { type Value = G::Output; + #[inline] fn test>>( &mut self, input: &mut T, @@ -202,10 +209,11 @@ where Ok(()) => Ok(true), Err(err) => Err(err), } - })? + }) }) } + #[inline] fn generate_value>(&self, input: &mut T) -> Self::Value { input.with_driver(&mut |driver| { let forward_panic = crate::panic::forward_panic(true); @@ -240,6 +248,7 @@ where { type Value = G::Output; + #[inline] fn test>>( &mut self, input: &mut T, @@ -268,10 +277,11 @@ where Ok(()) => Ok(true), Err(err) => Err(err), } - })? + }) }) } + #[inline] fn generate_value>(&self, input: &mut T) -> Self::Value { input.with_driver(&mut |driver| { let forward_panic = crate::panic::forward_panic(true); diff --git a/lib/bolero-generator/src/driver/macros.rs b/lib/bolero-generator/src/driver/macros.rs index bd825c0..5b7eed9 100644 --- a/lib/bolero-generator/src/driver/macros.rs +++ b/lib/bolero-generator/src/driver/macros.rs @@ -1,6 +1,6 @@ macro_rules! gen_int { ($name:ident, $ty:ident) => { - #[inline] + #[inline(always)] fn $name(&mut self, min: Bound<&$ty>, max: Bound<&$ty>) -> Option<$ty> { Uniform::sample(self, min, max) } @@ -74,12 +74,12 @@ macro_rules! gen_from_bytes { gen_float!(gen_f64, f64); - #[inline] + #[inline(always)] fn gen_char(&mut self, min: Bound<&char>, max: Bound<&char>) -> Option { char::sample(self, min, max) } - #[inline] + #[inline(always)] fn gen_bool(&mut self, probability: Option) -> Option { if let Some(probability) = probability { let value = self.sample_u32()? as f32 / core::u32::MAX as f32; @@ -89,20 +89,13 @@ macro_rules! gen_from_bytes { } } - #[inline] + #[inline(always)] fn gen_variant(&mut self, variants: usize, base_case: usize) -> Option { - match FillBytes::mode(self) { - DriverMode::Direct => { - Uniform::sample(self, Bound::Unbounded, Bound::Excluded(&variants)) - } - DriverMode::Forced => { - if self.depth == self.max_depth { - return Some(base_case); - } - - Uniform::sample(self, Bound::Unbounded, Bound::Excluded(&variants)) - } + if self.depth == self.max_depth { + return Some(base_case); } + + Uniform::sample(self, Bound::Unbounded, Bound::Excluded(&variants)) } }; }