Skip to content

Commit

Permalink
Merge #673
Browse files Browse the repository at this point in the history
673: Reduce the genericity of many closures r=nikomatsakis a=cuviper

The `take_while` closure only needs to be generic in `T`, along with a
captured `&AtomicBool`. When we write the closure directly, it carries
all the type baggage of `WhileSomeFolder<'f, C>::consumer_iter<I>`,
where the monomorphized type may explode. Instead, we can move this
closure to a standalone function for reduced genericity.

Co-authored-by: Josh Stone <cuviper@gmail.com>
  • Loading branch information
bors[bot] and cuviper committed Aug 15, 2019
2 parents 8d2e048 + dbc114f commit 83b67e2
Show file tree
Hide file tree
Showing 28 changed files with 442 additions and 241 deletions.
6 changes: 5 additions & 1 deletion rayon-core/src/job.rs
Expand Up @@ -109,10 +109,14 @@ where
R: Send,
{
unsafe fn execute(this: *const Self) {
fn call<R>(func: impl FnOnce(bool) -> R) -> impl FnOnce() -> R {
move || func(true)
}

let this = &*this;
let abort = unwind::AbortIfPanic;
let func = (*this.func.get()).take().unwrap();
(*this.result.get()) = match unwind::halt_unwinding(|| func(true)) {
(*this.result.get()) = match unwind::halt_unwinding(call(func)) {
Ok(x) => JobResult::Ok(x),
Err(x) => JobResult::Panic(x),
};
Expand Down
23 changes: 18 additions & 5 deletions rayon-core/src/join/mod.rs
Expand Up @@ -98,7 +98,12 @@ where
RA: Send,
RB: Send,
{
join_context(|_| oper_a(), |_| oper_b())
#[inline]
fn call<R>(f: impl FnOnce() -> R) -> impl FnOnce(FnContext) -> R {
move |_| f()
}

join_context(call(oper_a), call(oper_b))
}

/// Identical to `join`, except that the closures have a parameter
Expand All @@ -115,22 +120,30 @@ where
RA: Send,
RB: Send,
{
#[inline]
fn call_a<R>(f: impl FnOnce(FnContext) -> R, injected: bool) -> impl FnOnce() -> R {
move || f(FnContext::new(injected))
}

#[inline]
fn call_b<R>(f: impl FnOnce(FnContext) -> R) -> impl FnOnce(bool) -> R {
move |migrated| f(FnContext::new(migrated))
}

registry::in_worker(|worker_thread, injected| unsafe {
log!(Join {
worker: worker_thread.index()
});

let latch = SpinLatch::new();

// Create virtual wrapper for task b; this all has to be
// done here so that the stack frame can keep it all live
// long enough.
let job_b = StackJob::new(|migrated| oper_b(FnContext::new(migrated)), latch);
let job_b = StackJob::new(call_b(oper_b), SpinLatch::new());
let job_b_ref = job_b.as_job_ref();
worker_thread.push(job_b_ref);

// Execute task a; hopefully b gets stolen in the meantime.
let status_a = unwind::halt_unwinding(move || oper_a(FnContext::new(injected)));
let status_a = unwind::halt_unwinding(call_a(oper_a, injected));
let result_a = match status_a {
Ok(v) => v,
Err(err) => join_recover_from_panic(worker_thread, &job_b.latch, err),
Expand Down
23 changes: 4 additions & 19 deletions src/iter/collect/mod.rs
@@ -1,5 +1,4 @@
use super::{IndexedParallelIterator, IntoParallelIterator, ParallelExtend, ParallelIterator};
use std::collections::LinkedList;
use std::slice;
use std::sync::atomic::{AtomicUsize, Ordering};

Expand Down Expand Up @@ -138,24 +137,10 @@ where
}
None => {
// This works like `extend`, but `Vec::append` is more efficient.
let list: LinkedList<_> = par_iter
.fold(Vec::new, |mut vec, elem| {
vec.push(elem);
vec
})
.map(|vec| {
let mut list = LinkedList::new();
list.push_back(vec);
list
})
.reduce(LinkedList::new, |mut list1, mut list2| {
list1.append(&mut list2);
list1
});

self.reserve(list.iter().map(Vec::len).sum());
for mut vec in list {
self.append(&mut vec);
let list = super::extend::collect(par_iter);
self.reserve(super::extend::len(&list));
for ref mut vec in list {
self.append(vec);
}
}
}
Expand Down
6 changes: 3 additions & 3 deletions src/iter/copied.rs
Expand Up @@ -102,11 +102,11 @@ where
T: 'a + Copy,
{
type Item = T;
type IntoIter = iter::Map<P::IntoIter, fn(&T) -> T>;
type IntoIter = iter::Cloned<P::IntoIter>;

fn into_iter(self) -> Self::IntoIter {
// FIXME: use `Iterator::copied()` when Rust 1.36 is our minimum.
self.base.into_iter().map(|&x| x)
self.base.into_iter().cloned()
}

fn min_len(&self) -> usize {
Expand Down Expand Up @@ -211,7 +211,7 @@ where
I: IntoIterator<Item = &'a T>,
{
// FIXME: use `Iterator::copied()` when Rust 1.36 is our minimum.
self.base = self.base.consume_iter(iter.into_iter().map(|&x| x));
self.base = self.base.consume_iter(iter.into_iter().cloned());
self
}

Expand Down

0 comments on commit 83b67e2

Please sign in to comment.