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

Ensure that statics are always ByRef #50690

Merged
merged 5 commits into from
May 19, 2018
Merged

Ensure that statics are always ByRef #50690

merged 5 commits into from
May 19, 2018

Conversation

oli-obk
Copy link
Contributor

@oli-obk oli-obk commented May 12, 2018

Statics aren't values to be used, they are names for memory locations.

r? @eddyb

cc @Zoxc

fixes #50706

@rust-highfive
Copy link
Collaborator

r? @eddyb

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

@rust-highfive rust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label May 12, 2018
@oli-obk
Copy link
Contributor Author

oli-obk commented May 12, 2018

r? @eddyb

@@ -171,11 +128,11 @@ pub fn trans_static_initializer<'a, 'tcx>(
let param_env = ty::ParamEnv::reveal_all();
let static_ = cx.tcx.const_eval(param_env.and(cid))?;
Copy link
Member

Choose a reason for hiding this comment

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

I'm thinking const_eval isn't the best, but it's probably an okay compromise.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We could create a separate query for statics.

@eddyb
Copy link
Member

eddyb commented May 12, 2018

@bors r+

@bors
Copy link
Contributor

bors commented May 12, 2018

📌 Commit 89201f3 has been approved by eddyb

@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 May 12, 2018
@Zoxc
Copy link
Contributor

Zoxc commented May 12, 2018

This makes ConstValue for statics special cased to avoid the optimizations in ConstValue. This reduces performance and adds unnecessary complexity.

if layout.is_zst() {
return ty::Const::from_const_value(
tcx,
ConstValue::ByVal(PrimVal::Undef),
Copy link
Contributor

Choose a reason for hiding this comment

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

Is ZST always ByVal(PrimVal::Undef) in Miri?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

No. Accessing a zst field of a ByRef will return a ByRef

Copy link
Contributor

Choose a reason for hiding this comment

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

Then this code should still be here.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Why? Won't we simply get an empty allocation in the ByRef?

Copy link
Contributor

Choose a reason for hiding this comment

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

Each Rust value should only map to one ConstValue. so a ZST type cannot be both ByVal(PrimVal::Undef) and ByRef.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

that would require us to spray is_zst checks everywhere. Miri already "violates" your assumption left and right.

The current code tries to reduce special cases, only ignoring zst memory reads in Memory, not earlier.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Wait. wouldn't it actually make more sense to try to move to ByRef for zst everywhere? You can't ever have a zst value. They have no values (well one value, but we don't ever read/write it).

Copy link
Contributor

Choose a reason for hiding this comment

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

that would require us to spray is_zst checks everywhere. Miri already "violates" your assumption left and right.

Miri doesn't use ConstValue. It is not an assumption but an invariant of the ConstValue type. You just need to check for ZST types when converting to a ConstValue. Having this invariant for ConstValue is very useful since:

  • it reduces memory usage when it is interned
  • if you want to check for a specific value, you only need to look at one of it's variants, for example true only needs to check for ByVal(PrimVal::Bytes(1)) and can ignore ByRef entirely. There is a fair amount of code which relies on this properly which has to be updated if you want to make static always return ByRef.

We can get rid of the special case for ZST by making them have a Scalar ABI so they can be stored in ByVal instead of ByRef which would otherwise be required since they have Aggregate ABI currently.

Copy link
Contributor

Choose a reason for hiding this comment

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

Wait. wouldn't it actually make more sense to try to move to ByRef for zst everywhere? You can't ever have a zst value. They have no values (well one value, but we don't ever read/write it).

Then we'd have to create allocations for ZST types, which we want to avoid for performance reasons. That is why ConstValue::ByVal and ConstValue::ByValPair exist at all.

if let Value::ByValPair(a, b) = val {
ConstValue::ByValPair(a, b)
} else {
bug!("expected ByValPair value, got {:?}", val);
Copy link
Contributor

Choose a reason for hiding this comment

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

Please keep these sanity checks. At least when debug-assertions is on. I really don't trust Miri code to be correct.

@oli-obk
Copy link
Contributor Author

oli-obk commented May 13, 2018

@bors r-

more sanity checks

@bors bors added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. labels May 13, 2018
@bors
Copy link
Contributor

bors commented May 16, 2018

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

@oli-obk oli-obk force-pushed the mir_stuff branch 2 times, most recently from 7d96991 to dd048e9 Compare May 17, 2018 14:51
@oli-obk
Copy link
Contributor Author

oli-obk commented May 17, 2018

@eddyb @Zoxc this now also fixes #50706 (fix included here because without this PR the fix might do stupid things when accessing the fields of statics)

@bors
Copy link
Contributor

bors commented May 17, 2018

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

// Used only for the remaining cases
ByRef(&'tcx Allocation),
/// Used only for the remaining cases. An allocation + offset into the allocation
ByRef(&'tcx Allocation, u64),
Copy link
Member

Choose a reason for hiding this comment

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

Please use Size for offsets.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done

MemoryPointer { alloc_id, offset }
}

pub(crate) fn wrapping_signed_offset<C: HasDataLayout>(self, i: i64, cx: C) -> Self {
MemoryPointer::new(
self.alloc_id,
cx.data_layout().wrapping_signed_offset(self.offset, i),
Size::from_bytes(cx.data_layout().wrapping_signed_offset(self.offset.bytes(), i)),
Copy link
Member

Choose a reason for hiding this comment

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

Why would wrapping_signed_offset not work on a Size?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

because SIze doesn't have a sign. I mean we could create an Offset type (which would then also be the Output of impl Sub for Size)...

@eddyb
Copy link
Member

eddyb commented May 19, 2018

@bors r+

@bors
Copy link
Contributor

bors commented May 19, 2018

📌 Commit 7c25aa7 has been approved by eddyb

@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-author Status: This is awaiting some action (such as code changes or more information) from the author. labels May 19, 2018
@kennytm
Copy link
Member

kennytm commented May 19, 2018

@bors p=38

@bors
Copy link
Contributor

bors commented May 19, 2018

⌛ Testing commit 7c25aa7 with merge 5c3960c...

bors added a commit that referenced this pull request May 19, 2018
Ensure that statics are always ByRef

Statics aren't values to be used, they are names for memory locations.

r? @eddyb

cc @Zoxc

fixes #50706
@bors
Copy link
Contributor

bors commented May 19, 2018

☀️ Test successful - status-appveyor, status-travis
Approved by: eddyb
Pushing 5c3960c to master...

@bors bors merged commit 7c25aa7 into rust-lang:master May 19, 2018
@oli-obk oli-obk deleted the mir_stuff branch June 15, 2020 15:27
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.

const_val_field on non-field
6 participants