-
Notifications
You must be signed in to change notification settings - Fork 10.5k
[metadata prespecialization] Add canonical records to cache. #34490
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
[metadata prespecialization] Add canonical records to cache. #34490
Conversation
b323cd5
to
7fed11d
Compare
Emit a once token when adding canonical prespecialized metadata records to a nominal type descriptor and add the token itself as a trailing object to the type descriptor. The new token will, in subsequent commits, enable the canonical prespecialized metadata records attached to the type descriptor to be added to the metadata cache exactly once.
Add a new entry point for getting generic metadata which adds the canonical metadata records attached to the nominal type descriptor to the metadata cache. Change the implementation of the primary entry-point swift_getGenericMetadata to stop looking through canonical prespecialized records. Change the implementation of swift_getCanonicalSpecializedMetadata to use the caching token attached to the nominal type descriptor to add canonical prespecialized metadata records to the metadata cache only once rather than using the cache variables to limit the number of times the attempt was made.
When emitting the metadata accessor for a generic type for which canonical prespecialized metadata records have been formed, rather than calling getGenericMetadata, instead call getCanonicalPrespecializedGenericMetadata and pass to it the once token which will guard that the canonical prespecialized metadata records attached to the nominal type descriptor are only added to the metadata cache once.
7fed11d
to
1bbd0f4
Compare
@swift-ci please test |
@swift-ci please benchmark |
@swift-ci please test compiler performance |
@swift-ci please asan test |
Build failed |
@swift-ci please clean test linux platform |
@swift-ci please clean test windows platform |
Performance: -O
Code size: -OPerformance: -Osize
Code size: -OsizePerformance: -Onone
Code size: -swiftlibsHow 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
|
Build failed |
@swift-ci please clean test macos platform |
Very nice! Should we still use the previous implementation when targeting a 5.3 runtime, or is the code size/performance hit from checking all the specializations one by one just not worth it? |
@jckarter We're a bit lucky in a way: even before this change, The 5.3 runtime doesn't know about the new trailing objects on the nominal type descriptors which would be needed to loop over the prespecializations in swift_getGenericMetadata (and its version of swift_getGenericMetadata doesn't know to do that). The comparisons can't be done directly in the metadata accessor itself, either, because the 5.3 runtime lacks I guess if we added support in a compatibility library, we could just add swift_getCanonicalPrespecializedGenericMetadata itself, supposing we can add these trailing objects, if it's worth having this feature available for 5.3. What do you think? |
Ah, I thought we had shipped partial support for prespecializations in 5.3 already. If we haven't shipped that yet, then it might be interesting to back deploy, but I don't think it's strictly necessary since this is an optimization and not core functionality. |
Previously, every call to
swift_getGenericMetadata
involved looking into the passed-in nominal type descriptor to look for canonical prespecialized metadata records and searching through those records looking for one whose arguments matched those passed to the function. That behavior was an evolution from the previous behavior where the search through canonical metadata records was performed in the metadata accessor itself.Here, that behavior is removed from
swift_getGenericMetadata
entirely. This is made possible by calling a different variant of that function from the metadata accessors of generic types for which canonical prespecialized metadata records have been formed. The metadata accessors now call the new runtime functionswift_getCanonicalPrespecializedGenericMetadata
, either directly or by way of a newly added thunk__swift_instantiateCanonicalPrespecializedGenericMetadata
which is analogous to__swift_instantiateGenericMetadata
but calls through toswift_getCanonicalPrespecializedGenericMetadata
rather thanswift_getGenericMetadata
.The new runtime function
swift_getCanonicalPrespecializedGenericMetadata
takes an additional argument beyond those passed toswift_getGenericMetadata
, namely, aswift_once_t *
token. That token is used to guard that only one attempt is made to add the canonical prespecialized metadata records attached to the nominal type descriptor to the metadata cache.Additionally,
swift_getCanonicalSpecializedMetadata
--the entry point for canonicalizing non-canonical prespecialized metadata records--is able to make use of that same token to also avoid attempting to add more than once to the metadata cache those same canonical prespecialized records. Reusing the once token like this (by bothswift_getCanonicalPrespecializedGenericMetadata
andswift_getCanonicalSpecializedMetadata
) ensures that, regardless of which entry point is used, exactly one attempt will be made to add canonical prespecialized records to the metadata cache.Reusing the once token is made possible by adding its address to the struct enum and class descriptors after the canonical prespecialized records already in those descriptors.
swift_getCanonicalPrespecializedGenericMetadata
attempts to find the once token in the type descriptor. If it is there, then that means that there were prespecializations and it attempts to add those prespecializations to the cache (guarded, again, by that once token).rdar://problem/69855938