Skip to content

Remove three ObjC metadata fields from non-ObjC runtime #31811

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 2 commits into from
May 23, 2020

Conversation

davezarzycki
Copy link
Contributor

@davezarzycki davezarzycki commented May 15, 2020

Hi @rjmccall – Before I finish this draft pull request, I'd like to verify that:

  1. The non-Apple ABI is still not locked down.
  2. This change is reasonable.

I'll finish fixing all the broken tests if this is the case. Thanks! As a bonus, what other fields are good candidates for removal from the non-ObjC runtime?

[EDIT] – A related followup question for a followup PR: Should the vtable layout be more like C++? I.e. where the positive displacements are vtable slots and the negative displacements are language/runtime metadata? This would allow for better code density.

Copy link
Contributor

@mikeash mikeash left a comment

Choose a reason for hiding this comment

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

Seems reasonable to me.

StoredPointer dataPtr;
if (!Reader->readInteger(RemoteAddress(classAddress +
TargetClassMetadata<Runtime>::offsetToData()),
&dataPtr))
return StoredPointer();
#else
StoredPointer dataPtr = SWIFT_CLASS_IS_SWIFT_MASK;
Copy link
Contributor

Choose a reason for hiding this comment

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

You can just return StoredPointer(); here. You'll end up hitting the if (!dataPtr) path a few lines later anyway.

@rjmccall
Copy link
Contributor

Ideally, MetadataReader wouldn't be sensitive to target #if conditions, and instead ObjC interop-ness would be reflected in the Target abstraction. That would e.g. allow tools built one way to debug/analyze programs built the other. To make that work, you'll have to play some template games in Metadata.h, but it shouldn't be too bad.

@jckarter
Copy link
Contributor

You are correct that the non-Darwin ABI is still up for grabs. I agree with @rjmccall that it'd be nice if we could make this dependent on the Runtime template argument instead of using conditional compilation.

A good followup for non-Darwin optimization would be to start treating class objects as being directly referenceable as metadata, like struct/enum metadata is, since there's no ObjC realization to worry about. That should save a good amount of code size from metadata accesses, and allow dynamic class metadata instantiation for generic or resilient classes to be more efficient and avoid some synchronization that's necessary on Darwin to coordinate with ObjC realization.

@rjmccall
Copy link
Contributor

rjmccall commented May 15, 2020

Yeah. It'll need some new logic in order to check for transitive direct-referenceability of superclasses, since right now the condition is just "no, you can't emit this reference directly", but it should be possible to be much more efficient than we are on ObjC-interop platforms.

@@ -65,8 +65,10 @@ template <class Impl> class ClassMetadataVisitor
// FIXME: Figure out what can be removed altogether in non-objc-interop
// mode and remove it. rdar://problem/18801263
Copy link
Member

Choose a reason for hiding this comment

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

Does this not address this FIXME?

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'm not sure and that's why I asked at the top: "what other fields are good candidates for removal from the non-ObjC runtime?"

I think that @rjmccall and @jckarter got too excited about other things that need fixing, so they missed that question. ;-)

Copy link
Contributor

Choose a reason for hiding this comment

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

The three extra padding fields seem like the biggest obvious thing to remove. I can't off the top of my head think of any other places where we could wholesale remove fields. I'd be fine removing the fixme.

@davezarzycki
Copy link
Contributor Author

Hi @rjmccall and @jckarter – I'd like to do incremental updates. Would you be okay with focusing in unnecessary field removal in this PR? In particular, the MetadataReader was already using ifdefs, so I'd like to leave fixing that issue to a later PR.

@rjmccall
Copy link
Contributor

I'm not sure and that's why I asked at the top: "what other fields are good candidates for removal from the non-ObjC runtime?"

That addresses it for classes, which is the scope of this particular FIXME.

Assuming that we're not interested in highly-disruptive layout changes like putting the VWT at a positive offset, I think most of the other ways that ObjC inserts itself into the runtime representation are just extra alternatives in various metadata references — things like protocol references possibly being to ObjC protocols, or type references possibly being to ObjC classes.

Would you be okay with focusing in unnecessary field removal in this PR? In particular, the MetadataReader was already using ifdefs, so I'd like to leave fixing that issue to a later PR.

I think it's fine to make MetadataReader work cross-ObjC-interop in a different patch. Please base the conditionalization in Metadata.h on the Runtime parameter, though, otherwise it's just not being done right.

@jckarter
Copy link
Contributor

If we base the presence of the ObjC compatibility fields on the Runtime template parameter, then the correct MetadataReader behavior ought to fall out automatically.

@rjmccall
Copy link
Contributor

For this, at least. Dave is right that there are existing #ifs in that file which ought to be converted to uses of information from Runtime if we're going to support running cross-configuration properly.

@davezarzycki
Copy link
Contributor Author

