Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Behavior of zero-sized allocations is insufficiently specified #111

Open
CAD97 opened this issue Feb 28, 2023 · 2 comments
Open

Behavior of zero-sized allocations is insufficiently specified #111

CAD97 opened this issue Feb 28, 2023 · 2 comments

Comments

@CAD97
Copy link

CAD97 commented Feb 28, 2023

GlobalAlloc sidesteps the issue by making it the caller's problem and forbidding zero-sized allocations. Allocator makes it the job of the allocator to accept a zero-sized allocation request.

  • Are Allocators allowed to fail to allocate zero-sized allocations?
  • Are Allocators allowed to do a real memory block allocation for zero-sized allocations?

If either of these are true, we might end up where it's still considered good practice to not do an "actual" allocation for zero-sized allocations, and have a special case to use Layout::dangling in the caller instead. For the former, to avoid unnecessary allocation requirements/failures; for the latter, to avoid unnecessary allocation pressure.

The latter condition also carries an additional potential pitfall, in that deallocating a zero-sized allocation multiple times, or an allocation not made in this allocator, would be potential UB. This UB is unlikely to be caught with miri and the default global allocator; the current UCG leaning is to always allow all ZST accesses, irrespective of provenance, even after deallocation, and Global uses Layout::dangling to service zero-sized allocations (and does nothing for deallocation).

I personally think that we should just require zero-sized allocation requests to always succeed, and for zero-sized deallocation to be idempotent. However, if the ultimate decision of ucg#93 is that ZST accesses to deallocated provenance are invalid, then it might make sense to extend that flexibility to Allocator implementations to do actual work for zero-sized allocations (but still encourage zero-sized allocation to just be Layout::dangling/fake_alloc equivalent).

Either way, this should be spelled out more clearly in the documentation.

@zakarumych
Copy link

By reading documentation I can conclude that right now

Are Allocators allowed to fail to allocate zero-sized allocations?

Yes, since allocators are allowed to fail whenever they feel like it.

Are Allocators allowed to do a real memory block allocation for zero-sized allocations?

Yes and they can even return non-zero memory slice from allocate method.

@Amanieu
Copy link
Member

Amanieu commented Feb 28, 2023

  • Are Allocators allowed to fail to allocate zero-sized allocations?

  • Are Allocators allowed to do a real memory block allocation for zero-sized allocations?

Yes to both. The only requirement is that dealloc must accept an allocation returned by alloc.

If either of these are true, we might end up where it's still considered good practice to not do an "actual" allocation for zero-sized allocations, and have a special case to use Layout::dangling in the caller instead. For the former, to avoid unnecessary allocation requirements/failures; for the latter, to avoid unnecessary allocation pressure.

The rule of thumb is essentially:

  • If the layout is known at compile-time then sure, skip the the allocator and always return Layout::dangling.
  • If the layout is not known at compile-time then pass it on to the allocator. It is up to the allocator to decide whether it should special case ZST allocations.

For an example where this is relevant, consider a bump-pointer allocator such as bumpalo: it is faster to just bump the pointer by 0 bytes than to add a check for whether the layout is a ZST.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants