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

Reoptimize VecDeque::append #53564

Merged
merged 5 commits into from
Aug 29, 2018
Merged

Reoptimize VecDeque::append #53564

merged 5 commits into from
Aug 29, 2018

Conversation

MaloJaffre
Copy link
Contributor

@MaloJaffre MaloJaffre commented Aug 21, 2018

Unfortunately, I don't know if these changes fix the unsoundness mentioned in #53529, so it is stil a WIP.
This is also completely untested.
The VecDeque code contains other unsound code: one example : reading unitialized memory (detected by MIRI), so I think this code will need a bigger refactor to make it clearer and safer.

Note: this is based on #53571.
r? @SimonSapin
Cc: #53529 #52553 @yorickpeterse @jonas-schievink @Pazzaz @shepmaster.

@rust-highfive rust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Aug 21, 2018
@jonas-schievink
Copy link
Contributor

The VecDeque code contains other unsound code: one example : reading unitialized memory (detected by MIRI), so I think this code will need a bigger refactor to make it clearer and safer.

Oh wow, that's really bad!

FYI: buffer_as_slice and buffer_as_mut_slice also create slices of uninitialized values.

@MaloJaffre
Copy link
Contributor Author

In fact, after rereading the Rustonomicon, I found that creating slices of unitialized values if perfectly fine, it's just forbidden to read or write to it without using ptr::read, ptr::write, ptr::copy etc.
Maybe the code is triggering UB another way?

@rust-highfive
Copy link
Collaborator

The job x86_64-gnu-llvm-5.0 of your PR failed on Travis (raw log). Through arcane magic we have determined that the following fragments from the build log may contain information about the problem.

Click to expand the log.
[00:19:43] note: we would appreciate a bug report: https://github.com/rust-lang/rust/blob/master/CONTRIBUTING.md#bug-reports
[00:19:43] 
[00:19:43] note: rustc 1.30.0-dev running on x86_64-unknown-linux-gnu
[00:19:43] 
[00:19:43] note: compiler flags: -Z force-unstable-if-unmarked -C opt-level=2 -C prefer-dynamic -C debug-assertions=y -C link-args=-Wl,-rpath,$ORIGIN/../lib --crate-type lib
[00:19:43] note: some of the compiler flags provided by cargo are hidden
[00:19:43] 
[00:19:43] error: Could not compile `core`.
[00:19:43] 
---
151200 ./src/tools/clang
149112 ./src/llvm-emscripten/test
148688 ./obj/build/bootstrap/debug/incremental
134256 ./obj/build/bootstrap/debug/incremental/bootstrap-1v3ifugz4t07z
134252 ./obj/build/bootstrap/debug/incremental/bootstrap-1v3ifugz4t07z/s-f42a075x8w-h9mzy1-1iplbejydu42a
103868 ./src/tools/lldb
98956 ./obj/build/x86_64-unknown-linux-gnu/stage0/lib/rustlib/x86_64-unknown-linux-gnu/codegen-backends
93756 ./src/tools/clang/test
90576 ./obj/build/x86_64-unknown-linux-gnu/stage1
---
travis_time:end:0e9c4e8e:start=1534863313532289125,finish=1534863313540257491,duration=7968366
travis_fold:end:after_failure.3
travis_fold:start:after_failure.4
travis_time:start:32bb0106
$ ln -s . checkout && for CORE in obj/cores/core.*; do EXE=$(echo $CORE | sed 's|obj/cores/core\.[0-9]*\.!checkout!\(.*\)|\1|;y|!|/|'); if [ -f "$EXE" ]; then printf travis_fold":start:crashlog\n\033[31;1m%s\033[0m\n" "$CORE"; gdb -q -c "$CORE" "$EXE" -iex 'set auto-load off' -iex 'dir src/' -iex 'set sysroot .' -ex bt -ex q; echo travis_fold":"end:crashlog; fi; done || true
travis_fold:end:after_failure.4
travis_fold:start:after_failure.5
travis_time:start:002678e8
travis_time:start:002678e8
$ cat ./obj/build/x86_64-unknown-linux-gnu/native/asan/build/lib/asan/clang_rt.asan-dynamic-i386.vers || true
cat: ./obj/build/x86_64-unknown-linux-gnu/native/asan/build/lib/asan/clang_rt.asan-dynamic-i38

