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

Raise alignment limit from 2^15 to 2^31 - 1 #43097

Merged
merged 4 commits into from
Jul 9, 2017

Conversation

PlasmaPower
Copy link
Contributor

Fixes #42960

@rust-highfive
Copy link
Collaborator

Thanks for the pull request, and welcome! The Rust team is excited to review your changes, and you should hear from @arielb1 (or someone else) soon.

If any changes to this PR are deemed necessary, please add them as extra commits. This ensures that the reviewer can see what has changed since they last reviewed the code. Due to the way GitHub handles out-of-date commits, this should also make it reasonably obvious what issues have or haven't been addressed. Large or tricky changes may require several passes of review and changes.

Please see the contribution instructions for more information.

@PlasmaPower PlasmaPower changed the title Raised alignment limit from 2^15 to 2^31 Raise alignment limit from 2^15 to 2^31 Jul 6, 2017
@PlasmaPower
Copy link
Contributor Author

@eddyb - I think you wrote the initial Align struct in #32939, does this PR look good?

I don't think I can change the reviewer after creating the PR.

@eddyb
Copy link
Member

eddyb commented Jul 7, 2017

@PlasmaPower Did you mean 2^64 - 1? Or are you bounding it somewhere?

} else {
Ok(pow)
}
};

Ok(Align {
raw: pack(abi)? | (pack(pref)? << 4)
abi: pack(abi)?,
pref: pack(pref)?,
Copy link
Member

Choose a reason for hiding this comment

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

I'd rename this to log2.

// rustc::ty::layout::Align restricts align to <= 32768
if align <= 32768 {
acc.push(ReprAlign(align as u16));
// rustc::ty::layout::Align restricts align to <= 2147483648
Copy link
Member

Choose a reason for hiding this comment

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

Ah but this is incorrect given that Align::from_bytes takes an u64.

@PlasmaPower
Copy link
Contributor Author

@eddyb you're right, I did the math on the upper bound wrong. Will fix.

@shepmaster shepmaster added the S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. label Jul 7, 2017
@PlasmaPower
Copy link
Contributor Author

The resulting binary is segfaulting when I switch from u32s to u64s in some places, as necessary with a limit of 2^64 - 1. I'll investigate further.

@eddyb
Copy link
Member

eddyb commented Jul 7, 2017

@PlasmaPower LLVM probably doesn't like alignments larger than 2^31 - 1.

@PlasmaPower
Copy link
Contributor Author

@eddyb I'm assuming you mean larger than 2^32 - 1? I'm not sure why that would matter, and in addition I'm not testing alignments larger than 2^32 - 1. There might be another factor here. I might just stick with u32s though, as we shouldn't need anything larger than that.

@eddyb
Copy link
Member

eddyb commented Jul 7, 2017

@PlasmaPower LLVM uses signed 32-bit integers for alignments IIRC.

@PlasmaPower
Copy link
Contributor Author

I rebased on master and added the limit changes, but resulting binaries with big aligns still seem to be segfaulting. They were working before, but when I check out the previous commit it still seg faults. I might try removing my build directory and building the compiler fresh. Any ideas @eddyb ? When I run it with GDB, it says "no stack" after segfaulting.

@@ -312,39 +314,36 @@ impl Align {
}
if bytes != 1 {
Err(format!("`{}` is not a power of 2", align))
} else if pow > 0x0f {
Err(format!("`{}` is too large", align))
Copy link
Member

@eddyb eddyb Jul 8, 2017

Choose a reason for hiding this comment

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

You should keep the check here though (and update it for 31 bits).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Should this struct care about the 31 bit limit? I've done the checking for that closer to the parsing. The previous limit here was due to the limitations of using just 1 nibble, but now it has no such limit.

Copy link
Member

Choose a reason for hiding this comment

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

The parsing is for the user-facing value. Here we must protect any internal guarantees.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fair enough. Will fix.

arr[0] = 132;
let large = AlignLarge {
stuff: arr,
};
Copy link
Member

Choose a reason for hiding this comment

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

Try using box (not Box::new!) - maybe you're blowing the stack?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good point, I thought an upstream change might result in that but I didn't think to avoid it with box.

@eddyb
Copy link
Member

eddyb commented Jul 8, 2017

cc @alexcrichton The PR in its current state might be failing in strange ways due to the new probestack logic. For the record, the updated test contains:

// The align limit was originally smaller (2^15).
// Check that it works with big numbers.
#[repr(align(0x10000))]
struct AlignLarge {
    stuff: [u8; 0x10000],
}

// Check the actual address is aligned
fn is_aligned_to<T>(p: &T, align: usize) -> bool {
    let addr = p as *const T as usize;
    (addr & (align - 1)) == 0
}

fn main() {
    let mut arr = [0; 0x10000];
    arr[0] = 132;
    let large = AlignLarge {
        stuff: arr,
    };
    assert_eq!(large.stuff[0], 132);
    assert_eq!(mem::align_of::<AlignLarge>(), 0x10000);
    assert_eq!(mem::align_of_val(&large), 0x10000);
    assert!(is_aligned_to(&large, 0x10000));
}

@PlasmaPower
Copy link
Contributor Author

@eddyb That's exactly the change I thought of, but I don't know near enough about that low level stuff to know how to work around it or fix it.

@PlasmaPower
Copy link
Contributor Author

Box syntax fixed it, but it turns out it wasn't the large alignment but instead the large array. This used to work: let x = [0; 0x10000] but now it needs to be let x = box [0; 0x10000].

@PlasmaPower PlasmaPower changed the title Raise alignment limit from 2^15 to 2^31 Raise alignment limit from 2^15 to 2^31 - 1 Jul 8, 2017
@eddyb
Copy link
Member

eddyb commented Jul 8, 2017

@bors r+

@bors
Copy link
Contributor

bors commented Jul 8, 2017

📌 Commit b4973e9 has been approved by eddyb

@bors
Copy link
Contributor

bors commented Jul 8, 2017

⌛ Testing commit b4973e9 with merge c531c46140a9d65da3e2d24396ebde3ee1c54335...

@bors
Copy link
Contributor

bors commented Jul 8, 2017

💔 Test failed - status-travis

@PlasmaPower
Copy link
Contributor Author

Failure seems unrelated to this PR.

@eddyb
Copy link
Member

eddyb commented Jul 8, 2017

@bors retry

@bors
Copy link
Contributor

bors commented Jul 8, 2017

⌛ Testing commit b4973e9 with merge 4b7f41a...

bors added a commit that referenced this pull request Jul 8, 2017
Raise alignment limit from 2^15 to 2^31 - 1

Fixes #42960
@bors
Copy link
Contributor

bors commented Jul 9, 2017

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

@bors bors merged commit b4973e9 into rust-lang:master Jul 9, 2017
@pnkfelix pnkfelix mentioned this pull request Jul 13, 2017
12 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants