Skip to content

Commit

Permalink
Generate original vtable and clone's vtable in the same CGU
Browse files Browse the repository at this point in the history
  • Loading branch information
dtolnay committed Feb 27, 2024
1 parent 793b45f commit db535ba
Showing 1 changed file with 13 additions and 0 deletions.
13 changes: 13 additions & 0 deletions library/alloc/src/task.rs
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,15 @@ impl<W: Wake + Send + Sync + 'static> From<Arc<W>> for RawWaker {
#[inline(always)]
fn raw_waker<W: Wake + Send + Sync + 'static>(waker: Arc<W>) -> RawWaker {
// Increment the reference count of the arc to clone it.
//
// The #[inline(always)] is to ensure that raw_waker and clone_waker are
// always generated in the same code generation unit as one another, and
// therefore that the structurally identical const-promoted RawWakerVTable
// within both functions is deduplicated at LLVM IR code generation time.
// This allows optimizing Waker::will_wake to a single pointer comparison of
// the vtable pointers, rather than comparing all four function pointers
// within the vtables.
#[inline(always)]
unsafe fn clone_waker<W: Wake + Send + Sync + 'static>(waker: *const ()) -> RawWaker {
unsafe { Arc::increment_strong_count(waker as *const W) };
RawWaker::new(
Expand Down Expand Up @@ -304,6 +313,10 @@ impl<W: LocalWake + 'static> From<Rc<W>> for RawWaker {
#[inline(always)]
fn local_raw_waker<W: LocalWake + 'static>(waker: Rc<W>) -> RawWaker {
// Increment the reference count of the Rc to clone it.
//
// Refer to the comment on raw_waker's clone_waker regarding why this is
// always inline.
#[inline(always)]
unsafe fn clone_waker<W: LocalWake + 'static>(waker: *const ()) -> RawWaker {
unsafe { Rc::increment_strong_count(waker as *const W) };
RawWaker::new(
Expand Down

0 comments on commit db535ba

Please sign in to comment.