Skip to content

The Mojave Core Foundation merge. #1708

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 12 commits into from
Oct 10, 2018
Merged

The Mojave Core Foundation merge. #1708

merged 12 commits into from
Oct 10, 2018

Conversation

millenomi
Copy link
Contributor

Welcome to macOS Mojave and iOS 12. This patch merges improvements from the Core Foundation version found in these operating systems into Swift Foundation.

For more information on changes to clients of Core Foundation on these operating systems, see the Foundation release notes. In particular, macros for closed enumerations and CFMessagePort improvements apply to this codebase as well.

The changes in this merge mostly revolve around performance improvements. For example, type IDs are now constants and we can lay out constant objects' memory directly into CF instead of requiring dispatch_onces and allocations in __CFInitialize. We also audited which symbols are exported, picked more specific kinds of locks to improve performance in some situations, and improved the correctness of some code (e.g. CFURLComponents parsing; ensuring subclasses of NSData that override copy interact correctly with CFDataCreateCopy). Finally, we bring headers to closer parity with the macOS and iOS ones.

@millenomi
Copy link
Contributor Author

@swift-ci please test

@millenomi
Copy link
Contributor Author

If you're working on a port of Swift, or on ABI stability, I'd highly recommend you read the patch. In particular, @compnerd, @johnno1962, @Kaiede, @tinysun212 (for the Cygwin parts), @mikeash, would you like to take a look at this?


