Skip to content

Don't Serialize Declarations with package Access #70100

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
Dec 1, 2023

Conversation

CodaFi
Copy link
Contributor

@CodaFi CodaFi commented Nov 29, 2023

This accidentally started happening when I adjusted getEffectiveAccess to return Public for Package declarations in #69709. As a result, the optimizer thought it had more opportunities to go after declarations that used to be opaque. Unfortunately, this resulted in a miscompile as the devirtualizer was able to look through now-serialized package (static) functions. In one specific instance, the optimizer created direct calls to hidden accessors instead of going through the dispatch thunk.

Ban serializing witness tables, vtables, and functions for package types once more.

This accidentally started happening when I adjusted getEffectiveAccess to return `Public` for `Package` declarations in swiftlang#69709. As a result, the optimizer thought it had more opportunities to go after declarations that used to be opaque. Unfortunately, this resulted in a miscompile as the devirtualizer was able to look through now-serialized package (static) functions. In one specific instance, the optimizer created direct calls to hidden accessors instead of going through the dispatch thunk.
@CodaFi
Copy link
Contributor Author

CodaFi commented Nov 29, 2023

@swift-ci smoke test

@@ -1080,7 +1080,7 @@ void SILGenModule::emitNonCopyableTypeDeinitTable(NominalTypeDecl *nom) {
auto serialized = IsSerialized_t::IsNotSerialized;
bool nomIsPublic = nom->getEffectiveAccess() >= AccessLevel::Public;
// We only serialize the deinit if the type is public and not resilient.
if (nomIsPublic && !nom->isResilient())
if (nomIsPublic && !nom->hasPackageAccess() && !nom->isResilient())
Copy link
Contributor

Choose a reason for hiding this comment

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

is it possible that getEffectiveAccess() == Public && nom->hasPackageAccess()

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes. This PR #69709 changed the effective access level of package declarations to public since those declarations are visible across module boundaries.

Copy link
Contributor

Choose a reason for hiding this comment

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

Would it be too disruptive to have getEffectiveAccess() return a new enum that does not include 'Package' then? Or maybe move the computation to the SIL linkage level, so that AccessLevel::Package becomes SILLinkage::Public? getEffectiveAccess() is a terrible hack for -enable-testing and we should not hang new behavior off of it. There's also a FormalLinkage concept for type metadata in IRGen, IIRC. It's all too convoluted.

@CodaFi CodaFi merged commit db28fc8 into swiftlang:main Dec 1, 2023
@CodaFi CodaFi deleted the cereal-milk branch December 1, 2023 20:48
tshortli added a commit to tshortli/swift that referenced this pull request Dec 18, 2023
swiftlang#70100 prohibited `package` declarations from
ever being serialized in order to solve a problem in which the declarations
were being serialized inappropriately. That's too heavy handed, though, because
an `@_alwaysEmitIntoClient` function with `package` access *must* be serialized
because it has `public_nonabi` linkage.

Resolves rdar://104711625
tshortli added a commit to tshortli/swift that referenced this pull request Dec 18, 2023
swiftlang#70100 prohibited `package` declarations from
ever being serialized in order to solve a problem in which the declarations
were being serialized inappropriately. That's too heavy handed, though, because
an `@_alwaysEmitIntoClient` function with `package` access *must* be serialized
because it has public non-abi linkage.

Resolves rdar://104711625
tshortli added a commit to tshortli/swift that referenced this pull request Dec 19, 2023
tshortli added a commit to tshortli/swift that referenced this pull request Dec 19, 2023
meg-gupta pushed a commit to meg-gupta/swift that referenced this pull request Dec 21, 2023
swiftlang#70100 prohibited `package` declarations from
ever being serialized in order to solve a problem in which the declarations
were being serialized inappropriately. That's too heavy handed, though, because
an `@_alwaysEmitIntoClient` function with `package` access *must* be serialized
because it has public non-abi linkage.

Resolves rdar://104711625
meg-gupta pushed a commit to meg-gupta/swift that referenced this pull request Dec 21, 2023
meg-gupta pushed a commit to meg-gupta/swift that referenced this pull request Dec 21, 2023
Catfish-Man pushed a commit to Catfish-Man/swift that referenced this pull request Jan 19, 2024
swiftlang#70100 prohibited `package` declarations from
ever being serialized in order to solve a problem in which the declarations
were being serialized inappropriately. That's too heavy handed, though, because
an `@_alwaysEmitIntoClient` function with `package` access *must* be serialized
because it has public non-abi linkage.

Resolves rdar://104711625
Catfish-Man pushed a commit to Catfish-Man/swift that referenced this pull request Jan 19, 2024
Catfish-Man pushed a commit to Catfish-Man/swift that referenced this pull request Jan 19, 2024
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.

3 participants