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
free 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.
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.
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?