Skip to content
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

Merged

Conversation

bluss
Copy link
Member

@bluss bluss commented Sep 8, 2016

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

@rust-highfive
Copy link
Collaborator

r? @aturon

(rust_highfive has picked a reviewer for you, use r? to override)

@bluss bluss force-pushed the vec-extend-from-slice-aliasing-workaround branch 2 times, most recently from e9fc619 to a8702bf Compare September 8, 2016 22:02
…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).
@bluss bluss force-pushed the vec-extend-from-slice-aliasing-workaround branch from a8702bf to 765700b Compare September 9, 2016 00:39
@bluss
Copy link
Member Author

bluss commented Sep 9, 2016

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).

@bluss bluss changed the title WIP Work around pointer aliasing issue in Vec::extend_from_slice, extend_with_element Work around pointer aliasing issue in Vec::extend_from_slice, extend_with_element Sep 9, 2016
@bluss
Copy link
Member Author

bluss commented Sep 10, 2016

Adding fixes #17844 since Vec::clone uses extend_from_slice

@alexcrichton
Copy link
Member

@bors: r+ 765700b

Nice catch!

@bluss
Copy link
Member Author

bluss commented Sep 11, 2016

Thanks. I'm thrilled to see this fixed.

@bors
Copy link
Contributor

bors commented Sep 12, 2016

⌛ Testing commit 765700b with merge 4d91323...

bors added a commit that referenced this pull request Sep 12, 2016
…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
@bors bors merged commit 765700b into rust-lang:master Sep 12, 2016
@bluss bluss deleted the vec-extend-from-slice-aliasing-workaround branch September 12, 2016 11:01
mbrubeck added a commit to mbrubeck/rust-smallvec that referenced this pull request Jan 4, 2019
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.
bors-servo pushed a commit to servo/rust-smallvec that referenced this pull request Jan 4, 2019
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 -->
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants