This sets the 'requires instantiation' bit in a couple more cases, which
doesn't really matter because the runtime already checks a few other
conditions, such as the presence of resilient witnesses.
The condition for "needs a generic witness table" was wrong; any
conformance with associated conformances would get one, even though
its only necessary if the associated conformances are dependent.
Fixing this also allows simplifying some code.
If the conforming type is generic, we have to treat the conformance as
resilient if it is defined outside of the current module.
This is because it can resiliently change from being non-dependent
to dependent.
When calling a witness table accessor, IRGen was forcing the
conforming type to have complete metadata, even though only abstract
metadata is required for that query. This could cause cyclic metadata
dependencies when checking conditional conformances.
Fixes SR-5958.
This method wasn’t returning the protocol on which the that the witness
method would satisfy, as documented. Rather, it was returning the protocol
to which the `Self` type conforms, which could be completely unrelated. For
example, in IndexingIterator’s conformance to IteratorProtocol, this method
would produce the protocol “Collection”, because that’s where the witness
itself was implemented. However, there isn’t necessarily a single such
protocol, so checking for/returning a single protocol was incorrect.
It turns out that there were only a few SIL verifier assertions of it
(that are trivially true) and two actual uses in code:
(1) The devirtualizer was using this computation to decide when it didn’t
need to perform any additional substitutions, but it’s predicate for doing
so was essentially incorrect. Instead, it really wanted to check whether
the Self type is still a type parameter.
(2) Our polymorphic convention was using it to essentially check whether
the ’Self’ instance type of a witness_method was a GenericTypeParamType,
which we can check directly.
Fixes rdar://problem/47767506 and possibly the hard-to-reproduce
rdar://problem/47772899.
Protocol descriptors for resilient protocols relatively-reference
default witness thunks, so when using -num-threads N with N > 1,
we must ensure the default witness thunk is emitted in the same
LLVM module.
Protocol descriptors for resilient protocols relatively-reference
default witness thunks, so when using -num-threads N with N > 1,
we must ensure the default witness thunk is emitted in the same
LLVM module.
We've been running doxygen with the autobrief option for a couple of
years now. This makes the \brief markers into our comments
redundant. Since they are a visual distraction and we don't want to
encourage more \brief markers in new code either, this patch removes
them all.
Patch produced by
for i in $(git grep -l '\\brief'); do perl -pi -e 's/\\brief //g' $i & done
Resilient conformances now put all witnesses into the resilient witness
table, so optimize away the witness table pattern for such cases. Teach
the runtime to fill in the protocol conformance descriptor, because that’s
the only bit of real information that would be in the pattern.
This is a minor optimization enabled by rdar://problem/46282080.
Emit mangled inherited protocol witnesses into the resilient witness table,
and realize them when we instantiate the resilient witness table. Don’t
put mangled inherited protocol witnesses into non-resilient witness tables:
there is no efficient way to make sure they are realized, so keep the
previous instantiation-function approach.
Implements the rest of rdar://problem/46282080.
Now that the runtime fills in the private slots with conditional requirement
information, we can always use mangled names for inherited conformances.
Fixes rdar://problem/46282080.
Rather than having the witness table instantiation function copy the
instantiation arguments that corresponding to conditional requirements
into the private area, have the runtime do it. We’re going to depend on
these lining up anyway (and the witness table can of course have *more*
private slots that it manages some other way), so centralize the code.
More of rdar://problem/46282080.
Rather than setting the witness tables for base protocols in a witness
table’s instantiation function, use mangled names as we do for
associated conformances. The runtime will eagerly realize them so clients
of witness tables are not affected.
For now, only do this for unconditional conformances: conditional
conformances won’t work yet because the instantiation function currently
copies the instantiation arguments (which satisfy the conditional
requirements) in to the private area. The runtime will need to take over
this responsibility for conditional conformances to work.
Part of rdar://problem/46282080.
When a (file)private entity occurs inside a generic context, we still need
information about the genericity of the enclosing context to demangle
to metadata. Emit complete context descriptors for parents of anonymous
contexts.
Fixes rdar://problem/46109026.
Extend the key-path pattern with a representation of the generic environment
of the key-path, which includes the generic parameters and generic
requirements of the environment.
The runtime can choose to re-use the pattern of a witness table if in fact
there is nothing dependent about it. Only mark the pattern as constant
when we know it has no inline caching behavior.
The current representation of an associated conformance in a witness
tables (e.g., Iterator: IteratorProtocol within a witness table for
Sequence) is a function that the client calls.
Replace this with something more like what we do for associated types:
an associated conformance is either a pointer to the witness table (once
it is known) or a pointer to a mangled name that describes that
conformance. On first access, demangle the mangled name and replace the
entry with the resulting witness table. This will give us a more compact
representation of associated conformances, as well as always caching
them.
For now, the mangled name is a sham: it’s a mangled relative reference to
the existing witness table accessors, not a true mangled name. In time,
we’ll extend the support here to handle proper mangled names.
Part of rdar://problem/38038799.
Introduce a new runtime entry point, swift_getAssociatedConformanceWitness(),
which extracts an associated conformance witness from a witness table.
Teach IRGen to use this entry point rather than loading the witness
from the witness table and calling it directly.
There’s no advantage to doing this now, but it is staging for changing the
representation of associated conformances in witness tables.
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.
The “requires instantiation” bit for protocol conformances that
might require runtime instantiation was set for essentially every
resilient conformance, so we would always be forced to create a
copy of the table. Narrow the “requires instantiation” bit to those
cases where there is something in the pattern that needs it to be
copied (for now, only associated type witnesses involving a type
parameter, which need to be cached differently). This optimizes
some narrow cases where we wouldn’t otherwise need a copy.
Simplify calls to getAddrOfLLVMVariableOrGOTEquivalent() and
getAddrOfLLVMVariable() by moving the computation of the alignment and
default type into LinkEntity.
Co-authored-by: Joe Groff <jgroff@apple.com>
Collapse the generic witness table, which was used only as a uniquing
data structure during witness table instantiation, into the protocol
conformance record. This colocates all of the constant protocol conformance
metadata and makes it possible for us to recover the generic witness table
from the conformance descriptor (including looking at the pattern itself).
Rename swift_getGenericWitnessTable() to swift_instantiateWitnessTable()
to make it clearer what its purpose is, and take the conformance descriptor
directly.
The former appears in the code base a lot more frequently than the
latter, which returns a GenericTypeParamType *. Use it only in places
where the more specific type is intended.
Place resilient witnesses in the protocol conformance descriptor,
tail-allocated after the conditional requirements, so they can be found by
reflection. Drop the resilient witness table and protocol descriptor from
the generic witness table.
Addresses rdar://problem/45228582.
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.
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.
swift_getAssociatedTypeWitness() is logically readnone because it is the
only function that accesses associated type witness information within the
witness table. Mark calls to it as readnone and nounwind.
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.
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.