Skip to content

Commit

Permalink
add more inlines for better optimization (#223)
Browse files Browse the repository at this point in the history
  • Loading branch information
camshaft authored Jun 4, 2024
1 parent 966e81a commit 8b7539d
Show file tree
Hide file tree
Showing 5 changed files with 103 additions and 43 deletions.
36 changes: 34 additions & 2 deletions examples/boolean-tree/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use bolero_generator::TypeGenerator;
use core::fmt;

thread_local! {
static SHOULD_PANIC: bool = {
Expand All @@ -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<Expr>, Box<Expr>),
Or(Box<Expr>, Box<Expr>),
Xor(Box<Expr>, Box<Expr>),
Nand(Box<Expr>, Box<Expr>),
Not(Box<Expr>),
}

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(),
}
Expand Down
13 changes: 11 additions & 2 deletions lib/bolero-engine/src/noop/panic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,30 +30,39 @@ impl PanicError {
}
}

pub fn catch<F: RefUnwindSafe + FnOnce() -> Output, Output>(fun: F) -> Result<Output, PanicError> {
Ok(fun())
#[inline(always)]
pub fn catch<F: RefUnwindSafe + FnOnce() -> Result<Output, PanicError>, Output>(
fun: F,
) -> Result<Output, PanicError> {
fun()
}

#[inline(always)]
pub fn take_panic() -> Option<PanicError> {
None
}

#[inline(always)]
pub fn capture_backtrace(_value: bool) -> bool {
false
}

#[inline(always)]
pub fn forward_panic(_value: bool) -> bool {
false
}

#[inline(always)]
pub fn set_hook() {
// no-op
}

#[inline(always)]
pub fn rust_backtrace() -> bool {
false
}

#[inline(always)]
pub fn thread_name() -> String {
String::from("main")
}
Expand Down
54 changes: 35 additions & 19 deletions lib/bolero-engine/src/panic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,32 +82,44 @@ impl PanicError {
}
}

pub fn catch<F: RefUnwindSafe + FnOnce() -> Output, Output>(fun: F) -> Result<Output, PanicError> {
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<F: RefUnwindSafe + FnOnce() -> Result<Output, PanicError>, Output>(
fun: F,
) -> Result<Output, PanicError> {
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<dyn Display>, "{}");
try_downcast!(Box<dyn Debug>, "{:?}");
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<dyn Display>, "{}");
try_downcast!(Box<dyn Debug>, "{:?}");
PanicError::new("thread panicked with an unknown error".to_string())
})
}
}

#[inline]
pub fn take_panic() -> Option<PanicError> {
ERROR.with(|error| error.borrow_mut().take())
}

#[inline]
pub fn capture_backtrace(value: bool) -> bool {
CAPTURE_BACKTRACE.with(|cell| {
let prev = *cell.borrow();
Expand All @@ -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();
Expand All @@ -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())
}
Expand Down
20 changes: 15 additions & 5 deletions lib/bolero-engine/src/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ where
{
type Value = SliceDebug<Vec<u8>>;

#[inline]
fn test<T: Input<Result<bool, PanicError>>>(
&mut self,
input: &mut T,
Expand All @@ -48,10 +49,11 @@ where
Ok(()) => Ok(true),
Err(err) => Err(err),
}
})?
})
})
}

#[inline]
fn generate_value<T: Input<Self::Value>>(&self, input: &mut T) -> Self::Value {
input.with_slice(&mut |slice| SliceDebug(slice.to_vec()))
}
Expand All @@ -73,6 +75,7 @@ where
{
type Value = SliceDebug<Vec<u8>>;

#[inline]
fn test<T: Input<Result<bool, PanicError>>>(
&mut self,
input: &mut T,
Expand All @@ -84,10 +87,11 @@ where
Ok(()) => Ok(true),
Err(err) => Err(err),
}
})?
})
})
}

#[inline]
fn generate_value<T: Input<Self::Value>>(&self, input: &mut T) -> Self::Value {
input.with_slice(&mut |slice| SliceDebug(slice.to_vec()))
}
Expand All @@ -109,6 +113,7 @@ where
{
type Value = SliceDebug<Vec<u8>>;

#[inline]
fn test<T: Input<Result<bool, PanicError>>>(
&mut self,
input: &mut T,
Expand All @@ -121,10 +126,11 @@ where
Ok(()) => Ok(true),
Err(err) => Err(err),
}
})?
})
})
}

#[inline]
fn generate_value<T: Input<Self::Value>>(&self, input: &mut T) -> Self::Value {
input.with_slice(&mut |slice| SliceDebug(slice.to_vec()))
}
Expand Down Expand Up @@ -186,6 +192,7 @@ where
{
type Value = G::Output;

#[inline]
fn test<T: Input<Result<bool, PanicError>>>(
&mut self,
input: &mut T,
Expand All @@ -202,10 +209,11 @@ where
Ok(()) => Ok(true),
Err(err) => Err(err),
}
})?
})
})
}

#[inline]
fn generate_value<T: Input<Self::Value>>(&self, input: &mut T) -> Self::Value {
input.with_driver(&mut |driver| {
let forward_panic = crate::panic::forward_panic(true);
Expand Down Expand Up @@ -240,6 +248,7 @@ where
{
type Value = G::Output;

#[inline]
fn test<T: Input<Result<bool, PanicError>>>(
&mut self,
input: &mut T,
Expand Down Expand Up @@ -268,10 +277,11 @@ where
Ok(()) => Ok(true),
Err(err) => Err(err),
}
})?
})
})
}

#[inline]
fn generate_value<T: Input<Self::Value>>(&self, input: &mut T) -> Self::Value {
input.with_driver(&mut |driver| {
let forward_panic = crate::panic::forward_panic(true);
Expand Down
23 changes: 8 additions & 15 deletions lib/bolero-generator/src/driver/macros.rs
Original file line number Diff line number Diff line change
@@ -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)
}
Expand Down Expand Up @@ -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> {
char::sample(self, min, max)
}

#[inline]
#[inline(always)]
fn gen_bool(&mut self, probability: Option<f32>) -> Option<bool> {
if let Some(probability) = probability {
let value = self.sample_u32()? as f32 / core::u32::MAX as f32;
Expand All @@ -89,20 +89,13 @@ macro_rules! gen_from_bytes {
}
}

#[inline]
#[inline(always)]
fn gen_variant(&mut self, variants: usize, base_case: usize) -> Option<usize> {
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))
}
};
}

0 comments on commit 8b7539d

Please sign in to comment.