| ... | @@ -8,6 +8,7 @@ pub const Cmp = math.Cmp; | ... | @@ -8,6 +8,7 @@ pub const Cmp = math.Cmp; |
| 8 | pub const Allocator = struct { | 8 | pub const Allocator = struct { |
| 9 | /// Allocate byte_count bytes and return them in a slice, with the | 9 | /// Allocate byte_count bytes and return them in a slice, with the |
| 10 | /// slice's pointer aligned at least to alignment bytes. | 10 | /// slice's pointer aligned at least to alignment bytes. |
| | 11 | /// The returned newly allocated memory is undefined. |
| 11 | allocFn: fn (self: &Allocator, byte_count: usize, alignment: u29) -> %[]u8, | 12 | allocFn: fn (self: &Allocator, byte_count: usize, alignment: u29) -> %[]u8, |
| 12 | | 13 | |
| 13 | /// If `new_byte_count > old_mem.len`: | 14 | /// If `new_byte_count > old_mem.len`: |
| ... | @@ -17,6 +18,8 @@ pub const Allocator = struct { | ... | @@ -17,6 +18,8 @@ pub const Allocator = struct { |
| 17 | /// If `new_byte_count <= old_mem.len`: | 18 | /// If `new_byte_count <= old_mem.len`: |
| 18 | /// * this function must return successfully. | 19 | /// * this function must return successfully. |
| 19 | /// * alignment <= alignment of old_mem.ptr | 20 | /// * alignment <= alignment of old_mem.ptr |
| | 21 | /// |
| | 22 | /// The returned newly allocated memory is undefined. |
| 20 | reallocFn: fn (self: &Allocator, old_mem: []u8, new_byte_count: usize, alignment: u29) -> %[]u8, | 23 | reallocFn: fn (self: &Allocator, old_mem: []u8, new_byte_count: usize, alignment: u29) -> %[]u8, |
| 21 | | 24 | |
| 22 | /// Guaranteed: `old_mem.len` is the same as what was returned from `allocFn` or `reallocFn` | 25 | /// Guaranteed: `old_mem.len` is the same as what was returned from `allocFn` or `reallocFn` |
| ... | @@ -40,6 +43,10 @@ pub const Allocator = struct { | ... | @@ -40,6 +43,10 @@ pub const Allocator = struct { |
| 40 | { | 43 | { |
| 41 | const byte_count = %return math.mul(usize, @sizeOf(T), n); | 44 | const byte_count = %return math.mul(usize, @sizeOf(T), n); |
| 42 | const byte_slice = %return self.allocFn(self, byte_count, alignment); | 45 | const byte_slice = %return self.allocFn(self, byte_count, alignment); |
| | 46 | // This loop should get optimized out in ReleaseFast mode |
| | 47 | for (byte_slice) |*byte| { |
| | 48 | *byte = undefined; |
| | 49 | } |
| 43 | return ([]align(alignment) T)(@alignCast(alignment, byte_slice)); | 50 | return ([]align(alignment) T)(@alignCast(alignment, byte_slice)); |
| 44 | } | 51 | } |
| 45 | | 52 | |
| ... | @@ -54,8 +61,13 @@ pub const Allocator = struct { | ... | @@ -54,8 +61,13 @@ pub const Allocator = struct { |
| 54 | return self.alloc(T, n); | 61 | return self.alloc(T, n); |
| 55 | } | 62 | } |
| 56 | | 63 | |
| | 64 | const old_byte_slice = ([]u8)(old_mem); |
| 57 | const byte_count = %return math.mul(usize, @sizeOf(T), n); | 65 | const byte_count = %return math.mul(usize, @sizeOf(T), n); |
| 58 | const byte_slice = %return self.reallocFn(self, ([]u8)(old_mem), byte_count, alignment); | 66 | const byte_slice = %return self.reallocFn(self, old_byte_slice, byte_count, alignment); |
| | 67 | // This loop should get optimized out in ReleaseFast mode |
| | 68 | for (byte_slice[old_byte_slice.len..]) |*byte| { |
| | 69 | *byte = undefined; |
| | 70 | } |
| 59 | return ([]T)(@alignCast(alignment, byte_slice)); | 71 | return ([]T)(@alignCast(alignment, byte_slice)); |
| 60 | } | 72 | } |
| 61 | | 73 | |