This was a relict from the -sil-serialize-all days. This linkage doesn't make any sense because a private function cannot be referenced from another module (or file, in case of non-wmo compilation).
`objc_getRequiredClass` will produce a fatal error if the class isn't
found, which will prevent a malformed program using back-deployed @objc
actor from launching. Also eliminate the spurious `objc_opt_self`
call, which is unneeded given that we're realizing the metadata.
Thanks to Mike Ash for the review.
@objc actors implicitly inherit from the new, hidden
`SwiftNativeNSObject` class that inherits from `NSObject` yet provides
Swift-native reference counting, which is important for the actor
runtime's handling of zombies. However, `SwiftNativeNSObject` is only
available in the Swift runtime in newer OS versions (e.g., macOS
12.0/iOS 15.0), and is available in the back-deployed _Concurrency
library, but there is no stable place to link against for
back-deployed code. Tricky, tricky.
When back-deploying @objc actors, record `NSObject` as the superclass
in the metadata in the binary, because we cannot reference
`SwiftNativeNSObject`. Then, emit a static initializer to
dynamically look up `SwiftNativeNSObject` by name (which will find it
in either the back-deployment library, on older systems, or in the
runtime for newer systems), then swizzle that in as the superclass of
the @objc actor.
Fixes rdar://83919973.
A new LLVM IR affordance that allows expressing conditions under which globals
can be removed/dropped (even when marked with @llvm.used) is being discussed at:
- <https://reviews.llvm.org/D104496>
- <https://lists.llvm.org/pipermail/llvm-dev/2021-September/152656.html>
This is a preliminary implementation that marks runtime lookup records (namely
protocol records, type descriptors records and protocol conformance records)
with the !llvm.used.conditional descriptors. That allows link-time / LTO-time
removal of these records (by GlobalDCE) based on whether they're actually used
within the linkage unit. Effectively, this allows libraries that have a limited
and known set of clients, to be optimized against the client at LTO time, and
significantly reduce the code size of that library.
Parts of the implementation:
- New -conditional-runtime-records frontend flag to enable using !llvm.used.conditional
- IRGen code that emits these records can now emit these either as a single contiguous
array (asContiguousArray = true, the old way), which is used for JIT mode, or
as indivial globals (asContiguousArray = false), which is necessary for the
!llvm.used.conditional stripping to work.
- When records are emitted as individual globals, they have new names of
"\01l_protocol_" + mangled name of the protocol descriptor, and similarly for
other records.
- Fixed existing tests to account for individual records instead of a single array
- Added an IR level test, and an end-to-end execution test to demonstrate that
the !llvm.used.conditional-based stripping actually works.
- Under -internalize-at-link, stop unconditionally marking all globals as used.
- Under -internalize-at-link, restrict visibility of vtables to linkage unit.
- Emit virtual method thunks for cross-module vcalls when VFE is enabled.
- Use thunks for vcalls across modules when VFE is enabled.
- Adjust TBDGen to account for virtual method thunks when VFE is enabled.
- Add an end-to-end test case for cross-module VFE.
This is needed to for a future change, <https://github.com/apple/swift/pull/39313>, which will start to allow
under certain conditions to dead-strip unused types, protocols and conformances.
- Virtual calls are done via a @llvm.type.checked.load instrinsic call with a type identifier
- Type identifier of a vfunc is the base method's mangling
- Type descriptors and class metadata get !type markers that list offsets and type identifiers of all vfuncs
- The -enable-llvm-vfe frontend flag enables VFE
- Two added tests verify the behavior on IR and by executing a program
As of "ELF: Create unique SHF_GNU_RETAIN sections for llvm.used global
objects" (https://reviews.llvm.org/D97448) LLVM will create separate
sections for symbols marked as llvm.used. Use llvm.compiler.used
instead.
rdar://82681143
The MemoryBuffer loader is used by LLDB during debugging to import binary Swift
modules from .swift_ast sections. Modules imported from .swift_ast sections are
never produced from textual interfaces. By disabling resilience the expression
evaluator in the debugger can directly access private members.
rdar://79462915
In a back deployment scenario, this will provide a place where one could provide
function implementations that are not available in the relevant stdlib.
This is just setting up for future work and isn't doing anything interesting
beyond wiring it up/making sure that it is wired up correctly with tests.
In a back deployment scenario, this will provide a place where one could provide
function implementations that are not available in the relevant stdlib.
This is just setting up for future work and isn't doing anything interesting
beyond wiring it up/making sure that it is wired up correctly with tests.
Classes using the type-erased Objective-C generics model are represented in parts of IRGen as UnboundGenericTypes, which is a problem because a number of code paths expect all generic types to be bound. Update some of these that are involved in extensions on ObjC generic types.
Changes the task, taskGroup, asyncLet wait funtion call ABIs.
To reduce code size pass the context parameters and resumption function
as arguments to the wait function.
This means that the suspend point does not need to store parent context
and resumption to the suspend point's context.
```
void swift_task_future_wait_throwing(
OpaqueValue * result,
SWIFT_ASYNC_CONTEXT AsyncContext *callerContext,
AsyncTask *task,
ThrowingTaskFutureWaitContinuationFunction *resume,
AsyncContext *callContext);
```
The runtime passes the caller context to the resume entry point saving
the load of the parent context in the resumption function.
This patch adds a `Metadata *` field to `GroupImpl`. The await entry
pointer no longer pass the metadata pointer and there is a path through
the runtime where the task future is no longer available.
This showed up when trying to convert swift-package-manager to build
using static linking on Windows. We would not correctly identify the
module as being static due to there being no DeclContext for emission.
This adjusts the IRGen layer to accommodate the Windows linking model.
We assume dynamic linking by default. The static linking is enabled by
passing `-static` to the driver, which forwards it to the frontend when
building the module statically. This has already been required when
generating libraries, however, the non-Windows targets are more
forgiving and let it work. On those platforms, using this hint would
allow for more efficient code generation, reducing load times and some
runtime penalties from the PLT and GOT references formed to symbols
which are module local.
This corrects static linking on Windows, which is one of the last few
items that are missing on Windows. It also takes advantage of the hint
for the one peculiar difference between Windows and non-Windows:
protocol conformances that span module boundaries are not available as a
constant. However, when statically linking, we can enable those
conformances to be statically resolved. This should enable the last
known pattern to work when using static linking.
This support requires further work in the Swift Package Manager to
actually enable building libraries properly. However, when building
with CMake, this should be sufficient to enable static linking.
Previously, AsyncFunctionPointer constants were signed as code. That
was incorrect considering that these constants are in fact data. Here,
that is fixed.
rdar://76118522
The current code generation will emit an autibsp after adjusting the
stack pointe for the tail call. If callee and caller argument area does
not match this would fail.
First, just call an async -> T function instead of forcing the caller
to piece together which case we're in and perform its own copy. This
ensures that the task is actually kept alive properly.
Second, now that we no longer implicitly depend on the waiting tasks
being run synchronously, go ahead and schedule them to run on the
global executor.
This solves some problems which were blocking the work on TLS-ifying
the task/executor state.
In case a function is only referenced from a global without a declaration (e.g. an outlined global), we could end up with a null IRGenModule for the function (with multithreaded compilation). In this case, just use the primary IGM.
This fixes a IRGen crash, introduced with https://github.com/apple/swift/pull/35780
rdar://74358251
Previously, the name of the entry point function was always main. Here,
a new frontend flag is added to enable an arbitrary name to be
specified.
rdar://58275758
When building the label for the IAT synthetic, we need to pre-decorate
the symbol before we apply the synthetic symbol prefix lest we end up
placing the user-label prefix over the synthetic symbol rather than the
actual symbol. This is required to correctly resolve symbols when
building the standard library for x86.
An AsyncFunctionPointer, defined in Task.h, is a struct consisting of
two i32s: (1) the relative address of the async function and (2) the
size of the async context to be allocated when calling that function.
Here, such structs are emitted for every async SILFunction that is
emitted.