Skip to content

Commit b789617

Browse files
committed
Remove the reserve_in_place calls in {Typed,Dropless}Arena::grow.
They are pointless. No reasonable allocator will be able to satisfy a `reserve_in_place` request that *doubles* the size of an allocation when dealing with allocations that are 4 KiB and larger. Just to be sure, I confirmed on Linux that the `reserve_in_place` calls never succeed. (Note however that the `reserve_in_place` call for `DroplessArena::grow` did occasionally succeed prior to the off-by-one fix in the previous commit, because we would sometimes do a `reserve_in_place` request for the chunk's current size, which would trivially succeed!)
1 parent a80dc28 commit b789617

File tree

1 file changed

+22
-30
lines changed

1 file changed

+22
-30
lines changed

src/libarena/lib.rs

+22-30
Original file line numberDiff line numberDiff line change
@@ -216,34 +216,29 @@ impl<T> TypedArena<T> {
216216
#[cold]
217217
fn grow(&self, n: usize) {
218218
unsafe {
219-
// We need the element size in to convert chunk sizes (ranging from
219+
// We need the element size to convert chunk sizes (ranging from
220220
// PAGE to HUGE_PAGE bytes) to element counts.
221221
let elem_size = cmp::max(1, mem::size_of::<T>());
222222
let mut chunks = self.chunks.borrow_mut();
223-
let (chunk, mut new_capacity);
223+
let mut new_capacity;
224224
if let Some(last_chunk) = chunks.last_mut() {
225225
let used_bytes = self.ptr.get() as usize - last_chunk.start() as usize;
226-
let currently_used_cap = used_bytes / mem::size_of::<T>();
227-
last_chunk.entries = currently_used_cap;
228-
if last_chunk.storage.reserve_in_place(currently_used_cap, n) {
229-
self.end.set(last_chunk.end());
230-
return;
231-
} else {
232-
// If the previous chunk's capacity is less than HUGE_PAGE
233-
// bytes, then this chunk will be least double the previous
234-
// chunk's size.
235-
new_capacity = last_chunk.storage.capacity();
236-
if new_capacity < HUGE_PAGE / elem_size {
237-
new_capacity = new_capacity.checked_mul(2).unwrap();
238-
}
226+
last_chunk.entries = used_bytes / mem::size_of::<T>();
227+
228+
// If the previous chunk's capacity is less than HUGE_PAGE
229+
// bytes, then this chunk will be least double the previous
230+
// chunk's size.
231+
new_capacity = last_chunk.storage.capacity();
232+
if new_capacity < HUGE_PAGE / elem_size {
233+
new_capacity = new_capacity.checked_mul(2).unwrap();
239234
}
240235
} else {
241236
new_capacity = PAGE / elem_size;
242237
}
243238
// Also ensure that this chunk can fit `n`.
244239
new_capacity = cmp::max(n, new_capacity);
245240

246-
chunk = TypedArenaChunk::<T>::new(new_capacity);
241+
let chunk = TypedArenaChunk::<T>::new(new_capacity);
247242
self.ptr.set(chunk.start());
248243
self.end.set(chunk.end());
249244
chunks.push(chunk);
@@ -350,28 +345,25 @@ impl DroplessArena {
350345
fn grow(&self, needed_bytes: usize) {
351346
unsafe {
352347
let mut chunks = self.chunks.borrow_mut();
353-
let (chunk, mut new_capacity);
348+
let mut new_capacity;
354349
if let Some(last_chunk) = chunks.last_mut() {
355-
let used_bytes = self.ptr.get() as usize - last_chunk.start() as usize;
356-
if last_chunk.storage.reserve_in_place(used_bytes, needed_bytes) {
357-
self.end.set(last_chunk.end());
358-
return;
359-
} else {
360-
// If the previous chunk's capacity is less than HUGE_PAGE
361-
// bytes, then this chunk will be least double the previous
362-
// chunk's size.
363-
new_capacity = last_chunk.storage.capacity();
364-
if new_capacity < HUGE_PAGE {
365-
new_capacity = new_capacity.checked_mul(2).unwrap();
366-
}
350+
// There is no need to update `last_chunk.entries` because that
351+
// field isn't used by `DroplessArena`.
352+
353+
// If the previous chunk's capacity is less than HUGE_PAGE
354+
// bytes, then this chunk will be least double the previous
355+
// chunk's size.
356+
new_capacity = last_chunk.storage.capacity();
357+
if new_capacity < HUGE_PAGE {
358+
new_capacity = new_capacity.checked_mul(2).unwrap();
367359
}
368360
} else {
369361
new_capacity = PAGE;
370362
}
371363
// Also ensure that this chunk can fit `needed_bytes`.
372364
new_capacity = cmp::max(needed_bytes, new_capacity);
373365

374-
chunk = TypedArenaChunk::<u8>::new(new_capacity);
366+
let chunk = TypedArenaChunk::<u8>::new(new_capacity);
375367
self.ptr.set(chunk.start());
376368
self.end.set(chunk.end());
377369
chunks.push(chunk);

0 commit comments

Comments
 (0)