The layout changes to become relative-address based. For this to be
truly immutable (at least on Darwin), things like the RO data patterns
must be moved out of the pattern header. Additionally, compress the
pattern header so that we do not include metadata about patterns that
are not needed for the type.
Value metadata patterns just include the metadata kind and VWT.
The design here is meant to accomodate non-default instantiation
patterns should that become an interesting thing to support in the
future, e.g. for v-table specialization.
This is simpler, because the native form of that last argument is: a
pointer to a buffer (*) of pointers (*) to witness tables, which is
modelled as a buffer of void *s. Thus, void ***.
Change the "metadata base offset" variable into a "class metadata bounds"
variable that contains the base offset and the +/- bounds on the class.
Link this variable from the class descriptor when the class has a resilient
superclass; otherwise, store the +/- bounds there. Use this variable to
compute the immediate-members offset for various runtime queries. Teach the
runtime to fill it in lazily and remove the code to compute it from the
generated code for instantiation. Identify generic arguments with the start
of the immediate class metadata members / end of the {struct,enum} metadata
header and remove the generic-arguments offset from generic type descriptors.
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.
This is yet another waypoint on the path towards the final
generic-metadata design. The immediate goal is to make the
pattern a private implementation detail and to give the runtime
more visibility into the allocation and caching of generic types.
The dumper method dumps:
1. The container's metadata pointer.
2. A pointer to the container's value.
3. Whether or not said value is stored inline in the container.
This provides a general overview that can be used even when working with SIL
code in the debugger by grabbing a pointer to swift Anys and then calling the
c++ any method upon them.
The verifier is intended to be used in conjunction with ASAN for maximum
effect to catch use-after-frees of existential boxes.
While implementing this I refactored some code from ExistentialTypeMetadata into
methods on OpaqueExistentialContainer. ExistentialTypeMetadata just calls these
methods now instead of implementing the code inline.
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.
We dump the following information:
1. The Kind.
2. Pointer to the value witnesses.
3. Pointer to the class object if one is available.
4. Pointer the type context description if one is available.
5. Pointer to the generic arguments if one is available.
This makes it significantly easier to poke around Metadata.
rdar://34222540
This new format more efficiently represents existing information, while
more accurately encoding important information about nested generic
contexts with same-type and layout constraints that need to be evaluated
at runtime. It's also designed with an eye to forward- and
backward-compatible expansion for ABI stability with future Swift
versions.
* Remove RegisterPreservingCC. It was unused.
* Remove DefaultCC from the runtime. The distinction between C_CC and DefaultCC
was unused and inconsistently applied. Separate C_CC and DefaultCC are
still present in the compiler.
* Remove function pointer indirection from runtime functions except those
that are used by Instruments. The remaining Instruments interface is
expected to change later due to function pointer liability.
* Remove swift_rt_ wrappers. Function pointers are an ABI liability that we
don't want, and there are better ways to get nonlazy binding if we need it.
The fully custom wrappers were only needed for RegisterPreservingCC and
for optimizing the Instruments function pointers.
clang is miscompiling some swiftcall functions on armv7s.
Stop using swiftcall in some places until it is fixed.
Reverts c5bf2ec (#13299).
rdar://35973477
The prior refactoring to add the protocol conformance descriptor into
witness tables offset the # of requirements stored in the witness
table by 1. Address this oddity in the metadata by ensuring that the #
of requirements (and # of mandatory requirements) in the protocol
descriptor is accurate.
Extend witness tables with a pointer to the protocol conformance
descriptor from which the witness table was generated. This will allow
us to determine (for example) whether two witness tables were
generated from the same (or equivalent) conformances in the future, as
well as discover more information about the witness table itself.
Fixes rdar://problem/36287959.
Swift-defined @objc protocols are registered with the Objective-C runtime
under the Swift 3 mangling scheme; look in the Objective-C runting using
objc_getProtocol() with the appropriate name.
Also, correctly compute the "class bound" bit when forming a protocol
composition metatype. The information isn't in the mangled name when it
can be recovered from the protocols themselves, so look at the protocols.
TypeDecoder's interface with its builders already treated protocols as
a type (due to their being mangled as "protocol composition containing
one type"), and intermixed protocols with superclasses when forming
compositions. This makes for some awkwardness when working with
protocol descriptors, which are very much a distinct entity from a
type.
Separate out the notion of a "protocol declaration" (now represented
by the builder-provided BuiltProtocolDecl type) from "a protocol
composition containing a single type", similarly to the way we handle
nominal type declarations. Teach remote mirrors and remote AST to
handle the new contract.
Introduce a flags parameter to swift_getTupleTypeMetadata(). Add a flag
stating when the "labels" parameter points into nonconstant memory, in
which case we need to make a copy of the string before adding an entry
into the concurrent map.
Since it's not very common to use such ABI endpoints, let's remove
them and use the most general one `swift_getFunctionTypeMetadata`
instead when function parameters have flags attached to them.
Resolves: rdar://problem/36278686
This ABI endpoint is used to retrieve metadata about functions
without parameters. Which is very common use-case and it
makes sense to save some code size for that.
Nominal type descriptors are not always unique, so testing them via pointer
equality is not correct. Introduce an "isEqual()" operation for
nominal type descriptors that performs the appropriate equality check,
using pointer equality when possible, and falling back to string
comparisons of the mangled type name when it is not possible.
Introduce a "nonunique" flag into nominal type descriptors to describe
when they are, in fact, not unique. The only nonunique nominal type
descriptors currently come from Clang-imported types; all
Swift-defined types have unique nominal type descriptors. Use this
flag to make the aforementioned operation efficient in the "unique"
case.
Use the new isEqual() operation for protocol conformance lookup, and
make sure we're caching results based on the known-canonical nominal
type descriptor.
If the nominal type descriptor's resilient superclass flag
is set, the generic parameter offset, vtable start offset
and field offset start offset are all relative to the
start of the class's immedaite members, and not the start
of the class metadata.
Support this by loading the size of the superclass and
adding it to these offsets if the flag is set.
- Create the value witness table as a separate global object instead
of concatenating it to the metadata pattern.
- Always pass the metadata to the runtime and let the runtime handle
instantiating or modifying the value witness table.
- Pass the right layout algorithm version to the runtime; currently
this is always "Swift 5".
- Create a runtime function to instantiate single-case enums.
Among other things, this makes the copying of the VWT, and any
modifications of it, explicit and in the runtime, which is more
future-proof.
We can reduce the uniquing header from 3–4 pointer-sized words down to 1–2 32-bit words + one pointer:
- The initialization function (when present) and name are always emitted into the same binary image, so we can use relative references to shrink these down to 32-bit fields.
- We don't ever simultaneously need the initialization flags and the initialized uniqued pointer. (Keeping the "initialization function" flag bit theoretically lets us turn a "consume" load into a "relaxed" load, but that makes no practical difference on most contemporary architectures.) 12 flag bits Ought To Be Enough For Anyone and lets us reliably tell a valid pointer from a flag set, so overlap the initialization flags with the eventual invasive cache value.
The invasive cache is left inline, since we've decided we're not going to make the rest of type metadata records ever be true-const, so they'll already be sitting on a dirty page. A dynamic linker that was sufficiently Swift-optimized to precalculate the other load-time-initialized entries in metadata could likely precompute the invasive cache value as well.
rdar://problem/22527141
NFC intended. The layout of trailing matter here is getting fairly complex, so it's good to use LLVM's existing library code to keep track of it. We use a fork of llvm's TrailingObjects.h header so that future changes to LLVM don't disturb the ABI of Swift runtime objects that use the template.
Don't emit placeholders for field offsets and vtable entries,
since they were always null. Instead, calculate the final size
of class metadata at runtime using the size of the superclass
metadata and the number of immediate members, and only copy
this prefix from the template to the instantiated metadata,
zero-filling the rest.
For this to work with non-generic resilient classes and
non-generic subclasses of generic classes, we need a new
runtime entry point to relocate non-generic class metadata,
calculating its size at runtime using the same strategy.
When allocating metadata for a generic class we would copy
any prefix matter from the superclass metadata, if the
superclass metadata's address point was greater than our
address point.
While we may use prefix matter for resilient metadata
in the future, I don't believe just copying bytes like
this will prove useful.
Switch most general endpoint to be `flags, parameters, parameterFlags, result`,
instead of opaque `void **`, more specialized ones to use follow argument scheme:
`flags, param0, [flags0], ..., paramN, [flagsN], result` and store parameter/flags
information separately in `FunctionCacheEntry::{Key, Data}` as well.
Currently only single 'inout' flag has been encoded into function
metadata, these changes extend function metadata to support up to
32 flags per parameter.