[Runtime] Fix swift_retainCount for deiniting objects and BridgeObject tagged values. Make swift_bridgeObjectRetain/Release bail out early for tagged values.
We were previously only installing the image registration helper in the shared
runtime location. When building with a static runtime, we would look in the
wrong location. Ensure that we install to both locations to repair the static
builds.
Have clients pass the requirement base descriptor to
swift_getAssociatedTypeWitness(), so that the witness index is just one
subtraction away, avoiding several dependent loads (witness table ->
conformance descriptor -> protocol descriptor -> requirement offset)
in the hot path.
The Allocations Instrument overrides swift_retain with a function that records the retain count by calling swift_retainCount. Its assert for bits.getIsDeiniting() is incorrect in that case, so remove it.
The recent change to ObjC tagged pointer bits on x86-64 also caused the various bridgeObjectRetain/Release functions to call through to swift_retain for BridgeObject tagged values on Mac. swift_retain ignored those values so there was no functional change, except when Instruments overrode it and passed them to swift_retainCount, which tried to dereference them and crashed. Modify bridgeObjectRetain/Release to bail out early again. Also modify swift_retainCount to ignore those values in case anything else expects retainCount to work on any pointer swift_retain accepts.
rdar://problem/45102538
Rather than rely on the metadata initialization function to compute and
fill in the superclass, use the mangled superclass name to construct the
superclass metadata.
Previously we had a single mask for all x86-64 targets which included both the top and bottom bits. This accommodated simulators, which use the top bit, while macOS uses the bottom bit, but reserved one bit more than necessary on each. This change breaks out x86-64 simulators from non-simulators and reserves only the one bit used on each.
rdar://problem/34805348 rdar://problem/29765919
Introduce a sanity check verifying that we can demangle the superclass
of a class when forming type metadata, and that the result matches the
compiler-provided superclass metadata.
The superclass descriptor reference in class context descriptors is only used
for metadata bound computations when the superclass is resilient. Only
include the superclass descriptor reference when the class has a resilient
superclass, using a trailing record. It’s a tiny space savings for
classes that don’t have resilient superclasses.
The functions in LibcShims are used externally, some directly and some through @inlineable functions. These are changed to SWIFT_RUNTIME_STDLIB_SPI to better match their actual usage. Their names are also changed to add "_swift" to the front to match our naming conventions.
Three functions from SwiftObject.mm are changed to SPI and get a _swift prefix.
A few other support functions are also changed to SPI. They already had a prefix and look like they were meant to be SPI anyway. It was just hard to notice any mixup when they were #defined to the same thing.
rdar://problem/35863717
This is the scheme used for metadata caches elsewhere, and it
eliminates the need to check the metadata state along the hot path of
swift_getAssociatedTypeWitness().
Encode default associated type witnesses using a sentinel prefix byte
(0xFF) in the mangled name rather than as a second low bit on the
reference. Align all of the mangled names used for type references to
2 bytes (so we get that low bit regardless) and separate the symbol
names for default associated type witnesses vs. other kinds of
metadata or reflection metadata.
Indicate whether a particular associated type witness is a default (whose
mangled name is relative to the protocol) vs. being supplied as part of the
conformance (whose mangled name is relative to the conforming type). The
use of pointer identity to distinguish these cases can fail due to the
coalescing of these linker symbols.
When producing an associated type witness from a mangled name, adjust the
conforming type metadata to find the original conforming type, which may
be a superclass of the conforming type given.
Associated type witnesses in a witness table are cache entries, which are
updated by the runtime when the associated types are first accessed. The
presence of an associated type witness that involves type parameters requires
the runtime to instantiate the witness table; account for that in the runtime.
The presence of any associated type witness makes the witness table
non-constant.
Rather than storing associated type metadata access functions in
witness tables, initially store a pointer to a mangled type name.
On first access, demangle that type name and replace the witness
table entry with the resulting type metadata.
This reduces the code size of protocol conformances, because we no
longer need to create associated type metadata access functions for
every associated type, and the mangled names are much smaller (and
sharable). The same code size improvements apply to defaulted
associated types for resilient protocols, although those are more
rare. Witness tables themselves are slightly smaller, because we
don’t need separate private entries in them to act as caches.
On the caller side, associated type metadata is always produced via
a call to swift_getAssociatedTypeWitness(), which handles the demangling
and caching behavior.
In all, this reduces the size of the standard library by ~70k. There
are additional code-size wins that are possible with follow-on work:
* We can stop emitting type metadata access functions for non-resilient
types that have constant metadata (like `Int`), because they’re only
currently used as associated type metadata access functions.
* We can stop emitting separate associated type reflection metadata,
because the reflection infrastructure can use these mangled names
directly.
When demangling a symbolic reference to a nested generic type, the
demangle-to-metadata path will be given all levels of generic arguments at
once. Cope with this in the demangling-to-metadata path.
Eventually, we would like to switch all clients over to take all
levels of generic arguments at once.
When forming metadata for a nested generic type, gather all of the
generic arguments from the parent type “as written”, so that we can directly
map generic parameters to those generic arguments when they occur within
requirements. This allows us to demangle nested types within extensions
that have same-type constraints on generic parameters into type metadata.
Fixes rdar://problem/37170296.
At the moment the location being reported is inside the standard
library, which is not very helpful. Instead, the location should point
at the `try!` expression in the application code.
Fixes: rdar://problem/21407683
When mapping from type metadata to a demangle tree, fill in the complete
set of generic arguments. Most of the effort here is in dealing with
extensions that involve same-type constraints on a generic parameter, e.g.,
extension Array where String == Element { }
extension Dictionary where Key == Value { }
In such cases, the metadata won’t contain generic arguments for every
generic parameter. Rather, the generic arguments for non-key generic
parameters will need to be computed based on the same-type requirements
of the context. Do so, and eliminate the old hacks that put the generic
arguments on the innermost type. We don’t need them any more.
Part of rdar://problem/37170296.
If a class has a backward deployment layout:
- We still want to emit it using the FixedClassMetadataBuilder.
- We still want it to appear in the objc_classes section, and get an
OBJC_CLASS_$_ symbol if its @objc.
- However, we want to use the singleton metadata initialization pattern
in the metadata accessor.
- We want to emit metadata for all field types, and call the
swift_updateClassMetadata() function to initialize the class
metadata.
For now, this function just performs the idempotent initialization of
invoking a static method on the class, causing it to be realized with
the Objective-C runtime.
- Rename _swift_initializeSuperclass() to copySuperclassMetadataToSubclass(),
- Factor out initClassFieldOffsetVector()
- Factor out initClassVTable()
- Factor out initGenericObjCClass()
Otherwise, we emitted a static reference to its metaclass, so there's
no need to overwrite it here. This doesn't really improve anything,
it was just something I noticed while auditing this code in
preparation for a refactoring, so may as well fix it.
Reimplement SubstGenericParametersFromMetadata to cope with non-key
generic parameters, which are counted when referring to generic parameters
from metadata but do not have corresponding generic arguments.
Use SubstGenericParametersFromMetadata to handle substitutions when
checking generic requirements, extending SubstGenericParametersFromMetadata
for this purpose.
The field metadata translation has a great little lambda for extracting
generic arguments from metadata when demangling. Extract it into a
reusable function object.
The resolution of generic parameter references, which is used for
checking generic requirements at runtime, was written in terms of an
outdated signature for associated type access functions that did not
account for the MetadataRequest parameter or MetadataResponse result.
Use the existing AssociatedTypeAccessFunction typedef instead.
Fixes SR-7553 / rdar://problem/39769906
When SWIFT_ENABLE_MANGLED_NAME_VERIFICATION is set, we would end up
deadlocking when we encounter a metadata cycle. The demangling code only
requires abstract metadata, because at most it needs type identity and
filling in the type arguments of generics. Update clients of
_getTypeByMangledName to assert the kind of metadata they require.