The original check introduced by https://github.com/apple/swift/pull/71855
is too broad. For concrete metadata we call the runtime demangler so
we need to strip off marker protocols when mangling that string and
`mangleTypeForReflection` already does that.
For entities that must be part of the primary definition of a type,
mangle without inverses on the generic parameters of the enclosing
type. This ensures that we can adopt noncopyable on the generic
parameters without breaking the mangling of the fundamental entities
that describe the layout of the type.
Do this for enum elements first, so we don't break the mangling of
`Optional`. There will be other cases to consider as well.
Don't mangle inverse conformances for symbols related to dispatch thunks,
protocol members, and other entities that are inexorably tied to the
primary definition of the type and must have stable names.
Extend the conditional suppression of inverse conformance mangling to
property descriptors and more conformance-related symbols.
* [IRGen] Handle complex single payload enum cases
rdar://110138498
Handles single payload enum cases with more complex bit patterns (e.g. >64 bits or scattered) by storing a relative pointer to a function that reads the tag.
* Use proper symbol for enum tag helper
I wrote out this whole analysis of why different existential types
might have the same logical content, and then I turned around and
immediately uniqued existential shapes purely by logical content
rather than the (generalized) formal type. Oh well. At least it's
not too late to make ABI changes like this.
We now store a reference to a mangling of the generalized formal
type directly in the shape. This type alone is sufficient to unique
the shape:
- By the nature of the generalization algorithm, every type parameter
in the generalization signature should be mentioned in the
generalized formal type in a deterministic order.
- By the nature of the generalization algorithm, every other
requirement in the generalization signature should be implied
by the positions in which generalization type parameters appear
(e.g. because the formal type is C<T> & P, where C constrains
its type parameter for well-formedness).
- The requirement signature and type expression are extracted from
the existential type.
As a result, we no longer rely on computing a unique hash at
compile time.
Storing this separately from the requirement signature potentially
allows runtimes with general shape support to work with future
extensions to existential types even if they cannot demangle the
generalized formal type.
Storing the generalized formal type also allows us to easily and
reliably extract the formal type of the existential. Otherwise,
it's quite a heroic endeavor to match requirements back up with
primary associated types. Doing so would also only allows us to
extract *some* matching formal type, not necessarily the *right*
formal type. So there's some good synergy here.
One of the places where we ask whether a type's metadata should
be obtained via its mangled name was missing the newer, more
robust checking for minimum deployment target.
This pattern was really error-prone. I've fixed multiple bugs related
to CurGenericSignature not being set correctly at the right time, and
found another latent bug by inspection while doing this cleanup.
Mangling uses a generic signature is used to shorten member types
to just a name where the protocol is unambiguous.
Unfortunately, in the particular case of 'associated type paths',
the IRGen mangler did not consistently set the right signature.
Sometimes, it would use no signature, and other times it would use
the signature of the concrete conforming type, which is incorrect
because the member type is written relative to the root protocol's
generic signature, <Self : P>.
This was caught by some new assertions I'm adding to the rewrite
system.
Note that this changes the mangling of a few symbols, but none
are public in the ABI.
- Add `DispatchThunkDerivative` and `MethodDescriptorDerivative` as link entities. The derivative functions of initializers, subscripts, properties, and methods are **all methods**, so we don't need other link entities for this purpose.
- Mangle dispatch thunks and method descriptors. Make `AutoDiffFunction` a context node since it can be nested.
Resolves SR-13866 (rdar://71318828) and SR-13125 (rdar://65240599).
Emit a once token when adding canonical prespecialized metadata records
to a nominal type descriptor and add the token itself as a trailing
object to the type descriptor. The new token will, in subsequent
commits, enable the canonical prespecialized metadata records attached
to the type descriptor to be added to the metadata cache exactly once.
When a generic type from a different module is not resilient within the
current module and at least one of its arguments is from the current
module, emit a non-canonical prespecialized record, and access that
metadata via a call to swift_getCanonicalSpecializedMetadata, passing in
the non-canonical record.
rdar://problem/56996727
rdar://problem/56997022
When generic metadata for a class is requested in the same module where
the class is defined, rather than a call to the generic metadata
accessor or to a variant of typeForMangledNode, a call to a new
accessor--a canonical specialized generic metadata accessor--is emitted.
The new function is defined schematically as follows:
MetadataResponse `canonical specialized metadata accessor for C<K>`(MetadataRequest request) {
(void)`canonical specialized metadata accessor for superclass(C<K>)`(::Complete)
(void)`canonical specialized metadata accessor for generic_argument_class(C<K>, 1)`(::Complete)
...
(void)`canonical specialized metadata accessor for generic_argument_class(C<K>, count)`(::Complete)
auto *metadata = objc_opt_self(`canonical specialized metadata for C<K>`);
return {metadata, MetadataState::Complete};
}
where generic_argument_class(C<K>, N) denotes the Nth generic argument
which is both (1) itself a specialized generic type and is also (2) a
class. These calls to the specialized metadata accessors for these
related types ensure that all generic class types are registered with
the Objective-C runtime.
To enable these new canonical specialized generic metadata accessors,
metadata for generic classes is prespecialized as needed. So are the
metaclasses and the corresponding rodata.
Previously, the lazy objc naming hook was registered during process
execution when the first generic class metadata was instantiated. Since
that instantiation may occur "before process launch" (i.e. if the
generic metadata is prespecialized), the lazy naming hook is now
installed at process launch.
When an original module name is specified via @_originalDefinedIn attribute, we need to
use the original module name for all related runtime symbol names instead of the current
module names.
rdar://55268186
This removes it from the AST and largely replaces it with AnyObject
at the SIL and IRGen layers. Some notes:
- Reflection still uses the notion of "unknown object" to mean an
object with unknown refcounting. There's no real reason to make
this different from AnyObject (an existential containing a
single object with unknown refcounting), but this way nothing
changes for clients of Reflection, and it's consistent with how
native objects are represented.
- The value witness table and reflection descriptor for AnyObject
use the mangling "BO" instead of "yXl".
- The demangler and remangler continue to support "BO" because it's
still in use as a type encoding, even if it's not an AST-level
Type anymore.
- Type-based alias analysis for Builtin.UnknownObject was incorrect,
so it's a good thing we weren't using it.
- Same with enum layout. (This one assumed UnknownObject never
referred to an Objective-C tagged pointer. That certainly wasn't how
we were using it!)
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.
They aren't normally decl contexts, but if one has an opaque type, we want to be able to record
the property as a context so that we can reconstruct it in RemoteAST.
This is to support dynamic function replacement of functions with opaque
result type.
This approach requires that all state is thrown away (that could contain the
old returned type for an opaque type) between replacements.
rdar://48887938
When -enable-anonymous-context-mangled-names is provided, emit mangled
names as part of the metadata of an anonymous context. This will allow
us to match textual mangled names to the metadata.
This is a backward-compatible ABI extension. Part of rdar://problem/38231646/.