Skip to content

Clarifications on Allocator::grow #149

Description

@WorldSEnder

This is a reopen of #126. The author decided to close there on their own.

Should a consumer of Allocator::grow assume that a failure implies that a call to Allocator::allocate will also fail, and are allocators supposed to fallback to allocate()+memcpy()+free() when they can't grow the buffer? The following observations;

First, this is not necessarily related to grow_in_place. It is fine, on success, to invalidate previous pointers, e.g. by modifying the page table to "move" memory to a better suited location. The question is about behaviour on error.

The impl in RawVec does not try to allocate and copy when a call to grow fails, seemingly implying the behaviour of realloc.

When grow doesn't find sufficient space, every allocator implementation I have seen morally does the same thing:

    // as an aside, this is also done in the System impl when alignment differs
    let new_ptr = self.allocate(new_layout, zeroed)?;
    ptr::copy_nonoverlapping(ptr.as_ptr(), new_ptr.as_mut_ptr(), old_size);
    Allocator::deallocate(self, ptr, old_layout);

It seems, this is mostly an artifact from C's realloc, which always succeeds if memory is available. When reading the docs of Allocator, it's not clear if this is purposeful behaviour. As pointed out in #t-libs/wg-allocators > Optimizing copy on grow/shrink not all containers that could use the API need the (full) memory to be copied over, and some could perform better if the allocator would explicitly signal on failure to allocate new memory instead.

In any case, a resolution could be to just clarify the docs and declare that the allocator has to try and perform this memcpy - although I would find this suboptimal since no information is passed to the allocator how this memory is initialized (so worst case has to be assumed for the memcpy) and it is trivial to perform this part in the consuming container.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions