Back to deallocate(capacity:) — advanced heap allocation

SE-0184 got rid of the capacity: argument that UnsafeMutablePointer.deallocate() once had. The intention was never for Swift’s final dynamic memory allocation model to be reduced to the mallocfree model, but rather pave the way for a more sophisticated dynamic allocation backend. Now that SE-0184 has shipped with Swift 4.1, we should start talking about what kinds of advanced allocation features we want to support.

Make deallocate() sized again

free() is a little faster and much easier to implement when it knows the size of the block to deallocate. Although it was always understood that deallocate(capacity:) was a superior design to deallocate(), SE-0184 removed it because Swift’s implementation was deceiving users in memory-unsafe ways and the implementation could not be fixed in a way that did not risk introducing extremely hard-to-isolate memory bugs into existing code.

A full release cycle later, with all users having been forced to audit and correct misuse of deallocate(capacity:) (by replacing it with the less-efficient but obviously harder to misuse deallocate()) I think it’s time to reintroduce deallocate(capacity:), this time, the right way.

reallocate(toCapacity:) ?

Good selection of free memory blocks increases the chances that a memory buffer can be extended without being moved, reducing the amount of data copying that needs to take place. Resizability also means blocks can be shrunk in-place. With the current API, a new block has to be allocated, the contents moved, and the old block deallocated to change the capacity of a buffer.

What does everyone think?

1 Like

What is the right way?

The implementation will deploy at the same time as the API. Code that supplies deallocate(capacity:) with bad parameters will cause instability as the allocator will actually use the argument, whereas it used to be that the parameter was ignored.