I'm a bot! I can only do what humans tell me to, so if this was not helpful or you have suggestions for improvements, please ping or otherwise contact @TimNN. (Feature Requests)

@jonas-schievink
Copy link
Contributor

@MaloJaffre Interesting, that appears to be true. I thought that references and slices being marked dereferenceable in LLVM would be a problem, but that only guarantees that reads will not trap which is the case even if the memory is uninitialized.

@shepmaster
Copy link
Member

/cc @RalfJung

@shepmaster
Copy link
Member

Is the simplest thing to just revert the PR which introduced this until such time as it can be fixed?

@yorickpeterse
Copy link

yorickpeterse commented Aug 21, 2018

@shepmaster Considering that nightly is pretty widely used, that might not be a bad idea.

I made some more attempts at trying to reproduce the original problem in a standalone manner, but so far I have not managed to succeed in doing this.

@Mark-Simulacrum
Copy link
Member

That PR should be reverted as soon as we can; if someone can prepare a PR that would be great.

@RalfJung
Copy link
Member

miri is still WIP so if you'd prefer I can double-check to see if this looks like a false positive.

But the fact that real crashes occur means, I guess, that it might be legit...

@RalfJung
Copy link
Member

Ah, I think what is going on is that the Debug implementation of Iter is unsound. It tries to print uninitialized data.

Concretely, it first turns the entire buffer into a slice (buffer_as_slice), which is likely okay though we have not rules on "references to bad data" yet -- but then it prints that entire slice, and not just the part of it which is initialized. And that's certainly not okay, now we are touching uninitialized integers.

@RalfJung
Copy link
Member

I opened #53566 for the Debug problem, which is separate from #52553 I think.

Maybe I should add some VecDeque tests to miri's test suite to cover such things? :D

@MaloJaffre
Copy link
Contributor Author

I will open a reverting PR soon, along with a fix for #53566.

@SimonSapin SimonSapin removed their assignment Aug 21, 2018
@SimonSapin
Copy link
Contributor

I’m sorry, I feel I won’t be able to complete this review in reasonable time frame. Could someone else (perhaps from @rust-lang/libs) take over?

@SimonSapin
Copy link
Contributor

If #52553 made things worse perhaps we could revert it in the meantime, even if that’s not a complete fix.

@RalfJung
Copy link
Member

@SimonSapin see #53571

@shepmaster
Copy link
Member

To prevent this falling through the cracks, randomly reassigning to...

r? @alexcrichton

@bors
Copy link
Contributor

bors commented Aug 21, 2018

