about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMara Bos <m-ou.se@m-ou.se>2021-01-22 14:30:22 +0000
committerGitHub <noreply@github.com>2021-01-22 14:30:22 +0000
commit9c2a5776b205aebec2685966fc24f59dde7fe76a (patch)
treeba049a3d4573a2eec5e59dc7f972559cb1997775
parent70597f28f6a97015d3d02ee34a7fa076128f3f32 (diff)
parent758d855bff92cb35e13c5ae078639b862f02001f (diff)
downloadrust-9c2a5776b205aebec2685966fc24f59dde7fe76a.tar.gz
rust-9c2a5776b205aebec2685966fc24f59dde7fe76a.zip
Rollup merge of #81242 - jyn514:const-cap, r=sfackler
Enforce statically that `MIN_NON_ZERO_CAP` is calculated at compile time

Previously, it would usually get computed by LLVM, but this enforces it. This removes the need for the comment saying "LLVM is smart enough".

I don't expect this to make a performance difference, but I do think it makes the performance properties easier to reason about.
-rw-r--r--library/alloc/src/raw_vec.rs30
1 files changed, 14 insertions, 16 deletions
diff --git a/library/alloc/src/raw_vec.rs b/library/alloc/src/raw_vec.rs
index 36b7efc33a8..36e2d18d3dd 100644
--- a/library/alloc/src/raw_vec.rs
+++ b/library/alloc/src/raw_vec.rs
@@ -114,6 +114,19 @@ impl<T> RawVec<T, Global> {
 }
 
 impl<T, A: Allocator> RawVec<T, A> {
+    // Tiny Vecs are dumb. Skip to:
+    // - 8 if the element size is 1, because any heap allocators is likely
+    //   to round up a request of less than 8 bytes to at least 8 bytes.
+    // - 4 if elements are moderate-sized (<= 1 KiB).
+    // - 1 otherwise, to avoid wasting too much space for very short Vecs.
+    const MIN_NON_ZERO_CAP: usize = if mem::size_of::<T>() == 1 {
+        8
+    } else if mem::size_of::<T>() <= 1024 {
+        4
+    } else {
+        1
+    };
+
     /// Like `new`, but parameterized over the choice of allocator for
     /// the returned `RawVec`.
     #[rustc_allow_const_fn_unstable(const_fn)]
@@ -399,22 +412,7 @@ impl<T, A: Allocator> RawVec<T, A> {
         // This guarantees exponential growth. The doubling cannot overflow
         // because `cap <= isize::MAX` and the type of `cap` is `usize`.
         let cap = cmp::max(self.cap * 2, required_cap);
-
-        // Tiny Vecs are dumb. Skip to:
-        // - 8 if the element size is 1, because any heap allocators is likely
-        //   to round up a request of less than 8 bytes to at least 8 bytes.
-        // - 4 if elements are moderate-sized (<= 1 KiB).
-        // - 1 otherwise, to avoid wasting too much space for very short Vecs.
-        // Note that `min_non_zero_cap` is computed statically.
-        let elem_size = mem::size_of::<T>();
-        let min_non_zero_cap = if elem_size == 1 {
-            8
-        } else if elem_size <= 1024 {
-            4
-        } else {
-            1
-        };
-        let cap = cmp::max(min_non_zero_cap, cap);
+        let cap = cmp::max(Self::MIN_NON_ZERO_CAP, cap);
 
         let new_layout = Layout::array::<T>(cap);