From 29edc3fe5012fa1a6eb23deffd5ffb17ebebec7a Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 2 Jan 2019 11:59:22 -0800 Subject: [PATCH] Make `ListPool`'s `alloc` fill new memory with reserved values. This makes it harder to misuse, as 0 could be confused for a valid value. --- lib/entity/src/list.rs | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/lib/entity/src/list.rs b/lib/entity/src/list.rs index 37ac92ad0b..617ea2db32 100644 --- a/lib/entity/src/list.rs +++ b/lib/entity/src/list.rs @@ -1,4 +1,5 @@ //! Small lists of entity references. +use crate::packed_option::ReservedValue; use crate::EntityRef; use std::marker::PhantomData; use std::mem; @@ -59,13 +60,13 @@ use std::vec::Vec; /// The index stored in an `EntityList` points to part 2, the list elements. The value 0 is /// reserved for the empty list which isn't allocated in the vector. #[derive(Clone, Debug)] -pub struct EntityList { +pub struct EntityList { index: u32, unused: PhantomData, } /// Create an empty list. -impl Default for EntityList { +impl Default for EntityList { fn default() -> Self { Self { index: 0, @@ -76,7 +77,7 @@ impl Default for EntityList { /// A memory pool for storing lists of `T`. #[derive(Clone, Debug)] -pub struct ListPool { +pub struct ListPool { // The main array containing the lists. data: Vec, @@ -105,7 +106,7 @@ fn is_sclass_min_length(len: usize) -> bool { len > 3 && len.is_power_of_two() } -impl ListPool { +impl ListPool { /// Create a new list pool. pub fn new() -> Self { Self { @@ -140,7 +141,8 @@ impl ListPool { /// Allocate a storage block with a size given by `sclass`. /// /// Returns the first index of an available segment of `self.data` containing - /// `sclass_size(sclass)` elements. + /// `sclass_size(sclass)` elements. The allocated memory is filled with reserved + /// values. fn alloc(&mut self, sclass: SizeClass) -> usize { // First try the free list for this size class. match self.free.get(sclass as usize).cloned() { @@ -155,9 +157,8 @@ impl ListPool { _ => { // Nothing on the free list. Allocate more memory. let offset = self.data.len(); - // We don't want to mess around with uninitialized data. - // Just fill it up with nulls. - self.data.resize(offset + sclass_size(sclass), T::new(0)); + self.data + .resize(offset + sclass_size(sclass), T::reserved_value()); offset } } @@ -219,7 +220,7 @@ impl ListPool { } } -impl EntityList { +impl EntityList { /// Create a new empty list. pub fn new() -> Self { Default::default() @@ -351,7 +352,7 @@ impl EntityList { } } - /// Grow list by adding `count` uninitialized elements at the end. + /// Grow list by adding `count` reserved-value elements at the end. /// /// Returns a mutable slice representing the whole list. fn grow<'a>(&'a mut self, count: usize, pool: &'a mut ListPool) -> &'a mut [T] { @@ -483,6 +484,7 @@ impl EntityList { mod tests { use super::*; use super::{sclass_for_length, sclass_size}; + use crate::packed_option::ReservedValue; use crate::EntityRef; /// An opaque reference to an instruction in a function.