static bool __CFLocaleGetMeasurementSystemForPreferences(CFTypeRef metricPref, CFTypeRef measurementPref, UMeasurementSystem *outMeasurementSystem) {
if (metricPref || measurementPref) {
if (metricPref == kCFBooleanTrue && measurementPref && CFEqual(measurementPref, _measurementUnitsInches)) {
#if U_ICU_VERSION_MAJOR_NUM >= 55
Copy link
Contributor

Choose a reason for hiding this comment

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

Will removing this check break Ubuntu14 builds which I think only has version 52?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good catch.

@millenomi
Copy link
Contributor Author

@swift-ci please test

@@ -564,13 +572,13 @@ CF_EXPORT void _CFGetUGIDs(uid_t *euid, gid_t *egid) {
__CFGetUGIDs(euid, egid);
}

CF_EXPORT uid_t _CFGetEUID(void) {
CF_EXPORT uid_t _CFGetEUID() {
Copy link
Contributor

Choose a reason for hiding this comment

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

Should we have lost the void here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Nope. To fix.

@@ -1,7 +1,7 @@


# This is specific to Swift open source; Foundation's NSCFConstantString is used as our constant string class reference
__TMC15SwiftFoundation19_NSCFConstantString ___CFConstantStringClassReference
_$s15SwiftFoundation19_NSCFConstantStringCN ___CFConstantStringClassReference
Copy link
Contributor

Choose a reason for hiding this comment

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

Just a note here to double check this vs recent discussions about the mangling changing.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yup; it's using $s, which is the new prefix. (The other class names in the source have been updated accordingly as well.)


__CFDataSetNumBytesUsed(memory, 0);
__CFDataSetLength(memory, 0);
__CFDataSetDontDeallocate(memory, isDontDeallocate);
__CFDataSetDontDeallocate(memory, true);
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 this is reverting an earlier change

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yup. To fix.

@@ -460,7 +460,7 @@ CFDataRef CFDataCreateCopy(CFAllocatorRef allocator, CFDataRef data) {
Boolean allowRetain = true;
if (allowRetain) {
CF_OBJC_FUNCDISPATCHV(CFDataGetTypeID(), CFDataRef, (NSData *)data, copy);
CF_SWIFT_FUNCDISPATCHV(CFDataGetTypeID(), CFDataRef, (CFSwiftRef)data, NSObject.copyWithZone, NULL);
CF_SWIFT_FUNCDISPATCHV(CFDataGetTypeID(), CFDataRef, (CFSwiftRef)data, NSData.copy);
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 this may also be reverting an earlier change. Not sure.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

There was at least one test failing because a NSData subclass overrode copy() instead of copy(with:).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

(This brings it into consistency with ObjC, just above.)

@@ -242,7 +245,7 @@ static inline void __CFStorageSetChild(CFStorageNode *parentNode, CFIndex childI
*((void **)&parentNode->info.notLeaf.child[childIndex]) = newChild;
}

static inline void __CFStorageGetChildren(const CFStorageNode *parent, CFStorageNode ** _CF_RESTRICT resultArray, bool shouldRetain, bool shouldFreeze) {
static inline void __CFStorageGetChildren(const CFStorageNode *parent, CFStorageNode ** restrict resultArray, bool shouldRetain, bool shouldFreeze) {
Copy link
Contributor

Choose a reason for hiding this comment

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

This was recently added for C++ support so we need to use the macro.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I will make sure all mentions remain in the codebase.

@@ -696,50 +701,6 @@ static void __InitTZStrings(void) {
}
__CFUnlock(&__CFTZDirLock);
}

#elif DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED
Copy link
Contributor

Choose a reason for hiding this comment

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

We sure it's correct to remove this?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Tests pass, and it matches the original.

@@ -813,15 +769,6 @@ static CFTimeZoneRef __CFTimeZoneCreateSystem(void) {
CFRelease(name);
if (result) return result;
}
#if DEPLOYMENT_TARGET_ANDROID
Copy link
Contributor

Choose a reason for hiding this comment

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

I suspect most of the changes in CFTimeZone.c should probably prefer the SCL-F version.

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. This bit absolutely needs to be preserved.

void *_CFReallocf(void *ptr, size_t size) {
#if DEPLOYMENT_TARGET_WINDOWS | DEPLOYMENT_TARGET_LINUX
CF_CROSS_PLATFORM_EXPORT void *_CFReallocf(void *ptr, size_t size) {
#if TARGET_OS_WIN32 | DEPLOYMENT_TARGET_LINUX
Copy link
Contributor

Choose a reason for hiding this comment

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

Err... should be ||

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good catch.

@@ -52,8 +52,6 @@ enum {

#define __checkint_int64_mul(x, y, err) (x * y)
#define __checkint_uint64_add(x, y, err) (x + y)
#define __checkint_int32_mul(x,y,err) (x * y)
Copy link
Contributor

Choose a reason for hiding this comment

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

Hi, while this is not required on 64bits platforms it should still be on arm32 and x86 (committed by me with #1396).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'll fix it!

// On systems where we have ObjC support (DEPLOYMENT_RUNTIME_OBJC), STATIC_CLASS_REF(…) can statically produce a reference to the ObjC class symbol that ties into this particular type.
// When compiling for Swift Foundation, STATIC_CLASS_REF returns a Swift class. There's a mapping of ObjC name classes to Swift symbols in the header that defines it that should be kept up to date if more constant objects are defined.
// On all other platforms, it returns NULL, which is okay; we only need the type ID if CF is to be used by itself.
#if __LP64__
Copy link
Contributor

Choose a reason for hiding this comment

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

This set of macros is a little weird for a couple reasons:

It is using a ULL in the 32-bit portion.

It assumes that Darwin and non-Darwin both use effectively “unsigned” as the cfinfoa type. Probably not fatal, but confusing to read.

Also curious why this was added here rather than where the other initialization macros are, and why do we need another set?

Out of curiosity, does anyone know if _CFInfo is only used on Linux (non-ObjC) targets? Seems like it is?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

_cfinfoa is used on all targets. Its bits correspond to the ObjC object flag word semantics (please, runtime people, correct me if I'm wrong?), and it is used to store the refcount in ObjC and standalone (non-Swift) builds.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

A few more points:

  • This set of macros is used for constant objects — it prevents us from having to do initialization of their fields at __CFInitialize time, which is processing time that does add up on Darwin or in the case of processes that potentially restart often (say, server-side).

  • _CFInfo is a bitfield on all platforms and it doesn't make sense for it to be signed.

Copy link
Contributor

Choose a reason for hiding this comment

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

Okay, so these macros add more parameters that INIT_CFRUNTIME_BASE in CFRuntime.h doesn't. That's fine. It's just a little hard to compare the two sets of macros that do incredibly similar things because they are in different files. But since this is for internal, I guess that's the point.

My comment about _cfinfoa is more that on 32-bit, you've got a ULL (64-bit) instead of a UL (32-bit) const.

As for _CFInfo, I bring it up because it's padded to 64-bits, at least on Linux, which makes macros like this... interesting.

#define CFAssert1(cond, prio, desc, a1) do { if (!(cond)) { CFLog(prio, CFSTR(desc), a1); /* HALT; */ } } while (0)
#define CFAssert2(cond, prio, desc, a1, a2) do { if (!(cond)) { CFLog(prio, CFSTR(desc), a1, a2); /* HALT; */ } } while (0)
#define CFAssert3(cond, prio, desc, a1, a2, a3) do { if (!(cond)) { CFLog(prio, CFSTR(desc), a1, a2, a3); /* HALT; */ } } while (0)
#define CFAssert4(cond, prio, desc, a1, a2, a3, a4) do { if (!(cond)) { CFLog(prio, CFSTR(desc), a1, a2, a3, a4); /* HALT; */ } } while (0)
Copy link
Contributor

Choose a reason for hiding this comment

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

What's the reason for making these not halt anymore? Seems like they ought to since these are for debug builds.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'll research, and I'll uncomment if the reason doesn't apply to SCF.

@@ -52,8 +52,6 @@ enum {

#define __checkint_int64_mul(x, y, err) (x * y)
#define __checkint_uint64_add(x, y, err) (x + y)
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm sure these are only used in circumstances where it's fine, but the lack of parentheses around x and y makes me really paranoid.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I hear you; this needs a follow-up, I assume.

#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_EMBEDDED || DEPLOYMENT_TARGET_EMBEDDED_MINI
return pthread_getname_np(pthread_self(), buf, length);
#elif DEPLOYMENT_TARGET_ANDROID
Copy link
Contributor

Choose a reason for hiding this comment

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

is this a regression for Android?

@@ -997,15 +1042,6 @@ static struct {
{"CFNumberDisableCache", NULL},
{"__CFPREFERENCES_AVOID_DAEMON", NULL},
{"APPLE_FRAMEWORKS_ROOT", NULL},
#if DEPLOYMENT_RUNTIME_SWIFT
Copy link
Contributor

Choose a reason for hiding this comment

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

this looks like a regression for XDG

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yep, that's incorrect.

// CFRuntime_Internal.h
// CoreFoundation
//
// Created by Tony Parker on 4/21/18.
Copy link
Contributor

Choose a reason for hiding this comment

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

this should have an updated copyright header

Copy link
Contributor Author

Choose a reason for hiding this comment

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

ACK

@millenomi
Copy link
Contributor Author

@swift-ci please test.

@millenomi
Copy link
Contributor Author

@swift-ci please test macOS

@millenomi
Copy link
Contributor Author

@shahmishal (is swift-ci working? it has responded only once to commands on this patch).

@shahmishal
Copy link
Member

@swift-ci please test

@millenomi
Copy link
Contributor Author

This will be merged Monday morning, if nothing else pops up in the meanwhile.

@millenomi
Copy link
Contributor Author

I'm going to ask swift-ci to test and merge around 10.15 PST today.

@millenomi
Copy link
Contributor Author

@swift-ci please test and merge

@millenomi
Copy link
Contributor Author

@swift-ci please test and merge

@millenomi
Copy link
Contributor Author

Seems like an upstream issue.

@millenomi
Copy link
Contributor Author

@swift-ci please test and merge

@millenomi
Copy link
Contributor Author

@swift-ci test and merge

@millenomi
Copy link
Contributor Author

https://bugs.swift.org/browse/SR-8899 has been filed to track the blocker.

@millenomi
Copy link
Contributor Author

millenomi commented Oct 3, 2018

  • Uses bool instead of _Bool to match the API surface in Core Foundation

  • You may notice we are moving some DEPLOYMENT_TARGET_* flags to TARGET_OS_*. In general, we will strongly prefer TARGET_OS_* going forward wherever possible. (DEPLOYMENT_RUNTIME_SWIFT and DEPLOYMENT_RUNTIME_OBJC remain.)

  • Changing some extern function(); to extern function(void); was premature for subtle source compatibility reasons.

@millenomi
Copy link
Contributor Author

(on the off chance these changes actually happen to not trigger the blocker anymore.)

@millenomi
Copy link
Contributor Author

@swift-ci please test

@millenomi
Copy link
Contributor Author

Turns out: no.

…ilding SCF on iOS, it’s equivalent to TARGET_OS_MAC for Swift.
@millenomi
Copy link
Contributor Author

@swift-ci please test and merge

@@ -1517,7 +1524,7 @@ static UDate __CFDateFormatterCorrectTimeToARangeAroundCurrentDate(UCalendar *ca
}
} else {
if (period < INT_MAX && futureMax > period) {
futureRange.location = 1;
futureRange.location = 1,
Copy link
Contributor

Choose a reason for hiding this comment

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

Is this correct?

The comma operator will discard the first operand (1) and evaluate the second operator. Both futureRange.location and futureRange.length will end up having the same value futureMax - period.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Oh. This must've reverted a fix inadvertently.

Copy link
Contributor

Choose a reason for hiding this comment

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

Just for the record, in case it's somehow relevant in the future, the comma operator has a lower precedence than the assignment operator so this code does work as expected with the comma, although it's definitely weird. It's equivalent to (futureRange.location = 1), (futureRange.length = futureMax - period);. This very occasionally has a practical use in for loops, where you can use it to do multiple assignments in the increment section of the for(), but mostly this tidbit is only useful for making strange code.

@@ -1138,3 +1138,7 @@ extension NSData : _StructTypeBridgeable {
return Data._unconditionallyBridgeFromObjectiveC(self)
}
}

internal func _CFSwiftDataCreateCopy(_ data: AnyObject) -> Unmanaged<AnyObject> {
return Unmanaged<AnyObject>.passRetained((data as! NSDictionary).copy() as! NSObject)
Copy link
Contributor

Choose a reason for hiding this comment

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

I don’t think as! NSDictionary is correct. Shouldn’t it be as! NSData?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

A copy-and-paste error. I postponed adding tests due to the size, but this may merit one. Thanks!

@millenomi
Copy link
Contributor Author

@swift-ci please test


#if TARGET_OS_WIN32
// No C99 support
#define _CF_RESTRICT
Copy link
Member

Choose a reason for hiding this comment

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

We should conditional this over #if defined(_MSC_VER) && !defined(__clang__)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I’ll write a follow-up bug to do it tomorrow.

@millenomi
Copy link
Contributor Author

@swift-ci please test

1 similar comment
@millenomi
Copy link
Contributor Author

@swift-ci please test

@millenomi
Copy link
Contributor Author

@swift-ci please test and merge

@swift-ci swift-ci merged commit 05b5a05 into swiftlang:master Oct 10, 2018
3405691582 added a commit to 3405691582/swift-corelibs-foundation that referenced this pull request May 11, 2020
but this was removed in swiftlang#1708. After interpreting the commit, this looks
like it was renamed to _kCFRuntimeIDCFAllocator.  Therefore, make this
rename again.
3405691582 added a commit to 3405691582/swift-corelibs-foundation that referenced this pull request May 11, 2020
PR swiftlang#2786 references symbol __kCFAllocatorTypeID_CONST in CFRuntime.c but
this was removed in swiftlang#1708. After interpreting the commit, it looks like
this symbol was renamed to _kCFRuntimeIDCFAllocator. Therefore, make
this rename again.
3405691582 added a commit to 3405691582/swift-corelibs-foundation that referenced this pull request May 11, 2020
PR swiftlang#2786 references symbol __kCFAllocatorTypeID_CONST in CFRuntime.c but
this was removed in swiftlang#1708. After interpreting the commit, it looks like
this symbol was renamed to _kCFRuntimeIDCFAllocator. Therefore, make
this rename again.
3405691582 added a commit to 3405691582/swift-corelibs-foundation that referenced this pull request May 11, 2020
PR swiftlang#2782 references symbol __kCFAllocatorTypeID_CONST in CFRuntime.c but
this was removed in swiftlang#1708. After interpreting the commit, it looks like
this symbol was renamed to _kCFRuntimeIDCFAllocator. Therefore, make
this rename again.
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.