> 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

Reply via email to