> On Oct 17, 2016, at 12:01 PM, Michael Gottesman <mgottes...@apple.com> wrote:
> 
> 
>> On Oct 17, 2016, at 11:53 AM, Michael Gottesman via swift-dev 
>> <swift-dev@swift.org <mailto:swift-dev@swift.org>> wrote:
>> 
>> 
>>> On Oct 17, 2016, at 10:00 AM, Joe Groff <jgr...@apple.com 
>>> <mailto:jgr...@apple.com>> wrote:
>>> 
>>> 
>>>> On Oct 17, 2016, at 9:57 AM, Michael Gottesman <mgottes...@apple.com 
>>>> <mailto:mgottes...@apple.com>> wrote:
>>>> 
>>>> 
>>>>> On Oct 17, 2016, at 9:42 AM, Joe Groff via swift-dev <swift-dev@swift.org 
>>>>> <mailto:swift-dev@swift.org>> wrote:
>>>>> 
>>>>> 
>>>>>> On Oct 16, 2016, at 1:10 PM, Dave Abrahams via swift-dev 
>>>>>> <swift-dev@swift.org <mailto:swift-dev@swift.org>> wrote:
>>>>>> 
>>>>>> 
>>>>>> on Thu Oct 13 2016, Joe Groff <swift-dev-AT-swift.org 
>>>>>> <http://swift-dev-at-swift.org/>> wrote:
>>>>>> 
>>>>>>>> On Oct 13, 2016, at 1:18 PM, Greg Parker <gpar...@apple.com 
>>>>>>>> <mailto:gpar...@apple.com>> wrote:
>>>>>>>> 
>>>>>>>> 
>>>>>>>>> On Oct 13, 2016, at 10:46 AM, John McCall via swift-dev 
>>>>>>>>> <swift-dev@swift.org <mailto:swift-dev@swift.org>> wrote:
>>>>>>>>> 
>>>>>>> 
>>>>>>>>>> On Oct 13, 2016, at 9:04 AM, Joe Groff via swift-dev 
>>>>>>>>>> <swift-dev@swift.org <mailto:swift-dev@swift.org>> wrote:
>>>>>>>>>> 
>>>>>>>>>>> On Mar 1, 2016, at 1:33 PM, Joe Groff via swift-dev 
>>>>>>>>>>> <swift-dev@swift.org <mailto:swift-dev@swift.org>> wrote:
>>>>>>>>>>> 
>>>>>>>>>>> In swift_retain/release, we have an early-exit check to pass
>>>>>>>>>>> through a nil pointer. Since we're already burning branch, I'm
>>>>>>>>>>> thinking we could pass through not only zero but negative pointer
>>>>>>>>>>> values too on 64-bit systems, since negative pointers are never
>>>>>>>>>>> valid userspace pointers on our 64-bit targets. This would give
>>>>>>>>>>> us room for tagged-pointer-like optimizations, for instance to
>>>>>>>>>>> avoid allocations for tiny closure contexts.
>>>>>>>>>> 
>>>>>>>>>> I'd like to resurrect this thread as we look to locking down the
>>>>>>>>>> ABI. There were portability concerns about doing this unilaterally
>>>>>>>>>> for all 64-bit targets, but AFAICT it should be safe for x86-64
>>>>>>>>>> and Apple AArch64 targets. The x86-64 ABI limits the userland
>>>>>>>>>> address space, per section 3.3.2:
>>>>>>>>>> 
>>>>>>>>>> Although the AMD64 architecture uses 64-bit pointers,
>>>>>>>>>> implementations are only required to handle 48-bit
>>>>>>>>>> addresses. Therefore, conforming processes may only use addresses
>>>>>>>>>> from 0x00000000 00000000 to 0x00007fff ffffffff.
>>>>>>>>>> 
>>>>>>>>>> Apple's ARM64 platforms always enable the top-byte-ignore
>>>>>>>>>> architectural feature, restricting the available address space to
>>>>>>>>>> the low 56 bits of the full 64-bit address space in
>>>>>>>>>> practice. Therefore, "negative" values should never be valid
>>>>>>>>>> user-space references to Swift-refcountable objects. Taking
>>>>>>>>>> advantage of this fact would enable us to optimize small closure
>>>>>>>>>> contexts, Error objects, and, if we move to a reference-counted
>>>>>>>>>> COW model for existentials, small `Any` values, which need to be
>>>>>>>>>> refcountable for ABI reasons but don't semantically promise a
>>>>>>>>>> unique identity like class instances do.
>>>>>>>>> 
>>>>>>>>> This makes sense to me.  if (x <= 0) return; should be just as cheap 
>>>>>>>>> as is (x == 0) return;
>>>>>>>> 
>>>>>>>> Conversely, I wanted to try to remove such nil checks. Currently
>>>>>>>> they look haphazard: some functions have them and some do not.
>>>>>>>> 
>>>>>>>> Allowing ABI space for tagged pointer objects is a much bigger
>>>>>>>> problem than the check in swift_retain/release. For example, all
>>>>>>>> vtable and witness table dispatch sites to AnyObject or any other
>>>>>>>> type that might someday have a tagged pointer subclass would need to
>>>>>>>> compile in a fallback path now. You can't dereference a tagged
>>>>>>>> pointer to get its class pointer.
>>>>>>> 
>>>>>>> True. I don't think we'd want to use this optimization for class
>>>>>>> types; I was specifically thinking of other things for which we use
>>>>>>> nullable refcounted representations, particularly closure
>>>>>>> contexts. The ABI for function types requires the context to be
>>>>>>> refcountable by swift_retain/release, but it doesn't necessarily have
>>>>>>> to be a valid pointer, if the closure formation site and invocation
>>>>>>> function agree on a tagged-pointer representation. 
>>>>>> 
>>>>>> Well, but we'd like to take advantage of the same kind of optimization
>>>>>> for the small string optimization.  It doesn't seem like this should be
>>>>>> handled differently just because the string buffer is a class instance
>>>>>> and not a closure context.
>>>>> 
>>>>> String is a struct, and small strings don't have to be modeled as class 
>>>>> instances. An enum { case Big(StringStorage), Small(Int63) } or similar 
>>>>> layout should be able to take advantage of swift_retain/release ignoring 
>>>>> negative values too.
>>>> 
>>>> I need to catch up on this thread, but there is an important thing to 
>>>> remember. If you use an enum like this there are a few potential issues:
>>>> 
>>>> 1. In the implementation, you will /not/ want to use the enum internally. 
>>>> This would prevent the optimizer from eliminating all of the Small Case 
>>>> reference counting operations. This means you would rewrap the internal 
>>>> value when you return one and when you enter into an internal 
>>>> implementation code path try to immediately switch to a specialized small 
>>>> case path if you can.
>>>> 2. {Retain,Release}Values will be created outside. We are talking about 
>>>> some ways of fixing this from a code-size perspective by using a value 
>>>> witness, but in the present this may cause additional code-size increase.
>>> 
>>> This is exactly the case that would be improved, since retain/release_value 
>>> on such an enum would boil down to a single swift_retain/release call if 
>>> the runtime functions ignored the tagged small case values.
>> 
>> I am saying something stronger. What I am saying is that, you could have 0 
>> retain/release operations on the SmallString path.
> 
> Let me elaborate a little bit, and then I am going to drop my point here 
> since as Joe pointed out to me offlist, this is orthogonal to the ABI 
> discussion.
> 
> What I am trying to say is that the optimizer will eliminate all retain, 
> release operations on trivial values. Any code path which uses the top level 
> enum can not take advantage of this property since the top level enum /could/ 
> have the BigString contained in it. So what you want to do to get rid of the 
> most retain/release operations is to move the enum switch to the entrances of 
> the API so that one has the largest region of code where the optimizer can 
> clearly see that it has a small string.
> 
> Now we /could/ specialize on enum cases. I will file a radar for this.

