Progress
Details
As described in #368, Ref<B, T> currently stores a B with the invariant that the referent has a valid size and alignment for T. This allows us to infallibly produce a &(mut) T at runtime (given an existing Ref as a witness to the size and alignment guarantees). Currently, we use Ptr::try_cast_into_no_leftover to re-compute the &(mut) T and .expect on its result since we know it can't fail:
|
let ptr = Ptr::from_ref(b.into_byte_slice()) |
|
.try_cast_into_no_leftover::<T, BecauseImmutable>(None) |
|
.expect("zerocopy internal error: into_ref should be infallible"); |
This is expensive. In the long run, we should be able to remove most of this computation by storing the &(mut) T itself rather than the B (see #368), although that only works for some B types.
For the time being, and in order to support all B types, we can at least optimize this for the T: Sized case. In particular, since a &(mut) T has no pointer metadata when T: Sized, we can just short-circuit and cast the B pointer directly to a &(mut) T without performing any runtime checks. In other words, this entirely bypasses Ptr::try_cast_into_no_leftover.
We should also add benchmarks so we can measure the performance impact of this change, which I expect will be substantial.
Progress
RefmethodsT: SizedDetails
As described in #368,
Ref<B, T>currently stores aBwith the invariant that the referent has a valid size and alignment forT. This allows us to infallibly produce a&(mut) Tat runtime (given an existingRefas a witness to the size and alignment guarantees). Currently, we usePtr::try_cast_into_no_leftoverto re-compute the&(mut) Tand.expecton its result since we know it can't fail:zerocopy/src/ref.rs
Lines 624 to 626 in e8eb595
This is expensive. In the long run, we should be able to remove most of this computation by storing the
&(mut) Titself rather than theB(see #368), although that only works for someBtypes.For the time being, and in order to support all
Btypes, we can at least optimize this for theT: Sizedcase. In particular, since a&(mut) Thas no pointer metadata whenT: Sized, we can just short-circuit and cast theBpointer directly to a&(mut) Twithout performing any runtime checks. In other words, this entirely bypassesPtr::try_cast_into_no_leftover.We should also add benchmarks so we can measure the performance impact of this change, which I expect will be substantial.