From db535bad791fcab1e802728fe7e0ca95804192af Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Mon, 26 Feb 2024 20:55:38 -0800 Subject: Generate original vtable and clone's vtable in the same CGU --- library/alloc/src/task.rs | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'library/alloc/src') diff --git a/library/alloc/src/task.rs b/library/alloc/src/task.rs index b214f4946b1..b40768a52b6 100644 --- a/library/alloc/src/task.rs +++ b/library/alloc/src/task.rs @@ -136,6 +136,15 @@ impl From> for RawWaker { #[inline(always)] fn raw_waker(waker: Arc) -> 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(waker: *const ()) -> RawWaker { unsafe { Arc::increment_strong_count(waker as *const W) }; RawWaker::new( @@ -304,6 +313,10 @@ impl From> for RawWaker { #[inline(always)] fn local_raw_waker(waker: Rc) -> 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(waker: *const ()) -> RawWaker { unsafe { Rc::increment_strong_count(waker as *const W) }; RawWaker::new( -- cgit 1.4.1-3-g733a5