@swift-ci please test

@swift-ci
Copy link
Contributor

Build failed
Swift Test Linux Platform
Git Sha - 0cf24e8750e0db307578f91c6f484a4c3a1df204

@swift-ci
Copy link
Contributor

Build failed
Swift Test OS X Platform
Git Sha - 0cf24e8750e0db307578f91c6f484a4c3a1df204

@davezarzycki
Copy link
Contributor Author

@swift-ci please test windows

@davezarzycki
Copy link
Contributor Author

A good followup for non-Darwin optimization would be to start treating class objects as being directly referenceable as metadata, like struct/enum metadata is, since there's no ObjC realization to worry about.

Hi @jckarter – If you point me at a few lines of code to see the difference you're talking about, then I can make an attempt at fixing it.

@davezarzycki
Copy link
Contributor Author

@swift-ci please test macos

@davezarzycki
Copy link
Contributor Author

Hi @compnerd – Does FileCheck not execute RUN directives via a POSIX compliant shell on Windows? I'm trying to use $(( 1 + 2 * 3 )) style shell arithmetic in a RUN line.

@swift-ci
Copy link
Contributor

Build failed
Swift Test OS X Platform
Git Sha - 37250e1ca6e14f006861f91d125d348b05a5427a

@davezarzycki davezarzycki marked this pull request as ready for review May 20, 2020 13:22
@davezarzycki
Copy link
Contributor Author

@swift-ci please test

@swift-ci
Copy link
Contributor

Build failed
Swift Test Linux Platform
Git Sha - 37250e1ca6e14f006861f91d125d348b05a5427a

@swift-ci
Copy link
Contributor

Build failed
Swift Test OS X Platform
Git Sha - 37250e1ca6e14f006861f91d125d348b05a5427a

@davezarzycki
Copy link
Contributor Author

@swift-ci please clean test macos

@swift-ci
Copy link
Contributor

Build failed
Swift Test OS X Platform
Git Sha - 21af78586a549cb5134c418308e93e4005d32c7b

@davezarzycki
Copy link
Contributor Author

@swift-ci please test

@davezarzycki
Copy link
Contributor Author

@swift-ci please test windows

@swift-ci
Copy link
Contributor

Build failed
Swift Test OS X Platform
Git Sha - 21af78586a549cb5134c418308e93e4005d32c7b

@swift-ci
Copy link
Contributor

Build failed
Swift Test Linux Platform
Git Sha - 21af78586a549cb5134c418308e93e4005d32c7b

@davezarzycki
Copy link
Contributor Author

@swift-ci please test windows

@davezarzycki
Copy link
Contributor Author

@swift-ci please test

@swift-ci
Copy link
Contributor

Build failed
Swift Test Linux Platform
Git Sha - 4dd6ae4e0607bd5033da74f07745fe8e7ee320fb

@swift-ci
Copy link
Contributor

Build failed
Swift Test OS X Platform
Git Sha - 4dd6ae4e0607bd5033da74f07745fe8e7ee320fb

@jckarter
Copy link
Contributor

@davezarzycki If you want to look into making class metadata statically addressable, a good place to start looking would be shouldCacheTypeMetadataAccess and shouldTypeMetadataAccessUseAccessor in IRGen. You could also look over the *ClassMetadataBuilder* classes in IRGen and the various swift_init*Class* functions in the runtime to see if there are opportunities for optimizing the initialization process for generic or resilient classes when ObjC realization is not necessary.

@compnerd
Copy link
Member

@swift-ci please test Windows platform

Adjust the test to accommodate environments which do indirect imports,
which use the singleton strategy, relying on the runtime initialization
of fields which are imported.
@compnerd
Copy link
Member

#31981 has the test adjustments needed for this. Could you please grab the top commit and put it into this PR?

@davezarzycki
Copy link
Contributor Author

@swift-ci please test Windows platform

@davezarzycki
Copy link
Contributor Author

@swift-ci please test

@swift-ci
Copy link
Contributor

Build failed
Swift Test Linux Platform
Git Sha - 28bdd9831bee7115e7526a92c6cc07794f69db77

@swift-ci
Copy link
Contributor

Build failed
Swift Test OS X Platform
Git Sha - 28bdd9831bee7115e7526a92c6cc07794f69db77

@davezarzycki davezarzycki mentioned this pull request May 23, 2020
@davezarzycki
Copy link
Contributor Author

@swift-ci please test Windows platform

1 similar comment
@davezarzycki
Copy link
Contributor Author

@swift-ci please test Windows platform

@davezarzycki
Copy link
Contributor Author

@compnerd The windows failure looks unrelated. Agreed? Ready to merge?

@swift-ci please test Windows platform

@compnerd
Copy link
Member

Yeap, that looks unrelated to this change. sigh time to go track that down.

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.

6 participants