Skip to content

Commit 62569a4

Browse files
committed
Backport new microoptimizations
1 parent a77af1f commit 62569a4

2 files changed

Lines changed: 27 additions & 17 deletions

File tree

compiler/rustc_thread_pool/src/registry.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ where
126126
}
127127

128128
pub struct Registry {
129-
thread_infos: Vec<ThreadInfo>,
129+
thread_infos: Box<[ThreadInfo]>,
130130
sleep: Sleep,
131131
injected_jobs: Injector<JobRef>,
132132
broadcasts: Mutex<Vec<Worker<JobRef>>>,
@@ -989,7 +989,7 @@ impl WorkerThread {
989989
debug_assert!(self.local_deque_is_empty());
990990

991991
// otherwise, try to steal
992-
let thread_infos = &self.registry.thread_infos.as_slice();
992+
let thread_infos = &*self.registry.thread_infos;
993993
let num_threads = thread_infos.len();
994994
if num_threads <= 1 {
995995
return None;

compiler/rustc_thread_pool/src/worker_local.rs

Lines changed: 25 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ struct CacheAligned<T>(T);
1212
/// You can only access the worker local value through the Deref impl
1313
/// on the thread pool it was constructed on. It will panic otherwise
1414
pub struct WorkerLocal<T> {
15-
locals: Vec<CacheAligned<T>>,
15+
locals: Box<[CacheAligned<T>]>,
1616
registry: Arc<Registry>,
1717
}
1818

@@ -35,21 +35,15 @@ impl<T> WorkerLocal<T> {
3535

3636
/// Returns the worker-local value for each thread
3737
#[inline]
38-
pub fn into_inner(self) -> Vec<T> {
39-
self.locals.into_iter().map(|c| c.0).collect()
38+
pub fn into_inner(self) -> impl Iterator<Item = T> {
39+
self.locals.into_vec().into_iter().map(|local| local.0)
4040
}
41+
}
4142

42-
fn current(&self) -> &T {
43-
unsafe {
44-
let worker_thread = WorkerThread::current();
45-
if worker_thread.is_null()
46-
|| !std::ptr::eq(&*(*worker_thread).registry, &*self.registry)
47-
{
48-
panic!("WorkerLocal can only be used on the thread pool it was created on")
49-
}
50-
&self.locals[(*worker_thread).index].0
51-
}
52-
}
43+
#[inline(never)]
44+
#[cold]
45+
fn panic_different_registry() -> ! {
46+
panic!("WorkerLocal can only be used on the thread pool it was created on")
5347
}
5448

5549
impl<T> WorkerLocal<Vec<T>> {
@@ -70,7 +64,23 @@ impl<T> Deref for WorkerLocal<T> {
7064

7165
#[inline(always)]
7266
fn deref(&self) -> &T {
73-
self.current()
67+
unsafe {
68+
let worker_thread = WorkerThread::current();
69+
if worker_thread.is_null()
70+
|| !std::ptr::eq(&*(*worker_thread).registry, &*self.registry)
71+
{
72+
panic_different_registry()
73+
}
74+
// SAFETY: `verify` will only return values less than
75+
// `self.registry.num_threads` which is the size of the `self.locals` array.
76+
&self.locals.get_unchecked((*worker_thread).index).0
77+
}
78+
}
79+
}
80+
81+
impl<T: Default> Default for WorkerLocal<T> {
82+
fn default() -> Self {
83+
WorkerLocal::new(|_| Default::default())
7484
}
7585
}
7686

0 commit comments

Comments
 (0)