-
Notifications
You must be signed in to change notification settings - Fork 12.9k
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
Make &Slice a thin pointer #50612
Make &Slice a thin pointer #50612
Conversation
The job Click to expand the log.
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 |
At least the linker errors are reproducible |
src/librustc/ty/mod.rs
Outdated
|
||
impl<T> PartialEq for Slice<T> { | ||
#[inline] | ||
fn eq(&self, other: &Slice<T>) -> bool { | ||
(&self.0 as *const [T]) == (&other.0 as *const [T]) | ||
(self as *const _) == (other as *const _) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
PartialEq
and Hash
don't agree. Is it possible that we ever have two slices with the same address but different lengths?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's not possible as the length is stored at that address.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The Hash
implementation should just hash the pointer then. Should be faster too.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The HashStable
impl in impls_ty.rs
should also just use the pointer as the cache key.
src/librustc/ty/mod.rs
Outdated
pub fn empty<'a>() -> &'a Slice<T> { | ||
unsafe { | ||
mem::transmute(slice::from_raw_parts(0x1 as *const T, 0)) | ||
&*(EMPTY_SLICE as *const _) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm wondering if this can trigger some kind of undefined behavior? Maybe mem::transmute(EMPTY_SLICE)
would be better.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can get rid of the optimization for the empty slice and see if that helps...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removing it does make things work.
☔ The latest upstream changes (presumably #50332) made this pull request unmergeable. Please resolve the merge conflicts. |
Ping from triage @Zoxc! It's been a while since we heard from you, will you have time to work on this again soon? |
The job Click to expand the log.
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 |
The job Click to expand the log.
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 |
@bors try |
Make &Slice a thin pointer Split out from #50395 r? @michaelwoerister
☀️ Test successful - status-travis |
@Mark-Simulacrum I'd like a perf run here |
This will be interesting |
src/librustc/ty/mod.rs
Outdated
/// A wrapper for slices with the additional invariant | ||
/// that the slice is interned and no other slice with | ||
/// the same contents can exist in the same context. | ||
/// This means we can use pointer + length for both | ||
/// equality comparisons and hashing. | ||
#[derive(Debug, RustcEncodable)] | ||
pub struct Slice<T>([T]); | ||
pub struct Slice<T>(PhantomData<T>, OpaqueSliceContents); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you write this as:
#[repr(C)]
pub struct Slice<T> {
pub len: usize,
data: [T; 0],
_opaque: OpaqueSliceContents,
}
Then you can read/write the len
, and get a pointer to the start of the data by .data.as_ptr()
, both of which work in safe code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1
The job Click to expand the log.
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 |
src/librustc/ty/mod.rs
Outdated
let align = mem::align_of::<T>(); | ||
let align_mask = align - 1; | ||
let offset = mem::size_of::<usize>(); | ||
(offset + align_mask) & !align_mask |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since this is only used to compute the size to allocate, could you inline it into from_arena
?
☔ The latest upstream changes (presumably #50930) made this pull request unmergeable. Please resolve the merge conflicts. |
The job Click to expand the log.
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 |
@eddyb's suggestions have been applied. |
📌 Commit fb4e3b6 has been approved by |
Make &Slice a thin pointer Split out from #50395 r? @michaelwoerister
☀️ Test successful - status-appveyor, status-travis |
This looks like a slight performance win. The previous benchmark run hashed the length of slices and it had an assertion in the |
Split out from #50395
r? @michaelwoerister