rdar://28805035

> 
> Michael
> 
>> 
>>> 
>>> -Joe
>>> 
>>>> 
>>>> 
>>>>> 
>>>>> -Joe
>>>>> 
>>>>>>> We could also do interesting things with enums; if one payload type is
>>>>>>> a class reference and the rest are trivial, we could lay the enum out
>>>>>>> in such a way that we can use swift_retain/release on it by setting
>>>>>>> the high bit when tagging the trivial representations, saving us the
>>>>>>> need to emit a switch. We wouldn't actually dereference the pointer
>>>>>>> representation without checking it first.
>>>>>>> 
>>>>>>> I know we've discussed taking the nil check out of
>>>>>>> swift_retain/release, and possibly having separate variants that do
>>>>>>> include the null check for when we know we're working with
>>>>>>> Optionals. How much of difference would that really make, though? I'd
>>>>>>> expect it to be a fairly easily predictable branch, since most objects
>>>>>>> are likely to be nonnull in practice.
>>>>>>> 
>>>>>>> -Joe
>>>>>>> _______________________________________________
>>>>>>> swift-dev mailing list
>>>>>>> swift-dev@swift.org <mailto:swift-dev@swift.org>
>>>>>>> https://lists.swift.org/mailman/listinfo/swift-dev 
>>>>>>> <https://lists.swift.org/mailman/listinfo/swift-dev>
>>>>>> 
>>>>>> -- 
>>>>>> -Dave
>>>>>> 
>>>>>> _______________________________________________
>>>>>> swift-dev mailing list
>>>>>> swift-dev@swift.org <mailto:swift-dev@swift.org>
>>>>>> https://lists.swift.org/mailman/listinfo/swift-dev 
>>>>>> <https://lists.swift.org/mailman/listinfo/swift-dev>
>>>>> 
>>>>> _______________________________________________
>>>>> swift-dev mailing list
>>>>> swift-dev@swift.org <mailto:swift-dev@swift.org>
>>>>> https://lists.swift.org/mailman/listinfo/swift-dev 
>>>>> <https://lists.swift.org/mailman/listinfo/swift-dev>
>>>> 
>>> 
>> 
>> _______________________________________________
>> swift-dev mailing list
>> swift-dev@swift.org <mailto:swift-dev@swift.org>
>> https://lists.swift.org/mailman/listinfo/swift-dev
> 

_______________________________________________
swift-dev mailing list
swift-dev@swift.org
https://lists.swift.org/mailman/listinfo/swift-dev

Reply via email to