Skip to content

Enable dynamic replacement with library evolution #30965

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

Conversation

slavapestov
Copy link
Contributor

Fixes rdar://problem/58457716.

@@ -629,6 +629,8 @@ SILLinkage LinkEntity::getLinkage(ForDefinition_t forDefinition) const {
return SILLinkage::Private;

case Kind::DynamicallyReplaceableFunctionKey:
return getSILFunction()->getLinkage();
Copy link
Contributor Author

Choose a reason for hiding this comment

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

@aschwaighofer This was the only actual change I had to make. Are you aware of anything that I might have missed?

@slavapestov
Copy link
Contributor Author

@swift-ci Please test

@aschwaighofer
Copy link
Contributor

The way we choose which accessors get marked dynamically replaceable is not right. JohnM and Jrose explained to me that we should use the opaque accessors instead of whatever I choose to replace.

@slavapestov
Copy link
Contributor Author

@aschwaighofer Do you have an example that we miscompile today?

@rjmccall Do you remember what the issue was?

@aschwaighofer
Copy link
Contributor

I don't have an example. But the accessors that are printed in the swiftinterface file need to be the ones that are marked dynamic, I think.

@swift-ci
Copy link
Contributor

Build failed
Swift Test Linux Platform
Git Sha - c0ad045d8ce9cfac4e6f0ca725cc757fbcd93eb9

@aschwaighofer
Copy link
Contributor

aschwaighofer commented Apr 11, 2020

Here is the comment from the commit 1980c4a that disabled dynamic in library evolution mode:

Disallow `dynamic` on native Swift declarations under library-evolution mode
    
    The current ABI of dynamic is not what we want for certain declarations.
    
    e.g
    
    dynamic var x : Int {
      willset {
      }
    }
    
    Is exposed in the .swiftinterface file as
    
    dynamic var x : Int {
      get {}
      set {}
    }
    
    However, the actual implementation is marking the willSet only dynamic.
    
    var x : Int {
      dynamic willSet() {}
      get {}
      set {}
    }
    
    To be able to rely on `dynamic` in the future we disable dynamic (for
    non-@objc) under library-evolution for now until we have made sure that
    the ABI is proper.
    
    rdar://51678074

@aschwaighofer
Copy link
Contributor

I am not sure that we actually print all opaque accessors in the swift interface file.
I feel like _modify accessor is also part of the set of opaque accessors?

@slavapestov
Copy link
Contributor Author

@aschwaighofer I don't understand why, though. There's no resilience boundary between the instrumented library and the dynamic replacement stub.

It looks like the only thing that fails is the linkage computation
for the dynamic replacement key of class methods. Even though
methods have hidden linkage to prevent them from being directly
referenced from outside a resilient module, we need to ensure
the dynamic replacement key is visible.

Fixes <rdar://problem/58457716>.
@slavapestov slavapestov force-pushed the enable-dynamic-replacement-vs-library-evolution branch from c0ad045 to 23cac67 Compare April 11, 2020 02:54
@slavapestov
Copy link
Contributor Author

@swift-ci Please smoke test

@slavapestov
Copy link
Contributor Author

I'm going to merge this PR since it fixes the class method linkage issue. I'll keep poking at the accessor thing to try to come up with an example where the current scheme fails.

@slavapestov slavapestov merged commit 1af01ed into swiftlang:master Apr 11, 2020
@aschwaighofer
Copy link
Contributor

aschwaighofer commented Apr 11, 2020

I don't understand why, though. There's no resilience boundary between the instrumented library and the dynamic replacement stub.

This might be the case how it is being used today. But dynamic is a language feature like any other. So a resilient dynamic foo should be resilient? It should be possible to resiliently replace it.
I can't think of a reason why it can't be so.
You might be limited in what you do in the replacement but it should be possible?

If we ship the compiler with 'invalid' interface files we can't rely on them without some sort of versioning in the future (or so was the argument brought up in the radar).

I am not 100% sure anymore but the example above I think also is a distillation of a problem I ran into at some point. The mismatch was causing a problem somehow: I can see this causing problems when the compilation of the replacement would use the .swiftinterface file. It would try to replace the wrong entry points.

@aschwaighofer
Copy link
Contributor

It might be worth running the resilience tests with -enable-implicit-dynamic enabled and to see that does not cause issues.

I ran the all tests like this at one point (hack the compiler to have enable-implicit-dynamic enabled is probably the easiest way to do this).

@aschwaighofer
Copy link
Contributor

The mismatch was causing a problem somehow: I can see this causing problems when the compilation of the replacement would use the .swiftinterface file. It would try to replace the wrong entry points.

This might no longer reproduce today because this could have only reproduced when we were (erroneously) preferring .swiftinterface over .swiftmodule files?

@compnerd
Copy link
Member

@slavapestov - this seems to have caused a regression: https://ci-external.swift.org/job/swift-PR-windows/1596/consoleText

compnerd added a commit to compnerd/apple-swift that referenced this pull request Apr 11, 2020
swiftlang#30965 broke the Windows test suite, this speculatively fixes
it.
compnerd added a commit that referenced this pull request Apr 11, 2020
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.

4 participants