So far, static arrays had to be put into a writable section, because the isa pointer and the (immortal) ref count field were initialized dynamically at the first use of such an array.
But with a new runtime library, which exports the symbols for the (immortal) ref count field and the isa pointer, it's possible to put the whole array into a read-only section. I.e. make it a constant global.
rdar://94185998
This reverts the revert commit df353ff3c0.
Also, I added a frontend option to disable this optimization: `-disable-readonly-static-objects`
So far, static arrays had to be put into a writable section, because the isa pointer and the (immortal) ref count field were initialized dynamically at the first use of such an array.
But with a new runtime library, which exports the symbols for the (immortal) ref count field and the isa pointer, it's possible to put the whole array into a read-only section. I.e. make it a constant global.
rdar://94185998
This change extends the clang header printer to start emitting C++ classes for Swift struct types with the correct struct layout in them (size + alignment)
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.
This pipes the `-static` flag when building a static library into IRGen.
This should have no impact on non-Windows targets as the usage of the
information simply removes the `dllexport` attribute on the generated
interfaces. This ensures that a library built with `-static` will not
re-export its interfaces from the consumer. This is important to ensure
that the consumer does not vend the API surface when it statically links
a library. In conjunction with the removal of the force load symbol,
this allows the generation of static libraries which may be linked
against on Windows. However, a subsequent change is needed to ensure
that the consumer does not mark the symbol as being imported from a
foreign module (i.e. `dllimport`).
The RequirementSignature generalizes the old ArrayRef<Requirement>
which stores the minimal requirements that a conforming type's
witnesses must satisfy, to also record the protocol typealiases
defined in the protocol.
A "accessible" function that can be looked up based on a string key,
and then called through a fully-abstracted entry point whose arguments
can be constructed in code.
Previously, a LinkEntity for an AST async function pointer was built by
passing an AbstractFunctionDecl. Later, decl was used to construct a
SILDeclRef.
That arrangement meant that clients could not construct such a
LinkEntity whose SILDeclRef::Kind could not be inferred from the dynamic
type of the decl from which the SILDeclRef was constructed. In
particular, clients could not construct a LinkEntity for the initializer
corresponding to a ConstructorDecl.
Here, the arrangment is changed so that the LinkEntity for an AST async
function pointer is built by passing a SILDeclRef.
Gather 'round to hear tell of the saga of autolinking in incremental
mode.
In the beginning, there was Swift code, and there was Objective-C code.
To make one import bind two languages, a twinned Swift module named the same as an
Objective-C module could be imported as an overlay. But all was not
well, for an overlay could be created which had no Swift content, yet
required Swift symbols. And there was much wailing and gnashing of teeth
as loaders everywhere disregarded loading these content-less Swift
libraries.
So, a solution was found - a magical symbol _swift_FORCE_LOAD_$_<MODULE>
that forced the loaders to heed the dependency on a Swift library
regardless of its content. It was a constant with common linkage, and it
was good. But, along came COFF which needed to support autolinking but
had no support for such matters. It did, however, have support for
COMDAT sections into which we placed the symbol. Immediately, a darkness
fell across the land as the windows linker loudly proclaimed it had
discovered a contradiction: "_swift_FORCE_LOAD_$_<MODULE> cannot be
a constant!", it said, gratingly, "for this value requires rebasing."
Undeterred, we switched to a function instead, and the windows linker
happily added a level of indirection to its symbol resolution procedure
and all was right with the world.
But this definition was not all right. In order to support multiple
translation units emitting it, and to prevent the linker from dead
stripping it, Weak ODR linkage was used. Weak ODR linkage has the nasty
side effect of pessimizing load times since the dynamic linker must
assume that loading a later library could produce a more definitive
definition for the symbol.
A compromise was drawn up: To keep load times low, external linkage was
used. To keep the linker from complaining about multiple strong
definitions for the same symbol, the first translation unit in the
module was nominated to recieve the magic symbol. But one final problem
remained:
Incremental builds allow for files to be added or removed during the
build procedure. The placement of the symbol was therefore dependent
entirely upon the order of files passed at the command line. This was no
good, so a decree was set forth that using -autolink-force-load and
-incremental together was a criminal offense.
So we must compromise once more: Return to a symbol with common linkage,
but only on Mach-O targets. Preserve the existing COMDAT-friendly
approach everywhere else.
This concludes our tale.
rdar://77803299
Previously, because partial apply forwarders for async functions were
not themselves fully-fledged async functions, they were not able to
handle dynamic functions. Specifically, the reason was that it was not
possible to produce an async function pointer for the partial apply
forwarder because the size to be used was not knowable.
Thanks to https://github.com/apple/swift/pull/36700, that cause has been
eliminated. With it, partial apply forwarders are fully-fledged async
functions and in particular have their own async function pointers.
Consequently, it is again possible for these partial apply forwarders to
handle non-constant function pointers.
Here, that behavior is restored, by way of reverting part of
ee63777332 while preserving the ABI it
introduced.
rdar://76122027
Previously, thick async functions were represented sometimes as a pair
of (AsyncFunctionPointer, nullptr)--when the thick function was produced
via a thin_to_thick_function, e.g.--and sometimes as a pair of
(FunctionPointer, ThickContext)--when the thick function was produced by
a partial_apply--with the size stored in the slot of the ThickContext.
That optimized for the wrong case: partial applies of dynamic async
functions; in that case, there is no appropriate AsyncFunctionPointer to
form when lowering the partial_apply instruction. The far more common
case is to know exactly which function is being partially applied. In
that case, we can form the appropriate AsyncFunctionPointer.
Furthermore, the previous representation made calling a thick function
more complex: it was always necessary to check whether the context was
in fact null and then proceed along two different paths depending.
Here, that behavior is corrected by creating a thunk in a mandatory
IRGen SIL pass in the case that the function that is being partially
applied is dynamic. That new thunk is then partially applied in place
of the original partial_apply of the dynamic function.
Up to now, there had been no need to define a LinkEntity for a partial
apply forwarder. Now that async partial apply forwarders will each have
their own async function pointer, an entity is needed to pass to the
code that generates the async function pointers.
No demangling or remangling changes are required because that code has
existed for as long as partial apply forwarders to support demangling
their symbols.
- 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).
This adds new kinds of link entities corresponding to the three
dispatch thunk link entity kinds:
- DispatchThunkAsyncFunctionPointer
- DispatchThunkInitializerAsyncFunctionPointer
- DispatchThunkAllocatorAsyncFunctionPointer
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.
COMDAT can only be applied to definitions, not declarations. This
manifested in builds of llbuild with SwiftPM on Windows. The nominal
type descriptor accessor declaration was marked as COMDAT.
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.
This slightly regresses the standard library build (intentionally) while
generally improving the build of dispatch, foundation, xctest.
Rather than continuing to rely on the short-term hack of special casing
the standard library, identify the module where the decl originates
from. If the module is the current module, then assume that the symbol
need not be imported (static linking does not currently work on Windows
anyways). This allows for properly identifying the module where the
symbol will be homed.
Because we no longer special case the standard library here, a few known
metadata types will be incorrectly marked as being imported rather than
local.
Since linked entities which have `Shared` SILLinkage should be module
local, special case them to always be local. Without this the metadata
access function is still marked incorrectly.
With this computation we now get nearly all the cases correct. Dispatch
no longer has to rely on the linker relaxing the import to a local
binding. XCTest is also clean. Foundation misses the following case:
- `$sSS10FoundationE19_bridgeToObjectiveCAA8NSStringCyF`
The regressed cases in swiftCore are:
- `$sBi64_WV`
- `$sBi8_WV`
- `$sBi16_WV`
- `$sBi32_WV`
- `$sBpWV`
- `$syycWV`
- `$sBoWV`
- `$sBOWV`
- `$sBbWV`
- `$sytWV`
The logic here used to consist of a couple of ad-hoc checks,
followed by a general assumption that if something had already
been emitted, it could be referenced directly, whereas everything
else had to go through a GOT entry.
This is way too conservative. Instead, let's try to correctly
calculate what translation unit an entity is going to end up in.