> On May 22, 2017, at 6:07 AM, Ben Rimmington <[email protected]> wrote:
> 
> 
>> On 20 May 2017, at 19:58, Philippe Hausler wrote:
>> 
>>> On May 20, 2017, at 12:25 AM, David Waite wrote:
>>> 
>>> I believe behavior depends on whether the NSNumber is the objc type or 
>>> swift subtype, and whether you call the NSNumber.intValue or use 
>>> Int.init?(exactly: NSNumber).
>> 
>> That part of the behavior is no longer the case. The bridge only transacts 
>> upon one number type (to leverage tagged pointers) and the subclass was 
>> removed (since it caused some gnarly inconsistencies)
> 
> The subclass `_SwiftTypePreservingNSNumber` still exists:
> 
> <https://github.com/apple/swift/blob/master/stdlib/public/SDK/Foundation/TypePreservingNSNumber.mm>

Hmm it shouldn’t, that looks like an oversight on my part if it is still alive.

> 
> Maybe the file isn't compiled anymore due to your pull requests:
> 
> <https://github.com/apple/swift/pull/9162>
> <https://github.com/apple/swift/pull/9293>

Correct. it should no longer be used (hopefully it isn’t bloating binaries with 
un-used code). I will look into this here shortly.

> 
> You mentioned tagged pointers. My understanding is that:
> 
> * `OBJC_TAG_NSNumber` doesn't attempt to store a `float` or `double` in the 
> 60-bit payload;

Integral double or float values are stored (when they can be). So 42.0 will be 
stored, but 53.5 won’t be. All other storage types (modulo NSDecimals) will 
store as a tagged pointer if they can; NSNumber(value: Int32.max) on a 64 bit 
system will be tagged but NSNumber(value: UInt64.max) of course won’t be.

The most common floating point NSNumbers are 0.0, 1.0, -1.0, 10.0, 22.0, 0.5. 
But it is worth noting that since we can construct NSNumbers as cached values 
or even as addresses of static structures (see 
https://github.com/apple/swift-corelibs-foundation/blob/master/CoreFoundation/NumberDate.subproj/CFNumber.c#L377
 
<https://github.com/apple/swift-corelibs-foundation/blob/master/CoreFoundation/NumberDate.subproj/CFNumber.c#L377>)



> * `OBJC_TAG_NSDate` is used only if bits 0...3 of the `NSTimeInterval` (aka 
> `double`) are zero.

NSDates are stored as 56 bits in the tagged pointer. 

> 
> <https://opensource.apple.com/source/objc4/objc4-709/runtime/objc-internal.h.auto.html>
> 
> How often is an NSDate (with "sub-millisecond precision") created as a tagged 
> pointer?

Not very often at all really. The most common dates are usually integral values.

> 
> — Ben
> 

To further give a bit of insight on tagged NSNumbers; using those instead of 
allocating a new instance each time accounts for about 1% on average for 
property lists. So this wasn’t really just a consistency change alone, it was 
execution time as well as memory fragmentation improvement.

It is also worth noting that as the overall system usage changes over time we 
might change our layout of tagged pointers (for both NSDate and NSNumber). So 
don’t rely on them being a certain way ;)





_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to