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.
We cannot link against the DSO (dll) on Windows and instead link against
the import library. Let the driver understand this and use the standard
linking technique. Adjust the name of the emitted files accordingly and
use the `%target-library-name` macro more freely.
Two tests remain:
- multifile.protocol-conformance-member
The getter is synthesized by not exported so `llvm-nm` is unable to
see it
- multifile.nested_types
Windows uses the singleton strategy, so the emitted full type
metadata does not have the reference to the value witness table for
Void
Create a new capturing substitution for adding a rpath to a target
library. This is needed as Windows doesn't really support the concept
of a rpath. This also makes it possible to remove the parameter from
the command line on windows.
The naming convention is different on Windows than on Unix-like
environments. In order to follow the convention we need to substitute
the prefix and the suffix. Take the opportunity to rename the
`target-dylib-extension` to the CMake-like variable
`target-shared-library-suffix` and introduce
`target-shared-library-prefix`. This helps linking the test suite
binaries on Windows.