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

Simplify SyncOnceCell's take and drop. #76640

Merged
merged 2 commits into from
Sep 14, 2020

Conversation

m-ou-se
Copy link
Member

@m-ou-se m-ou-se commented Sep 12, 2020

Prevents copies by using assume_init_read and assume_init_drop.

@m-ou-se

This comment has been minimized.

@jyn514 jyn514 added T-libs Relevant to the library team, which will review and decide on the PR/issue. S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-libs-api Relevant to the library API team, which will review and decide on the PR/issue. labels Sep 12, 2020
Without this, it was not inlined in SyncOnceCell::into_inner(), causing
unecessary checks and dead code.
@m-ou-se

This comment has been minimized.

@RalfJung
Copy link
Member

I am not familiar with this SyncOnceCell type and never used it, nor the Once it builds on... so, while the MaybeUninit interaction looks okay, I cannot tell if it satisfies the invariant of these types.

Cc @matklad @KodrAus can you help with the review here?

@RalfJung
Copy link
Member

The struct type has a comment

    // Whether or not the value is initialized is tracked by `state_and_queue`.

but there's no state_and_queue. So maybe someone who actually understands this type could please also fix the outdated comment? :D

Also Cc @Mark-Simulacrum who was involved in previous reviews here.

Copy link
Member

@matklad matklad left a comment

Choose a reason for hiding this comment

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

@bors r+ rollup

// SAFETY: `self.value` is initialized and contains a valid `T`.
// `self.once` is reset, so `is_initialized()` will be false again
// which prevents the value from being read twice.
unsafe { Some((&mut *self.value.get()).assume_init_read()) }
Copy link
Member

Choose a reason for hiding this comment

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

So we leave some garbage bytes inside, but they are guarded by reseted Once? Nifty!

Copy link
Member

@RalfJung RalfJung Sep 13, 2020

Choose a reason for hiding this comment

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

FWIW, previously this wrote MaybeUninit::uninit() which is equivalent to not writing anything, so we already left behind garbage before. (Just the compiler might find it easier this way as there are no uninit writes to eliminate.)

Copy link
Member Author

Choose a reason for hiding this comment

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

The disassembly of this new version is slightly shorter. It seems to make one less copy. (Specifically for SyncOnceCell<String> at least.) But that's probably just the copy out of self.value into value.

Copy link
Member

Choose a reason for hiding this comment

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

It's also possible that the compiler just did not realize before that it was needlessly copying uninitialized memory.

///
/// Safety: The cell must now be free'd WITHOUT dropping. No other usages of the cell
/// are valid. Only used by `into_inner` and `drop`.
unsafe fn take_inner(&mut self) -> Option<T> {
Copy link
Member

Choose a reason for hiding this comment

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

👍 I was thinking about removing take_inner as well (its contract is just weird), but I didn't know about those useful MaybeUninit helpers!

Copy link
Member Author

Choose a reason for hiding this comment

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

That's because they didn't exist yet. :) I added assume_init_drop in #76484 just a few days ago.

@RalfJung
Copy link
Member

Bors doesn't read review comments
@bors r=matklad rollup
r? @matklad

@bors
Copy link
Contributor

bors commented Sep 13, 2020

📌 Commit aa68aaa has been approved by matklad

@rust-highfive rust-highfive assigned matklad and unassigned RalfJung Sep 13, 2020
@matklad
Copy link
Member

matklad commented Sep 13, 2020

The struct type has a comment

Yeah, that comment is outdated, it's basically a transposon -- it was originally copy-pasted from std's Once impl into once_cell crate, and now it is copy-pasted back

This comment also seems suspicious:

// Treat the underlying `Once` as poisoned since we
// failed to initialize our value. Calls
p.poison();

It would be good to clean those up, but probably in a separate PR.

@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 Sep 13, 2020
RalfJung added a commit to RalfJung/rust that referenced this pull request Sep 13, 2020
…ll-drop, r=matklad

Simplify SyncOnceCell's `take` and `drop`.

Prevents copies by using `assume_init_read` and `assume_init_drop`.
RalfJung added a commit to RalfJung/rust that referenced this pull request Sep 13, 2020
…ll-drop, r=matklad

Simplify SyncOnceCell's `take` and `drop`.

Prevents copies by using `assume_init_read` and `assume_init_drop`.
bors added a commit to rust-lang-ci/rust that referenced this pull request Sep 13, 2020
…as-schievink

Rollup of 12 pull requests

Successful merges:

 - rust-lang#75559 (unions: test move behavior of non-Copy fields)
 - rust-lang#76441 (Note that parallel-compiler = true causes tests to fail)
 - rust-lang#76527 (Remove internal and unstable MaybeUninit::UNINIT.)
 - rust-lang#76629 (Simplify iter zip struct doc)
 - rust-lang#76640 (Simplify SyncOnceCell's `take` and `drop`.)
 - rust-lang#76646 (Add mailmap entry)
 - rust-lang#76651 (Remove Windows details from Unix and VmWorks symlink() docstrings)
 - rust-lang#76663 (Simplify iter chain struct doc)
 - rust-lang#76665 (slice::from_raw_parts: explicitly mention that data must be initialized)
 - rust-lang#76667 (Fix CI LLVM to work on NixOS out of the box)
 - rust-lang#76668 (Add visualization of rustc span in doc)
 - rust-lang#76677 (note that test_stable_pointers does not reflect a stable guarantee)

Failed merges:

r? `@ghost`
@bors bors merged commit f9b9467 into rust-lang:master Sep 14, 2020
@rustbot rustbot added this to the 1.48.0 milestone Sep 14, 2020
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. T-libs Relevant to the library team, which will review and decide on the PR/issue. T-libs-api Relevant to the library API team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants