Bitwise takability is now part of the layout of a type, because
non-bitwise takable types are never stored inline in an
existential or resilient global's buffer, even if they would
fit.
The basic rule is that weak references, unknown-refcounted
unowned references, and aggregates that contain them, are not
bitwise takable, whereas everything else is bitwise takable.
Also, since the bitwise takable for an unowned reference
depends on the reference counting style, we have to record the
superclass of a protocol, if any, to correctly determine the
reference counting style of the protocol existential.
In order to handle LinkOnceODR semantics correctly across various object
formats, introduce a new helper ApplyIRLinkage. This abstracts the need
to create a COMDAT group and set it on the GlobalValue. Adjust all
sites where we set the IR linkage attributes to use this mechanism
instead to avoid having to track down symbols not being added to a
COMDAT group.
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.
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.
This makes it easier to grep for and eventually remove the
remaining usages.
It also allows you to write FunctionType::get({}, ...) to call the
ArrayRef overload empty parameter list, instead of picking the Type
overload and calling it with an empty Type() value.
While I"m at it, in a few places instead of renaming just clean up
usages where it was completely mechanical to do so.
This saves us some expensive cross-referencing and caching in the runtime, and lets us reclaim the `isReflectable` bit from the context descriptor flags (since a null field descriptor is a suitable and more accurate indicator of whether a type is reflectable).
We’re not using this parameter, and don’t expect to do so in the future,
so remove it. Also fold away TypeBase::usesNativeReferenceCounting()
and irgen::getReferenceCountingForType(), both of which are trivial.
The TypeDecoder doesn't support the new box mangling yet and instead
just decodes it as Builtin.NativeObject, but that's OK because the
Remote Mirrors lowered the old box mangling as Builtin.NativeObject
anyway.
This makes resolving mangled names to nominal types in the same module more efficient, and for eventual secrecy improvements, also allows types in the same module to be referenced from mangled typerefs without encoding any source-level name information about them.
Update IRGen to trigger generation of type metadata for foreign
struct types found in fields. And fix TypeRefBuilder to handle
the case where struct has fields but at the same time has opaque
metadata.
The mangled name of protocol descriptors was the “protocol composition”
type consisting of a single protocol, which is a little odd. Instead,
use a bare protocol reference (e.g., “6Module5ProtoP”) with the “$S”
prefer to be more in line with nominal type descriptor names while still
making it clear that this is a Swift (not an Objective-C) protocol.
Restructure the COFF metadata handling to use the linker section
grouping to emit section start/stop markers in the appropriate location.
This allows us to lookup the sections statically without having to the
walk the entire image structure.
Introduce a constructor for PE/COFF binaries. This will ensure that the
registration occurs for all modules appropriately. This should resolve
rdar://problem/19045112. The registration should occur prior to
`DllMain` being invoked from `DllMainCRTStartup`.
Restructure the ELF handling to be completely agnostic to the OS.
Rather than usng the loader to query the section information, use the
linker to construct linker tables and synthetic markers for the
beginning and of the table. Save off the values of these pointers and
pass them along through the constructor to the runtime for registration.
This removes the need for the begin/end objects. Remove the special
construction of the begin/end objects through the special assembly
constructs, preferring to do this in C with a bit of inline assembly to
ensure that the section is always allocated.
Remove the special handling for the various targets, the empty object
file can be linked on all the targets.
The new object file has no requirements on the ordering. It needs to
simply be injected into the link.
Name the replacement file `swiftrt.o` mirroring `crt.o` from libc. Merge
the constructor and the definition into a single object file.
This approach is generally more portable, overall simpler to implement,
and more robust.
Thanks to Orlando Bassotto for help analyzing some of the odd behaviours
when switching over.
Rather than storing contextual types in the type witnesses and associated
conformances of NormalProtocolConformance, store only interface types.
@huonw did most of the work here, and @DougGregor patched things up to
complete the change.
@objc enums lower as their raw type, so should go through the same
code path as imported enums.
Fixes <https://bugs.swift.org/browse/SR-5625> and
<rdar://problem/33683103>.
ground work for the syntactic bridging peephole.
- Pass source and dest formal types to the bridging routines in addition
to the dest lowered type. The dest lowered type is still necessary
in order to handle non-standard abstraction patterns for the dest type.
- Change bridging abstraction patterns to store bridged formal types
instead of the formal type.
- Improve how SIL type lowering deals with import-as-member patterns.
- Fix some AST bugs where inadequate information was being stored in
various expressions.
- Introduce the idea of a converting SGFContext and use it to regularize
the existing id-as-Any conversion peephole.
- Improve various places in SILGen to emit directly into contexts.
As a step toward eliminating the single input type
representation of function parameters, add more constraints on that
input type. It can be one of:
* A tuple type, for multiple parameters,
* A parenthesized type, for a single parameter, or
* A type variable type, for specific cases in the type checker
Enforce these constraints for *canonical* types as well, so the
canonical form of:
typealias MyInt = Int
typealias MyFuncType = (MyInt) -> Int
is now:
(Int) -> Int
rather than:
Int -> Int
This affects canonicalization of FunctionType and
GenericFunctionType. Enchance both, as well as their Can*Type
counterparts, with "get" operators that take an array of
AnyFunctionType::Param, and start switching a few clients over to this
new, preferred API.
The "superclass as associated type" modeling was put in to
maintain backward compatibility.
We just bumped the version number because of new mangling so
we may as well fix this sillyness too.
Add a 'hasExplicitAnyObject()' bit to ProtocolCompositionType
to represent canonical composition types containing '& AnyObject'.
Serialize this bit and take it into account when building
ExistentialLayouts.
Rename ProtocolCompositionType::getProtocols() to getMembers()
since it can contain classes now, and update a few usages that
need further attention with FIXMEs or asserts.
For now, nothing actually constructs these types, and they will
trigger arounds asserts. Upcoming patches will introduce support
for this.