> On Sep 6, 2017, at 1:06 PM, Taylor Swift <[email protected]> wrote: > > > > On Wed, Sep 6, 2017 at 12:41 PM, Joe Groff via swift-evolution > <[email protected]> wrote: > > Currently, memory is deallocated by an instance method on > > UnsafeMutablePointer, deallocate(count:). Like much of the Swift pointer > > API, performing this operation on a buffer pointer requires extracting > > baseAddress! and count. It is very common for the allocation code above to > > be immediately followed by: > > > > defer > > > > { > > buffer. > > baseAddress?.deallocate(capacity: buffer.count > > ) > > } > > > > This method is extremely problematic because nearly all users, on first > > seeing the signature of deallocate(capacity:), will naturally conclude from > > the capacity label that deallocate(capacity:) is equivalent to some kind of > > realloc()that can only shrink the buffer. However this is not the actual > > behavior — deallocate(capacity:) actually ignores the capacity argument and > > just calls free() on self. The current API is not only awkward and > > suboptimal, it is misleading. You can write perfectly legal Swift code that > > shouldn’t segfault, but still can, for example > > > > var ptr = UnsafeMutablePointer<UInt8>.allocate(capacity: 1000000 > > ) > > ptr. > > initialize(to: 13, count: 1000000 > > ) > > ptr. > > deallocate(capacity: 500000) // deallocate the second half of the memory > > block > > ptr[0] // segmentation fault > > where the first 500000 addresses should still be valid if the documentation > > is to be read literally. > > The fact that the Swift runtime currently uses malloc/free is an > implementation detail. Tracking deallocation size is a very useful > optimization for better allocator backends, and C++ underwent an ABI break to > make it so that sized delete can be supported. Maybe we can change the name > to `deallocate(allocatedCapacity:)` to make it clear that it isn't resizing > the memory, and/or make the capacity argument optional so that you can pay > for the overhead of the allocator deriving the size if it's inconvenient for > the calling code to carry the size around, but we shouldn't remove the > functionality altogether. > > -Joe > _______________________________________________ > swift-evolution mailing list > [email protected] > https://lists.swift.org/mailman/listinfo/swift-evolution > > The idea is to get the house in order by removing all parameters from > deallocate(), since that’s what it really does right now. Then, in the > future, if Swift gets a more sophisticated allocator backend, a new method > like deallocate(capacity:) or reallocate(toCapacity:) could be added without > conflicting with the currently named deallocate(capacity:). However, using > the function signature to pretend that it does something it can’t actually do > right now is extremely dangerous.
I don't think that's a good idea in this case, because it's not unlikely we would explore an optimized allocator soon after ABI stability, and retrofitting these interfaces in a future version of Swift would put a deployment target limit on when they can be used, and mean that a lot of user code would need to be retrofitted to carry allocated capacities where needed to see any benefit. -Joe _______________________________________________ swift-evolution mailing list [email protected] https://lists.swift.org/mailman/listinfo/swift-evolution
