The only initialization these class objects need is ObjC realization, which can be done
fast with `objc_opt_self` on recent Apple OSes. The cache check just adds code size and
dirties memory.
Some metadata may require instantiation, but not in a way that requires us to put an additional
cache layer in front of it. `Self` metadata is also trivial to access from the local cache, but
isn't statically referenceable. Split these concepts and update code to use one or the other
appropriately. This catches an issue with metadata prespecialization where it would try to
make records for dynamic `Self` incorrectly.
When a specialized usage of a generic enum occurs in the same module
where the enum was defined, directly reference the prespecialized
metadata.
rdar://problem/56994321
To achieve this replace the current implementation which recursively
constructs a layout compatible metadata by an implementation that
recursively constructs a layout compatible type and the use
emitTypeMetadataRef on that type to generate the metadata.
Previously, some ad hoc checks were done in order to determine whether
the metadata access for a generic type was trivial. Now, standard
predicates are used, specifically IRGenModule's member functions
isDependentConformance and isResilientConformance.
Previously, when emitting the metadata accessor, the generic arguments
of the type were enumerated one after the next. That was fine in most
cases but is incorrect in cases where the actual number of generic
arguments is less than apparent number as when two arguments are required
to be equal.
Now, the arguments are enumerated according to the requirements vended by
the GenericTypeRequirements struct.
Recently we started using the runtime demangler to realize imported
Objective-C class metadata, to save on code size since no metadata
accessor function needs to be emitted in this case.
This introduced a regression where OBJC_CLASSREF symbols were no
longer being emitted in some cases, which breaks autolinking.
The fix for this was tracked by rdar://56136123, but unfortunately
had to be reverted because it caused other problems.
Until the original fix can be re-applied, let's put in a temporary
workaround where we avoid going through the runtime demangler for
imported Objective-C classes. This regresses code size but unblocks
everyone involved, until the fix for the demangling code path
(8247525471) can be re-applied.
Fixes <rdar://56621277>.
Metadata accessors are dependent on prespecializations of the metadata
of generic, in-module types. Those prespecializations are themselves
dependent on usages of the types in functions. Consequently, the
accessors must be emitted after all the functions are emitted.
When possible, directly reference metadata prespecializations. Doing so
is possible when the type is defined in the same module, because in
those cases the metadata accessor can be modified to ensure that the
prespecialized metadata is canonical.
rdar://problem/56994171
For every prespecialization of generic metadata that exists in the
module where the generic type is defined, the metadata accessor gains
code with the following effect
switch arguments {
case prespecialization1.genericArguments:
return prespecialization1
case prespecialization2.genericArguments:
return prespecialization2
...
default:
return swift_getGenericMetadata(...)
}
rdar://problem/56961700
When emitting a reference to the metadata for a generic type, prepare
to, rather than always inserting calls to the type metadata access
function, emit direct references to static specializations when possible
and emit calls to the forthcoming swift_getCanonicalSpecializedMetadata
when not possible.
For now, the metadata access function is always called.
use getTypeByMangledName when abstract metadata state is requested
This can significantly reduce the code size of apps constructing deeply
nested types with conditional conformances.
Requires a new runtime.
rdar://57157619
ProtocolConformanceRef already has an invalid state. Drop all of the
uses of Optional<ProtocolConformanceRef> and just use
ProtocolConformanceRef::forInvalid() to represent it. Mechanically
translate all of the callers and callsites to use this new
representation.
We can't access types in the same module if they are private: they could
be in a different TU.
We can't access types from different modules if they are private or
internal.
Some more information can be gleaned from the resilience expansion: A
minimally resilient function can't reference private or internal types.
rdar://56093964
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!)
box descriptors
We want to substitute opaque result types in addTypeRef but when we pass
SILFunctionTypes this would fail because AST type substitution does not
support lowered SIL types.
Instead add addLoweredTypeRef which substitutes based on SILTypes.
rdar://54529445
In too many places, we were calling into `emitDynamicTypeOfOpaqueHeapObject` even when we had
more specific type information about the heap object we were querying. Replace all calls with
`emitDynamicTypeOfHeapObject`, which uses the best available access path and completely avoids
runtime calls for pure Swift classes and heap objects. When targeting non-ObjC-interop platforms,
we also know we never need to call `swift_getObjectType`, so avoid doing so altogether.
This indicates that the "self" argument to the current function is always dynamically of the exact
static base class type, allowing metadata accesses in IRGen to use the local self metadata to answer
metadata requests for the class type. Set this attribute on allocating entry points of designated
inits, which is one of the most common places where we emit redundant metadata accesses.
Class methods always have a "self" argument that can be used to get the metadata of the dynamic
Self type, which in final classes is always the same as the statically-known base class. Use this
to avoid reconstructing the static base class type.
The Swift 5.1 runtime (and master, for the time being) do not successfully demangle this mangling,
so for the time being, fall back to open-coded metadata access in this case. Workaround for
rdar://problem/54084733.
If we're allowed to know at IRGen time what the underlying type of an opaque type is, we can
satisfy references to the opaque type's metadata or protocol witness tables by directly referencing
the underlying type instead.