Avoid reloading Vec::len across grow_one in push
This saves an extra load from memory.
This commit is contained in:
parent
c3ceb00281
commit
f1ae5314be
@ -1991,15 +1991,17 @@ fn drop(&mut self) {
|
|||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
#[rustc_confusables("push_back", "put", "append")]
|
#[rustc_confusables("push_back", "put", "append")]
|
||||||
pub fn push(&mut self, value: T) {
|
pub fn push(&mut self, value: T) {
|
||||||
|
// Inform codegen that the length does not change across grow_one().
|
||||||
|
let len = self.len;
|
||||||
// This will panic or abort if we would allocate > isize::MAX bytes
|
// This will panic or abort if we would allocate > isize::MAX bytes
|
||||||
// or if the length increment would overflow for zero-sized types.
|
// or if the length increment would overflow for zero-sized types.
|
||||||
if self.len == self.buf.capacity() {
|
if len == self.buf.capacity() {
|
||||||
self.buf.grow_one();
|
self.buf.grow_one();
|
||||||
}
|
}
|
||||||
unsafe {
|
unsafe {
|
||||||
let end = self.as_mut_ptr().add(self.len);
|
let end = self.as_mut_ptr().add(len);
|
||||||
ptr::write(end, value);
|
ptr::write(end, value);
|
||||||
self.len += 1;
|
self.len = len + 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
16
tests/codegen/vec-len-invariant.rs
Normal file
16
tests/codegen/vec-len-invariant.rs
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
//@ compile-flags: -O
|
||||||
|
//@ only-64bit
|
||||||
|
//
|
||||||
|
// This test confirms that we do not reload the length of a Vec after growing it in push.
|
||||||
|
|
||||||
|
#![crate_type = "lib"]
|
||||||
|
|
||||||
|
// CHECK-LABEL: @should_load_once
|
||||||
|
#[no_mangle]
|
||||||
|
pub fn should_load_once(v: &mut Vec<u8>) {
|
||||||
|
// CHECK: load i64
|
||||||
|
// CHECK: call {{.*}}grow_one
|
||||||
|
// CHECK-NOT: load i64
|
||||||
|
// CHECK: add {{.*}}, 1
|
||||||
|
v.push(1);
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user