mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
When we generate code that asks for complete metadata for a fully concrete specific type that doesn't have trivial metadata access, like `(Int, String)` or `[String: [Any]]`, generate a cache variable that points to a mangled name, and use a common accessor function that turns that cache variable into a pointer to the instantiated metadata. This saves a bunch of code size, and should have minimal runtime impact, since the demangling of any string only has to happen once. This mostly just works, though it exposed a couple of issues: - Mangling a type ref including objc protocols didn't cause the objc protocol record to get instantiated. Fixed as part of this patch. - The runtime type demangler doesn't correctly handle retroactive conformances. If there are multiple retroactive conformances in a process at runtime, then even though the mangled string refers to a specific conformance, the runtime still just picks one without listening to the mangler. This is left to fix later, rdar://problem/53828345. There is some more follow-up work that we can do to further improve the gains: - We could improve the runtime-provided entry points, adding versions that don't require size to be cached, and which can handle arbitrary metadata requests. This would allow for mangled names to also be used for incomplete metadata accesses and improve code size of some generic type accessors. However, we'd only be able to take advantage of the new entry points in OSes that ship a new runtime. - We could choose to always symbolic reference all type references, which would generally reduce the size of mangled strings, as well as make runtime demangling more efficient, since it wouldn't need to hit the runtime caches. This would however require that we be able to handle symbolic references across files in the MetadataReader in order to avoid regressing remote mirror functionality.