Skip to content

Commit

Permalink
To avoid monomorphizing psm::on_stack::with_on_stack 1500 times in …
Browse files Browse the repository at this point in the history
…rustc, convert the callback passed to grow `_grow` to `dyn FnMut()`.

This should improve rustc's compile time a bit, and surprisingly also improves runtime in some cases.

https://perf.rust-lang.org/compare.html?start=7402a394471a6738a40fea7d4f1891666e5a80c5&end=f242334c1e2e719cf1cba923923ad8ec62affb71
  • Loading branch information
Julian Wollersberger committed Sep 14, 2020
1 parent 7a1d421 commit 71993c7
Showing 1 changed file with 19 additions and 3 deletions.
22 changes: 19 additions & 3 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,11 +59,27 @@ pub fn maybe_grow<R, F: FnOnce() -> R>(red_zone: usize, stack_size: usize, callb
/// The closure will still be on the same thread as the caller of `grow`.
/// This will allocate a new stack with at least `stack_size` bytes.
pub fn grow<R, F: FnOnce() -> R>(stack_size: usize, callback: F) -> R {
// Measuring with cargo-llvm-lines revealed that `psm::on_stack::with_on_stack`
// was monomorphized 1552 times in rustc and was responsible for 1.5% of
// rustc's total llvm IR lines. That takes time for LLVM to process.
// Converting the generic callback to a dynamic one removes all that duplication.
let mut opt_callback = Some(callback);
let mut ret = None;
let ret_ref = &mut ret;
_grow(stack_size, move || {
*ret_ref = Some(callback());
});

// This wrapper around `callback` achieves two things:
// * It converts the `impl FnOnce` to a `dyn FnMut`.
// `dyn` because we want it to not be generic, and
// `FnMut` because we can't pass a `dyn FnOnce` around without boxing it.
// * It eliminates the generic return value, by writing it to the stack of this function.
// Otherwise the closure would have to return an unsized value, which isn't possible.
let dyn_callback: &mut dyn FnMut() = &mut || {
let taken_callback = opt_callback.take().unwrap();
*ret_ref = Some(taken_callback());
};

// _grow is only monomorphized once with a `dyn` argument.
_grow(stack_size, dyn_callback);
ret.unwrap()
}

Expand Down

0 comments on commit 71993c7

Please sign in to comment.