When allocating, the shape is computed, and it (its constant value if
any) is needed when deallocating, so return the shape along with the
address. And when deallocating, accept the shape, which the client
received during allocation, rather than requiring that the caller
compute the fixed size.
* [Executors][Distributed] custom executors for distributed actor
* harden ordering guarantees of synthesised fields
* the issue was that a non-default actor must implement the is remote check differently
* NonDefaultDistributedActor to complete support and remote flag handling
* invoke nonDefaultDistributedActorInitialize when necessary in SILGen
* refactor inline assertion into method
* cleanup
* [Executors][Distributed] Update module version for NonDefaultDistributedActor
* Minor docs cleanup
* we solved those fixme's
* add mangling test for non-def-dist-actor
We don't have any language or runtime support for noncopyable types as generic
or dynamic types yet, and existing reflection code almost certainly assumes it
can copy the values it's working with, and will trap or corrupt state if it does
so with noncopyable types. But a class can have noncopyable fields while the
type itself is copyable, and existing code assumes that it can use `Mirror` or
other reflection mechanisms to safely traverse the contents of an arbitrary
class.
Allow this sort of code to continue working, while still preparing for forward
compatibility with future runtimes that do support noncopyable generics, by
emitting the type references for fields using a function that probes the
address of a new symbol in the Swift runtime. The symbol will either be missing
or defined with an absolute address of zero in current or previous runtime
versions, but can be changed to a non-null address in the future.
A lot of the fixes here are adjustments to compensate in the
fulfillment and metadata-path subsystems for the recent pack
substitutions representation change. I think these adjustments
really make the case for why the change was the right one to make:
the code was clearly not considering the possibility of packs
in these positions, and the need to handle packs makes everything
work out much more cleanly.
There's still some work that needs to happen around type packs;
in particular, we're not caching them or fulfilling them as a
whole, and we do have the setup to do that properly now.
For now these are completely resilient blobs, which is wrong
because it prevents us from being able to model something like
(Int, repeat each T, String).
But one step at a time...
rdar://105837040
* WIP: Store layout string in type metadata
* WIP: More cases working
* WIP: Layout strings almost working
* Add layout string pointer to struct metadata
* Fetch bytecode layout strings from metadata in runtime
* More efficient bytecode layout
* Add support for interpreted generics in layout strings
* Layout string instantiation, take and more
* Remove duplicate information from layout strings
* Include size of previous object in next objects offset to reduce number of increments at runtime
* Add support for existentials
* Build type layout strings with StructBuilder to support target sizes and metadata pointers
* Add support for resilient types
* Properly cache layout strings in compiler
* Generic resilient types working
* Non-generic resilient types working
* Instantiate resilient type in layout when possible
* Fix a few issues around alignment and signing
* Disable generics, fix static alignment
* Fix MultiPayloadEnum size when no extra tag is necessary
* Fixes after rebase
* Cleanup
* Fix most tests
* Fix objcImplementattion and non-Darwin builds
* Fix BytecodeLayouts on non-Darwin
* Fix Linux build
* Fix sizes in linux tests
* Sign layout string pointers
* Use nullptr instead of debug value
- SILPackType carries whether the elements are stored directly
in the pack, which we're not currently using in the lowering,
but it's probably something we'll want in the final ABI.
Having this also makes it clear that we're doing the right
thing with substitution and element lowering. I also toyed
with making this a scalar type, which made it necessary in
various places, although eventually I pulled back to the
design where we always use packs as addresses.
- Pack boundaries are a core ABI concept, so the lowering has
to wrap parameter pack expansions up as packs. There are huge
unimplemented holes here where the abstraction pattern will
need to tell us how many elements to gather into the pack,
but a naive approach is good enough to get things off the
ground.
- Pack conventions are related to the existing parameter and
result conventions, but they're different on enough grounds
that they deserve to be separated.
For spatial locality on startup.
Hide collocating metadata functions in a separate section behind a flag.
The default is not to collocate functions.
rdar://101593202
This reverts commit 3617b7603c, reversing
changes made to 58a519a5c1.
This causes issues for the linker and branches accross sections if
addresses are too far apart.
This reverts commit 1f3e159cfe, reversing
changes made to 103b4a89c2.
Re-applies "IRGen: Co-locate metadata instatiation/completions/accessor
functions in a special section" for MachO only. The original change broke lldb
on aarch64 linux.
rdar://102481054
In preparation for moving to llvm's opaque pointer representation
replace getPointerElementType and CreateCall/CreateLoad/Store uses that
dependent on the address operand's pointer element type.
This means an `Address` carries the element type and we use
`FunctionPointer` in more places or read the function type off the
`llvm::Function`.
These will never appear in the source language, but can arise
after substitution when the original type is a tuple type with
a pack expansion type.
Two examples:
- original type: (Int, T...), substitution T := {}
- original type: (T...), substitution T := {Int}
We need to model these correctly to maintain invariants.
Callers that previously used to rely on TupleType::get()
returning a ParenType now explicitly check for the one-element
case instead.
Since I am beginning to prepare for adding real move only types to the language,
I am renaming everything that has to do with copyable types "move only wrapped"
values instead of move only. The hope is this reduces/prevents any confusion in
between the two.
for plain protocol and protocol composition types.
These types should always be wrapped in ExistentialType, but there isn't
sufficient validation of this throughout the compiler yet. Change
the fatal error when the metadata request sees these plain types to an
assert and restore the old type metadata emission path for protocol and
protocol composition types to avoid crashing in those cases.
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.
`readonly` (instead of `readnone`) because we want there to be a memory control
dependence on potential preceeding availability checks.
`willreturn` such that LLVM can remove calls without a use.
Starting with Android 11, AArch64 placed a tag in the top byte of pointers to
allocations, which has been slowly rolling out to more devices and collides
with Swift's tags. Moving these tags to the second byte works around this
problem.