-
Couldn't load subscription status.
- Fork 13.9k
Work around pointer aliasing issue in Vec::extend_from_slice, extend_with_element #36355
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Work around pointer aliasing issue in Vec::extend_from_slice, extend_with_element #36355
Conversation
|
r? @aturon (rust_highfive has picked a reviewer for you, use r? to override) |
e9fc619 to
a8702bf
Compare
…with_element Due to missing noalias annotations for &mut T in general (issue rust-lang#31681), in larger programs extend_from_slice and extend_with_element may both compile very poorly. What is observed is that the .set_len() calls are not lifted out of the loop, even for `Vec<u8>`. Use a local length variable for the Vec length instead, and use a scope guard to write this value back to self.len when the scope ends or on panic. Then the alias analysis is easy. This affects extend_from_slice, extend_with_element, the vec![x; n] macro, Write impls for Vec<u8>, BufWriter, etc (but may / may not have triggered since inlining can be enough for the compiler to get it right).
a8702bf to
765700b
Compare
|
Verified that it fixes the two issues. (More or less by finding programs that exhibit the regression behavior, and then that the new version fixes it). |
|
Adding fixes #17844 since Vec::clone uses extend_from_slice |
|
Thanks. I'm thrilled to see this fixed. |
…d, r=alexcrichton Work around pointer aliasing issue in Vec::extend_from_slice, extend_with_element Due to missing noalias annotations for &mut T in general (issue #31681), in larger programs extend_from_slice and extend_with_element may both compile very poorly. What is observed is that the .set_len() calls are not lifted out of the loop, even for `Vec<u8>`. Use a local length variable for the Vec length instead, and use a scope guard to write this value back to self.len when the scope ends or on panic. Then the alias analysis is easy. This affects extend_from_slice, extend_with_element, the vec![x; n] macro, Write impls for Vec<u8>, BufWriter, etc (but may / may not have triggered since inlining can be enough for the compiler to get it right). Fixes #32155 Fixes #33518 Closes #17844
This ensures that the length of the SmallVec is updated even if the iterator panics in `next`. This uses `SetLenOnDrop` rather than setting the length inside the loop, because otherwise this suffers from the same optimization issue as rust-lang/rust#36355. Fixes servo#136.
Don't leak on panic in extend This ensures that the length of the SmallVec is updated even if the iterator panics in `next`. This uses `SetLenOnDrop` rather than setting the length inside the loop, because otherwise this suffers from the same optimization issue as rust-lang/rust#36355. Fixes #136. <!-- Reviewable:start --> --- This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/rust-smallvec/137) <!-- Reviewable:end -->
Due to missing noalias annotations for &mut T in general (issue #31681),
in larger programs extend_from_slice and extend_with_element may both
compile very poorly. What is observed is that the .set_len() calls are
not lifted out of the loop, even for
Vec<u8>.Use a local length variable for the Vec length instead, and use a scope
guard to write this value back to self.len when the scope ends or on
panic. Then the alias analysis is easy.
This affects extend_from_slice, extend_with_element, the vec![x; n]
macro, Write impls for Vec, BufWriter, etc (but may / may not
have triggered since inlining can be enough for the compiler to get it right).
Fixes #32155
Fixes #33518
Closes #17844