Instead of capturing SubstGenericParametersFromMetadata and SubstGenericParametersFromWrittenArgs by value, capture by reference.
This avoids those instances to be copied and thus avoids a lot of mallocs.
SR-10028
rdar://problem/48575729
This dramatically reduces the number of needed malloc calls.
Unfortunately I had to add the implementation of SmallVectorBase::grow_pod to the runtime, as we don't link LLVM. This is a bad hack, but better than re-inventing a new SmallVector implementation.
SR-10028
rdar://problem/48575729
We would not previously symbolicate the stack trace and as a result
would not display the stack trace. Add symbolication support to the
runtime to actually make use of the captured stack trace. This allows
us to get a stack trace when the standard library or swift code reports
a fatal error.
In our initial approach for resolving metadata dependency cycles with classes, non-transitively complete superclass metadata was fetched by the subclass's metadata completion function and passed to `swift_initClassMetadata`. That could mean generating quite a lot of code in the completion function, and so we fairly recently changed it so that `swift_initClassMetadata` instead fetched the superclass metadata via a demangling. Unfortunately, the metadata demangler only fetches _abstract_ metadata by default, and class metadata cannot be considered even non-transitively complete when its superclass reference not at that stage. If the superclass metadata is being completed on one thread, and a subclass is being completed on another, and the subclass installs the incomplete superclass metadata in its superclass field and attempts to register the subclass with the Objective-C runtime, the runtime may crash reading the incompletely-initialized superclass.
The proper fix is to make `swift_initClassMetadata` fetch non-transitively complete metadata for the superclass, delaying completion if that metadata is unavailable. Unfortunately, that can't actually be implemented on top of `swift_initClassMetadata` because that function has no means of reporting an unsatisfied dependency to its caller, and we can no longer simply change its signature without worrying about a small of internal code that might still be using it. We cannot simply perform a blocking metadata request in `swift_initClassMetadata` because it is deeply problematic to block within a metadata completion function. The solution is therefore to add a `swift_initClassMetadata2` which has the ability to report unsatisfied dependencies. That was done in #22386; this patch builds on that by teaching the compiler to generate code to actually use it. It is therefore not safe to use this patch if you might be running on an OS that only provides the old runtime function, but that should be a temporary Apple-internal problem.
Fixes rdar://47549859.
Note that I've called out a couple of suspicious places where we
are requesting abstract metadata for superclasses but probably
need to be requesting something more complete.
This is a funnel point for looking up the protocol conformance descriptor
for a given conforming type + conformance. Make it overridable in case we
need to back-deploy changes or fixes.
Implements rdar://problem/46281660.
We know we're going to want this parameter to handle lookup of
retroactive conformances when we've been given a module, so add it
now because we want this to be an overridable entry point.
The conformance cache was caching the witness table for a conformance
`T: P`, where `T` is a concrete type and `P` is a protocol. However, it
essentially picked one of potentially many witness tables for that
conformance, because retroactive conformances might produce different results
from different modules.
Make the conformance cache what is says it is: a cache of the conformance
descriptor for a given `T: P`, potentially filtered by a module (when
requested). Clients of the conformance cache can choose how to interpret
the protocol conformance descriptor, e.g., by instantiating a witness table.
We can bring back a specific conformance cache for swift_conformsToProtocol()
if it is profitable.
(cherry picked from commit 0af2af00a739a4d912d2a9c3b196449e4164484f)
We should also allow references via manglings just to cover the
general case if we need it, but this is useful on its own so that
we can emit a reference to any natively-declared Swift type.
Rename the funnel points for demangling strings/nodes to metadata to
swift_getTypeByMangled(Name|Node) and make them overridable. This will let
us back-deploy mangling improvements and bug fixes.
Clean up the interfaces used to go from a mangled name or demangle tree to
metadata. Parameterize these interfaces for generic parameter substitutions
(already in use) and dependent conformance substitutions (speculative).
When we are looking for the specific type for a protocol conformance (e.g.,
because we may have a subclass of the type that declared conformances), don't
go back through swift_conformsToProtocol() multiple times, which
requires more lookups in the global conformance table. Instead, use
the (known) protocol conformance descriptor.
TargetGenericParamRef is a specialized structure used to describe the
subject of a generic requirement, e.g., the “T.Assoc” in “T.Assoc: P”.
Replace it with a mangled name, for several reasons:
1) Mangled type names are also fairly concise, can often be shared, and
are a well-tested path
2) Mangled type names can express any type, which might be useful in the
future
3) This structure doesn’t accommodate specifically stating where the
conformances come from (to extract associated type witnesses). Neither
can mangled names, but we’d like to do that work in only one place.
This change exposed an existing bug where we improperly calculated the
generic parameter counts for extensions of nested generic types. Fix that
bug here (which broke an execution test).
This runtime function doesn’t always perform instantiation; it’s how we
get a witness table given a conformance, type, and set of instantiation
arguments. Name it accordingly.
Witness table accessors return a witness table for a given type's
conformance to a protocol. They are called directly from IRGen
(when we need the witness table instance) and from runtime conformance
checking (swift_conformsToProtocol digs the access function out of the
protocol conformance record). They have two interesting functions:
1) For witness tables requiring instantiation, they call
swift_instantiateWitnessTable directly.
2) For synthesized witness tables that might not be unique, they call
swift_getForeignWitnessTable.
Extend swift_instantiateWitnessTable() to handle both runtime
uniquing (for #2) as well as handling witness tables that don't have
a "generic table", i.e., don't need any actual instantiation. Use it
as the universal entry point for "get a witness table given a specific
conformance descriptor and type", eliminating witness table accessors
entirely.
Make a few related simplifications:
* Drop the "pattern" from the generic witness table. Instead, store
the pattern in the main part of the conformance descriptor, always.
* Drop the "conformance kind" from the protocol conformance
descriptor, since it was only there to distinguish between witness
table (pattern) vs. witness table accessor.
* Internalize swift_getForeignWitnessTable(); IRGen no longer needs to
call it.
Reduces the code size of the standard library (+assertions build) by
~149k.
Addresses rdar://problem/45489388.
When searching the superclasses at runtime, e.g., to find a suitable
protocol conformance record, also consider the superclasses of CF
types, which were recorded in the metadata but otherwise unused.
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.
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.
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.
Use SubstGenericParametersFromMetadata to handle substitutions when
checking generic requirements, extending SubstGenericParametersFromMetadata
for this purpose.
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.
Generic parameter references, which occur in generic requirement
metadata, were hardcoding associated type indices. Instead, use
relative references to associated type descriptors and perform the
index calculation at runtime.
Associated types can now be reordered resiliently (without relying on
sorting), which is the first main step toward rdar://problem/44167982.
As part of this, rename TypeMetadataRecordKind to TypeReferenceKind
and consistently give it three bits of storage.
The better modelling of these type references appears to have been
sufficient to make dynamic conformance checks succeed, which is good
but unexpected.
Reimplement protocol descriptors for Swift protocols as a kind of
context descriptor, dropping the Objective-C protocol compatibility
layout. The new protocol descriptors have several advantages over the
current implementation:
* They drop all of the unused fields required for layout-compatibility
with Objective-C protocols.
* They encode the full requirement signature of the protocol. This
maintains more information about the protocol itself, including
(e.g.) correctly encoding superclass requirements.
* They fit within the general scheme of context descriptors, rather than
being their own thing, which allows us to share more code with
nominal type descriptors.
* They only use relative pointers, so they’re smaller and can be placed
in read-only memory
Implements rdar://problem/38815359.
In a generic requirement, distinguish between Swift and
Objective-C protocols using a spare bit within the relative
(indirectable) reference to the protocol.
The runtime hash table for protocol conformances is keyed by (type, protocol),
where the type can be either a type metadata pointer or a type context
descriptor. The latter is preferred for generic and resilient types, because
a single entry in the cache can work for any instantiation.
However, not all type metadata has a corresponding type context descriptor.
For example, a class that is dynamically subclassed by the Objective-C
runtime won't have a type context descriptor. In such cases, our key
into the hash table was (NULL, protocol) leading to mistaken
conformances for different dynamically-subclassed types.
Introduce a NULL check for the type of the hash table key, which
illustrates the problem in a number of existing tests that exercise
the runtime, and teach the runtime to use the type context descriptor
as the key only when it's non-NULL, falling back to the type metadata
pointer otherwise.
Fixes rdar://problem/38053213.
Minimize the generic class metadata template by removing the
class header and base-class members. Add back the set of
information that's really required for instantiation.
Teach swift_allocateGenericClass how to allocate classes without
superclass metadata. Reorder generic initialization to establish
a stronger phase-ordering between allocation (the part that doesn't
really care about the generic arguments) and initialization (the
part that really does care about the generic arguments and therefore
might need to be delayed to handle metadata cycles).
A similar thing needs to happen for resilient class relocation.
@objc protocols don't have witness tables. However, both type metadata
(in the nominal type descriptors) and the runtime code to demangle
type names into metadata weren't acknowledging this. Fix type metadata
emission to not count an "extra argument" for @objc protocol
conformance requirements, and teach the runtime code to properly look
for conformances to @objc protocols (through the Objective-C runtime)
and not record witness tables for them.
When evaluating whether a given type conforms to a protocol, evaluate the
conditional requirements and pass the results to the witness table
accessor function. This provides the ability to query conditional
conformances at runtime, and is the last major part of implementing
SE-0143.
The newly-added unlock/lock dance in the conformance lookup code is a
temporary stub. We have some ideas to do this better.
Fixes rdar://problem/34944655.
Extend the runtime's ability for evaluating generic requirements to
handle same-type requirements, demangling/substituting the name from
the generic requirement metadata.
Extend support for mapping a mangled name -> type metadata to include
support for checking protocol conformance requirements, using the
encoding of generic requirements that is now available within context
descriptors. For example, this allows
_typeByMangledName(mangled-name-of-Set<Int>) to construct proper type
metadata, filling in the Int: Hashable requirement as appropriate.
This is useful when trying to track down data corruption in the runtime. I am
currently running into such issues with the +0-all-arg work, so I am adding
stuff like this to help debug this issue and future such issues.
rdar://34222540