about summary refs log tree commit diff
diff options
context:
space:
mode:
authorC Jones <code@calebjones.net>2018-04-30 15:24:59 -0400
committerC Jones <code@calebjones.net>2018-05-07 21:57:45 -0400
commit669bd8223bf159d757d0c552a4c413a137bc6b10 (patch)
treeb5486f61d76aaa919d51ddebfd03455f27c49ef9
parent64e6dda0bce96da47e52f7f3e278d05f7a09473c (diff)
downloadrust-669bd8223bf159d757d0c552a4c413a137bc6b10.tar.gz
rust-669bd8223bf159d757d0c552a4c413a137bc6b10.zip
Make LeafNode #[repr(C)] and put the metadata before generic items
This way we can safely statically allocate a LeafNode to use as the
placeholder before allocating, and any type accessing it will be able to
access the metadata at the same offset.
-rw-r--r--src/liballoc/btree/node.rs20
1 files changed, 12 insertions, 8 deletions
diff --git a/src/liballoc/btree/node.rs b/src/liballoc/btree/node.rs
index d6346662314..3e27331aa38 100644
--- a/src/liballoc/btree/node.rs
+++ b/src/liballoc/btree/node.rs
@@ -60,12 +60,12 @@ pub const CAPACITY: usize = 2 * B - 1;
 ///
 /// See also rust-lang/rfcs#197, which would make this structure significantly more safe by
 /// avoiding accidentally dropping unused and uninitialized keys and values.
+///
+/// We put the metadata first so that its position is the same for every `K` and `V`, in order
+/// to statically allocate a single dummy node to avoid allocations. This struct is `repr(C)` to
+/// prevent them from being reordered.
+#[repr(C)]
 struct LeafNode<K, V> {
-    /// The arrays storing the actual data of the node. Only the first `len` elements of each
-    /// array are initialized and valid.
-    keys: [K; CAPACITY],
-    vals: [V; CAPACITY],
-
     /// We use `*const` as opposed to `*mut` so as to be covariant in `K` and `V`.
     /// This either points to an actual node or is null.
     parent: *const InternalNode<K, V>,
@@ -77,10 +77,14 @@ struct LeafNode<K, V> {
 
     /// The number of keys and values this node stores.
     ///
-    /// This is at the end of the node's representation and next to `parent_idx` to encourage
-    /// the compiler to join `len` and `parent_idx` into the same 32-bit word, reducing space
-    /// overhead.
+    /// This next to `parent_idx` to encourage the compiler to join `len` and
+    /// `parent_idx` into the same 32-bit word, reducing space overhead.
     len: u16,
+
+    /// The arrays storing the actual data of the node. Only the first `len` elements of each
+    /// array are initialized and valid.
+    keys: [K; CAPACITY],
+    vals: [V; CAPACITY],
 }
 
 impl<K, V> LeafNode<K, V> {