☔ The latest upstream changes (presumably #53530) made this pull request unmergeable. Please resolve the merge conflicts.

@Pazzaz
Copy link
Contributor

Pazzaz commented Aug 21, 2018

I think reverting my PR for now is a good idea but I'm not sure that this PR is needed to fix the segfault. See my comment on the issue for what I think is the reason for the segfault and what would be a much simpler fix.

@rust-highfive
Copy link
Collaborator

The job x86_64-gnu-llvm-5.0 of your PR failed on Travis (raw log). Through arcane magic we have determined that the following fragments from the build log may contain information about the problem.

Click to expand the log.
[00:20:03] note: we would appreciate a bug report: https://github.com/rust-lang/rust/blob/master/CONTRIBUTING.md#bug-reports
[00:20:03] 
[00:20:03] note: rustc 1.30.0-dev running on x86_64-unknown-linux-gnu
[00:20:03] 
[00:20:03] note: compiler flags: -Z force-unstable-if-unmarked -C opt-level=2 -C prefer-dynamic -C debug-assertions=y -C link-args=-Wl,-rpath,$ORIGIN/../lib --crate-type lib
[00:20:03] note: some of the compiler flags provided by cargo are hidden
[00:20:03] 
[00:20:03] error: Could not compile `core`.
[00:20:03] 
[00:20:03] 
[00:20:03] Caused by:
[00:20:03]   process didn't exit successfully: `/checkout/obj/build/bootstrap/debug/rustc --crate-name core libcore/lib.rs --color always --error-format json --crate-type lib --emit=dep-info,link -C opt-level=2 -C metadata=aae624166adf9237 -C extra-filename=-aae624166adf9237 --out-dir /checkout/obj/build/x86_64-unknown-linux-gnu/stage1-std/x86_64-unknown-linux-gnu/release/deps --target x86_64-unknown-linux-gnu -L dependency=/checkout/obj/build/x86_64-unknown-linux-gnu/stage1-std/x86_64-unknown-linux-gnu/release/deps -L dependency=/checkout/obj/build/x86_64-unknown-linux-gnu/stage1-std/release/deps` (exit code: 101)
[00:20:03] warning: build failed, waiting for other jobs to finish...
[00:20:07] error: build failed
[00:20:07] command did not execute successfully: "/checkout/obj/build/x86_64-unknown-linux-gnu/stage0/bin/cargo" "build" "--target" "x86_64-unknown-linux-gnu" "-j" "4" "--release" "--locked" "--color" "always" "--features" "panic-unwind jemalloc backtrace" "--manifest-path" "/checkout/src/libstd/Cargo.toml" "--message-format" "json"
[00:20:07] expected success, got: exit code: 101
[00:20:07] thread 'main' panicked at 'cargo must succeed', bootstrap/compile.rs:1119:9
[00:20:07] travis_fold:end:stage1-std

[00:20:07] travis_time:end:stage1-std:start=1534924113101168159,finish=1534924118630042329,duration=5528874170


[00:20:07] failed to run: /checkout/obj/build/bootstrap/debug/bootstrap build
[00:20:07] Build completed unsuccessfully in 0:15:37
[00:20:07] make: *** [all] Error 1
[00:20:07] Makefile:28: recipe for target 'all' failed

The command "stamp sh -x -c "$RUN_SCRIPT"" exited with 2.
travis_time:start:1e46c0e8
$ date && (curl -fs --head https://google.com | grep ^Date: | sed 's/Date: //g' || true)

I'm a bot! I can only do what humans tell me to, so if this was not helpful or you have suggestions for improvements, please ping or otherwise contact @TimNN. (Feature Requests)

MaloJaffre added a commit to MaloJaffre/rust that referenced this pull request Aug 22, 2018
…onSapin"

This partially reverts commit d5b6b95,
reversing changes made to 6b1ff19.

Fixes rust-lang#53529.
Cc: rust-lang#53564.
Copy link
Contributor

@gnzlbg gnzlbg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM.

@alexcrichton
Copy link
Member

@bors: r=gnzlbg

@bors
Copy link
Contributor

bors commented Aug 29, 2018

📌 Commit 21d2a6c has been approved by gnzlbg

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Aug 29, 2018
@bors
Copy link
Contributor

bors commented Aug 29, 2018

⌛ Testing commit 21d2a6c with merge 02cb8f2...

bors added a commit that referenced this pull request Aug 29, 2018
Reoptimize VecDeque::append

~Unfortunately, I don't know if these changes fix the unsoundness mentioned in #53529, so it is stil a WIP.
This is also completely untested.
The VecDeque code contains other unsound code: one example : [reading unitialized memory](https://play.rust-lang.org/?gist=6ff47551769af61fd8adc45c44010887&version=nightly&mode=release&edition=2015) (detected by MIRI), so I think this code will need a bigger refactor to make it clearer and safer.~

Note: this is based on #53571.
r? @SimonSapin
Cc: #53529 #52553 @yorickpeterse @jonas-schievink @Pazzaz @shepmaster.
@bors
Copy link
Contributor

bors commented Aug 29, 2018

☀️ Test successful - status-appveyor, status-travis
Approved by: gnzlbg
Pushing 02cb8f2 to master...

@bors bors merged commit 21d2a6c into rust-lang:master Aug 29, 2018
@MaloJaffre MaloJaffre deleted the vecdeque branch August 30, 2018 07:33
@RalfJung
Copy link
Member

The good news is that miri has nothing to complain about when running the same test case with the new append :)

@jens1o
Copy link
Contributor

jens1o commented Sep 6, 2018

What is the impact of this change?

@ljedrz
Copy link
Contributor

ljedrz commented Sep 6, 2018

@jens1o it is a fix to an earlier attempt to speed up DecVeque::append which had caused some unsoundness.

@alexcrichton
Copy link
Member

@pnkfelix has done some awesome bug hunting to pinpoint a 1.30.0 regression to this PR. I've posted a revert while it's investigated, but we can of course avoid reverting if the bug is found sooner!

pietroalbini added a commit to pietroalbini/rust that referenced this pull request Oct 5, 2018
…ckler

Fix a regression in 1.30 by reverting rust-lang#53564

Investigation on rust-lang#54477 revealed rust-lang#53564 as the culprit in the regression for that crate. I've reproduced the regression with the [detailed test cases provided](rust-lang#54477 (comment)). While we figure out how to fix the regression this commit reverts the current culprit.
bors added a commit that referenced this pull request Oct 6, 2018
Rollup of 11 pull requests

Successful merges:

 - #54078 (Expand the documentation for the `std::sync` module)
 - #54717 (Cleanup rustc/ty part 1)
 - #54781 (Add examples to `TyKind::FnDef` and `TyKind::FnPtr` docs)
 - #54787 (Only warn about unused `mut` in user-written code)
 - #54804 (add suggestion for inverted function parameters)
 - #54812 (Regression test for #32382.)
 - #54833 (make `Parser::parse_foreign_item()` return a foreign item or error)
 - #54834 (rustdoc: overflow:auto doesn't work nicely on small screens)
 - #54838 (Fix typo in src/libsyntax/parse/parser.rs)
 - #54851 (Fix a regression in 1.30 by reverting #53564)
 - #54853 (Remove unneccessary error from test, revealing NLL error.)

Failed merges:

r? @ghost

// This is only safe because copy_slice never panics when capacity is sufficient.
self.copy_slice(src_low);
self.copy_slice(src_high);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are these two lines in the wrong order? src_high should be appended before src_low.

bors added a commit that referenced this pull request Oct 8, 2018
[beta] Rollup backports

Merged and approved:

* #54851: Fix a regression in 1.30 by reverting #53564
* #54865: Backport 1.29.2 release notes to master
* #54810: Fix dead code lint for functions using impl Trait

r? @ghost
bors added a commit that referenced this pull request Oct 9, 2018
[beta] Rollup backports

Merged and approved:

* #54851: Fix a regression in 1.30 by reverting #53564
* #54865: Backport 1.29.2 release notes to master
* #54810: Fix dead code lint for functions using impl Trait

r? @ghost
pietroalbini added a commit to pietroalbini/rust that referenced this pull request Nov 1, 2018
…ts, r=nikomatsakis

Regression tests for issue rust-lang#54477.

At some point someone may want to revisit PR rust-lang#53564

it would be really good to have regression tests for rust-lang#54477 before that happens. :)
bors added a commit to rust-lang-ci/rust that referenced this pull request Oct 15, 2021
Optimize VecDeque::append

Optimize `VecDeque::append` to do unsafe copy rather than iterating through each element.

On my `Intel(R) Xeon(R) CPU E5-2630 v4 @ 2.20GHz`, the benchmark shows 37% improvements:
```
Master:
custom-bench vec_deque_append 583164 ns/iter
custom-bench vec_deque_append 550040 ns/iter

Patched:
custom-bench vec_deque_append 349204 ns/iter
custom-bench vec_deque_append 368164 ns/iter
```

Additional notes on the context: this is the third attempt to implement a non-trivial version of `VecDeque::append`, the last two are reverted due to unsoundness or regression, see:
- rust-lang#52553, reverted in rust-lang#53571
- rust-lang#53564, reverted in rust-lang#54851

Both cases are covered by existing tests.

Signed-off-by: tabokie <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet