Skip to content

Cater for new Swift reference count representation #1525

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 20, 2018
Merged

Cater for new Swift reference count representation #1525

merged 1 commit into from
Apr 20, 2018

Conversation

johnno1962
Copy link
Contributor

@johnno1962 johnno1962 commented Apr 18, 2018

The representation of reference counts for 32 bit systems has changed swiftlang/swift@ae1c984 and needs to be adjusted in the matching structs in CoreFoundation (__CFRuntimeBase & __CFConstStr). Swift ivars now start at offset 8 bytes from self on 32 bit systems. Part of #1518

@parkera
Copy link
Contributor

parkera commented Apr 18, 2018

@gparker42 any comment on this one?

@@ -449,11 +449,13 @@ CF_EXPORT double kCFCoreFoundationVersionNumber;
#endif

#if __LLP64__
typedef uint32_t _CFSwiftRCCount;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This still doesn't belong in CFBase.h. It is for CFRuntime.h and CFString.h only, and I would prefer they just put the #ifdef directly.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The reason is that we're adding a new API and name here, and for all platforms - even those that don't use the Swift RC pattern.

Copy link
Contributor Author

@johnno1962 johnno1962 Apr 18, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Amended.

@gparker42
Copy link

A better placeholder for Swift's data would be a single uintptr_t on all architectures. The refcount storage is certainly not divided into two equal-size fields as described here; better to not tease the possibility of reading useful information from them.

uint32_t _swift_strong_rc;
uint32_t _swift_weak_rc;
_CFSwiftRCCount _swift_strong_rc;
_CFSwiftRCCount _swift_weak_rc;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So here I would write:

     uintptr_t _cfisa;
#if __LLP64__
    uint32_t _swift_strong_rc;
    uint32_t _swift_weak_rc;
#else
    int16_t _swift_strong_rc;
    int16_t _swift_weak_rc;
#endif
    _Atomic(uint64_t) _cfinfoa;

and so forth, for the others

@parkera
Copy link
Contributor

parkera commented Apr 18, 2018

@gparker42 thanks, even better

@johnno1962
Copy link
Contributor Author

How does it look now?

@millenomi
Copy link
Contributor

LGTM. @parkera?

let offTemp1 = MemoryLayout<OpaquePointer>.size + MemoryLayout<Int32>.size
let offTemp2 = MemoryLayout<Int32>.size + MemoryLayout<_CFInfo>.size
let offTemp1 = MemoryLayout<OpaquePointer>.size + MemoryLayout<uintptr_t>.size
let offset = offTemp1 + MemoryLayout<_CFInfo>.size
return offTemp1 + offTemp2 + MemoryLayout<UnsafePointer<UInt8>>.size

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't compile, does it?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, noticed that.. should be ok now

@@ -412,11 +412,11 @@ CF_EXPORT void *__CFConstantStringClassReference[];
#endif

#define CONST_STRING_DECL(S, V) \
const struct __CFConstStr __##S CONST_STRING_SECTION = {{(uintptr_t)&__CFConstantStringClassReference, _CF_CONSTANT_OBJECT_STRONG_RC, 0, 0x000007c8U}, (uint8_t *)(V), sizeof(V) - 1}; \
const struct __CFConstStr __##S CONST_STRING_SECTION = {{(uintptr_t)&__CFConstantStringClassReference, _CF_CONSTANT_OBJECT_STRONG_RC, 0x000007c8U}, (uint8_t *)(V), sizeof(V) - 1}; \

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you need to change the definition of _CF_CONSTANT_OBJECT_STRONG_RC? My guess is that the bits generated here will be wrong if you do not.

Copy link
Contributor Author

@johnno1962 johnno1962 Apr 18, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will work on little-endian only perhaps?

#if DEPLOYMENT_RUNTIME_SWIFT

#define _CF_SWIFT_RC_PINNED_FLAG 0x1
#define _CF_SWIFT_RC_FLAGS_COUNT 2
#define _CF_CONSTANT_OBJECT_STRONG_RC ((1 << _CF_SWIFT_RC_FLAGS_COUNT) | _CF_SWIFT_RC_PINNED_FLAG)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the point of splitting it into strong/weak here was so we could set that pinned flag. There may now be a better way.

Copy link
Contributor Author

@johnno1962 johnno1962 Apr 18, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Android tests run through ok. Are you saying separate them again so big-endian 64 bits works?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think you were setting the pinned flag correctly before. The pinned flag is the LSB of that uintptr_t on all platforms.

I don't think you are setting the refcount correctly now. The strong refcount is stored differently on 32-bit versus 64-bit, but on all platforms it is biased: a strong refcount of 1 is represented as bit value 0.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#define _CF_CONSTANT_OBJECT_STRONG_RC (_CF_SWIFT_RC_PINNED_FLAG) then?

@johnno1962
Copy link
Contributor Author

johnno1962 commented Apr 20, 2018

I’ve amended the commit and this is running on Android so should be good to go. Do you want to do a @swift-ci please test to check we’re on the right track?

@spevans
Copy link
Contributor

spevans commented Apr 20, 2018

@swift-ci please test

1 similar comment
@alblue
Copy link
Contributor

alblue commented Apr 20, 2018

@swift-ci please test

@parkera
Copy link
Contributor

parkera commented Apr 20, 2018

once @gparker42 approves (since it's his struct we are messing with) we are good to merge

@gparker42
Copy link

Looks good now.

@parkera
Copy link
Contributor

parkera commented Apr 20, 2018

Thanks!

@johnno1962
Copy link
Contributor Author

Looks like we’re done. Can someone push the merge button please and I can rebase the original PR?

@millenomi
Copy link
Contributor

@swift-ci please test and merge

@millenomi
Copy link
Contributor

(Ping me again if this doesn't merge in a timely fashion.)

@millenomi
Copy link
Contributor

Actually bypassing swift-ci since it's not starting.

@millenomi millenomi merged commit ac7f803 into swiftlang:master Apr 20, 2018
@johnno1962
Copy link
Contributor Author

Thanks @millenomi et all.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants