Skip to content

[5.1] Always give known-empty class properties a zero offset in the static layout. #22818

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

Conversation

rjmccall
Copy link
Contributor

Field offset vectors are always filled out with either zero or the static layout's offset, depending on the metadata initialization strategy. This change means that the static layout's offset will only be non-zero for properties with a statically-known layout. Existing runtimes doing dynamic class layout assign class properties a zero offset if the field offset vector entry is zero and the property is zero-sized. So this effectively brings the compiler into accord with the runtime (for all newly-compiled Swift code, which will eventually be all Swift code because the current public releases of Swift 5 are not yet considered ABI-stable) and guarantees a zero value for the offset everywhere.

Since the runtime will agree with the compiler about the zero value of the offset, the compiler can continue to emit such offset variables as constant. The exception to this rule is if the class has non-fragile ObjC ancestry, in which case the ObjC runtime (which is not aware of this special rule for empty fields) will attempt to slide it along with everything else.

Fixes rdar://48031465, in which the FixedClassMetadataBuilder for a class with a legacy-fixed layout was writing a non-zero offset for an empty field into the field offset vector, causing the runtime to not apply the special case and thus to compute a non-zero offset, which it then attempted to copy into the global field offset variable, which the compiler had emitted as a true-constant zero.

This is the 5.1 version of #22738.

@rjmccall
Copy link
Contributor Author

@swift-ci Please test.

@swift-ci
Copy link
Contributor

Build failed
Swift Test Linux Platform
Git Sha - 270808baff836b55b356b8f081585b43e2507a44

@swift-ci
Copy link
Contributor

Build failed
Swift Test OS X Platform
Git Sha - 270808baff836b55b356b8f081585b43e2507a44

…layout.

Field offset vectors are always filled out with either zero or the static layout's offset, depending on the metadata initialization strategy.  This change means that the static layout's offset will only be non-zero for properties with a statically-known layout.  Existing runtimes doing dynamic class layout assign class properties a zero offset if the field offset vector entry is zero and the property is zero-sized.  So this effectively brings the compiler into accord with the runtime (for all newly-compiled Swift code, which will eventually be all Swift code because the current public releases of Swift 5 are not yet considered ABI-stable) and guarantees a zero value for the offset everywhere.

Since the runtime will agree with the compiler about the zero value of the offset, the compiler can continue to emit such offset variables as constant.  The exception to this rule is if the class has non-fragile ObjC ancestry, in which case the ObjC runtime (which is not aware of this special rule for empty fields) will attempt to slide it along with everything else.

Fixes rdar://48031465, in which the `FixedClassMetadataBuilder` for a class with a legacy-fixed layout was writing a non-zero offset for an empty field into the field offset vector, causing the runtime to not apply the special case and thus to compute a non-zero offset, which it then attempted to copy into the global field offset variable, which the compiler had emitted as a true-constant zero.
@rjmccall rjmccall force-pushed the empty-field-offset-variables-5.1 branch from 270808b to e80da7b Compare February 26, 2019 20:58
@rjmccall
Copy link
Contributor Author

@swift-ci Please test.

@rjmccall rjmccall merged commit f53baf9 into swiftlang:swift-5.1-branch Feb 27, 2019
@rjmccall rjmccall deleted the empty-field-offset-variables-5.1 branch February 27, 2019 03:57
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.

2 participants