-
Notifications
You must be signed in to change notification settings - Fork 10.5k
Fixed layout classes should still have resilient vtables #20850
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
Fixed layout classes should still have resilient vtables #20850
Conversation
(This still needs some more tests and cleanup) |
@swift-ci Please benchmark |
Build comment file:Performance: -O
Performance: -Osize
Performance: -Onone
How to read the dataThe tables contain differences in performance which are larger than 8% and differences in code size which are larger than 1%.If you see any unexpected regressions, you should consider fixing the Noise: Sometimes the performance results (not code size!) contain false Hardware Overview
|
f389afd
to
c28379f
Compare
Let's try with one more tweak @swift-ci Please benchmark |
Build comment file:Performance: -O
Performance: -Osize
Performance: -Onone
How to read the dataThe tables contain differences in performance which are larger than 8% and differences in code size which are larger than 1%.If you see any unexpected regressions, you should consider fixing the Noise: Sometimes the performance results (not code size!) contain false Hardware Overview
|
@swift-ci Please test source compatibility |
2 similar comments
@swift-ci Please test source compatibility |
@swift-ci Please test source compatibility |
c28379f
to
549d1b6
Compare
@@ -928,6 +928,9 @@ SubclassScope SILDeclRef::getSubclassScope() const { | |||
assert(FD->getEffectiveAccess() <= classType->getEffectiveAccess() && | |||
"class must be as visible as its members"); | |||
|
|||
// FIXME: This is too narrow. Any class with resilient metadata should | |||
// probably have this, at least for method overrides that don't add new | |||
// vtable entries. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, this seems important for the correctness issue we're worried about.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Slava clarified privately that we can change this later as long as the fixed-layout classes we ship in Swift 5 don't break the rules that were there in Swift 5.
549d1b6
to
3cac828
Compare
@swift-ci Please test |
1 similar comment
@swift-ci Please test |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Alright, this seems ok.
As I mentioned in chat, this implies that we consider the generic signature section of the metadata to be stable when the metadata is fixed-layout, which may make some things with resiliently-added default generic arguments harder. But I think we can live with that.
Build failed |
- We don't want to support changing a root class of a class, so don't pretend that works. Some of these tests got removed recently in d8104e7 but one still remained. - For the tests that insert a non-root superclass in the inheritance hierarchy, also test calling a method of the derived class. This works now that we no longer hardcode vtable offsets and instead use dispatch thunks.
We want to be able to define classes with a fixed storage layout, but a resilient (opaque) vtable. If the class is also generic, we still have to load field offsets from the metadata if they are dependent. So put the field offsets after the generic arguments and before the vtable. This is an ABI break for @_fixed_layout classes, which are defined by the stdlib.
…t-metadata from resilient-storage We want @_fixed_layout classes to have non-resilient storage, but still have resilient metadata.
@_fixed_layout classes have resilient vtables now, so we can add and re-order methods. Removing overrides is not legal though because they are subject to devirtualization.
The result type mismatch comes up when we're calling a covariant override of a class method resiliently as well.
3cac828
to
f8d2881
Compare
@swift-ci Please test |
To achieve this, re-organize the metadata so that the field offset vector comes immediately after the generic parameter area, instead of after the vtable. This means the vtable can change resiliently.
Note that for non-generic
@_fixed_layout
classes without resiliently-sized fields, field offsets are constant and will be inlined directly, but we need the more general access pattern to work if the@_fixed_layout
class has generic layout.Also, use method dispatch thunks to call vtable methods instead of accessing the vtable directly, as with resilient classes.
Since the metadata size is not known at compile time, we use the most general metadata instantiation strategy now.