The previous approach was effectively to catch the exception and then
run a trap instruction. That has the unfortunate feature that we end
up with a crash at the catch site, not at the throw site, which leaves
us with very little information about which exception was thrown or
where from.
(Strictly we do have the exception pointer and could obtain exception
information, but it still won't tell us what threw it.)
Instead of that, set a personality function for Swift functions that
call potentially throwing code, and have that personality function
trap the exception during phase 1 (i.e. *before* the original stack
has been unwound).
rdar://120952971
`swift_willThrow` is called with an error right before it is thrown.
This existing entrypoint requires an already-boxed error existential;
with typed errors, we don't have the error existential on hand, so we
would need to allocate the box to throw a typed error. That's not okay.
Introduce a new `swift_willThrowTypedImpl` entry point into the runtime
that will first check for the presence of an error handler and, if one
is present, box the error to provide to the error handler. This
maintains the no-allocations path for typed errors while still
allowing existing error handlers to work.
This new entrypoint isn't available on older Swift runtimes, so create
a back-deployable shim called by the compiler. On new-enough platforms,
this will call through to `swift_willThrowTypedImpl`. On older
platforms, we drop the error and don't call the registered will-throw
handler at all. This is a compromise that avoids boxing when throwing
typed errors, at the cost of a slightly different experience for this
new feature on older runtimes.
Fixes rdar://119828459.
Symbolication can take some time, depending on the binaries involved.
In certain contexts it's better for the backtrace to finish quickly,
and then symbolication could be done offline.
rdar://122302117
rdar://117083470
An existential can contain a different type than the one that is being assigned, so we have to check the types and handle the values accordingly.
We run the builder, then use a small program that converts the JSON output into C code that generates the data. Compile that into a bundle, then load it as the prespecializations library. Then scan all the entries in the table and compare them with what the runtime builds dynamically.
We were doing a linear scan of the table contents as a stopgap. Stop doing that, and compute the proper key for the lookup, matching the one used in the builder.
Not quite NFC because apparently the representation bleeds into what's
accepted in some situations where we're supposed to be warning about
conflicts and then making an arbitrary choice. But what we're doing
is nonsense, so we definitely need to break behavior here.
This is setting up for isolated(any) and isolated(caller). I tried
to keep that out of the patch as much as possible, though.
This library uses GenericMetadataBuilder with a ReaderWriter that can read data and resolve pointers from MachO files, and emit a JSON representation of a dylib containing the built metadata.
We use LLVM's binary file readers to parse the MachO files and resolve fixups so we can follow pointers. This code is somewhat MachO specific, but could be generalized to other formats that LLVM supports.
rdar://116592577
ASL is deprecated in macOS 10.12. It may be time to transition to os_log now
that deployment targets have been raised to 10.12, but until that project
starts these warnings are just pollution.
Filed rdar://121066531 to track adoption of `os_log()` if appropriate.
Create a version of the metadata specialization code which is abstracted so that it can work in different contexts, such as building specialized metadata from dylibs on disk rather than from inside a running process.
The GenericMetadataBuilder class is templatized on a ReaderWriter. The ReaderWriter abstracts out everything that's different between in-process and external construction of this data. Instead of reading and writing pointers directly, the builder calls the ReaderWriter to resolve and write pointers. The ReaderWriter also handles symbol lookups and looking up other Swift types by name.
This is accompanied by a simple implementation of the ReaderWriter which works in-process. The abstracted calls to resolve and write pointers are implemented using standard pointer dereferencing.
A new SWIFT_DEBUG_VALIDATE_EXTERNAL_GENERIC_METADATA_BUILDER environment variable uses the in-process ReaderWriter to validate the builder by running it in parallel with the existing metadata builder code in the runtime. When enabled, the GenericMetadataBuilder is used to build a second copy of metadata built by the runtime, and the two are compared to ensure that they match. When this environment variable is not set, the new builder code is inactive.
The builder is incomplete, and this initial version only works on structs. Any unsupported type produces an error, and skips the validation.
rdar://116592420
For calloc, the variable denoting the of elements comes first,
then the variable denoting the size of each element. However, both
arguments are swapped when calling this function in many places in this codebase.
We can't use `malloc_type_aligned_alloc()` because `aligned_alloc()` requires
that `size` be a multiple of `alignment`, which isn't something we expect here.
rdar://119137861
In the event that the backtracer fails to suspend a thread, it emits a
warning message. Unfortunately the exact meaning of this message isn't
obvious and it doesn't make clear that it's a secondary problem (that is,
you've already crashed at this point).
Update the message to make things clearer.
rdar://116593541
The static bridgeableProtocol inherits the ptrauth_struct attribute which uses the B key, and that's not allowed on global data in the shared cache. Pass the value directly as a parameter instead.
rdar://118606044
The initWithTakeTable accidentally referenced bridgeRetain instead of copyingInitWithTake, which caused a leak when an object containing a bridge reference was also not bitwise takable.
Accessing the thread context structures is complicated because their
member variables change name depending on various macros. This caused
a build failure for ARM64e.
rdar://118402226
* [Runtime] Use threaded code in compact value witness runtime
These changed reduce branching and yield performance improvements of up to 10% for some cases.
* Fix offset in handleRefCountsInitWithTake
We shouldn't try to erase the message when in non-color mode; mostly
that's intended for redirected output scenarios anyway, and in that case
we don't really want garbage in the output.
Also, improve the failure messages when the backtracer itself goes
wrong or can't be executed.
Finally, change the behaviour slightly so that *if* we're explicitly
enabled, *and* the backtracer path wasn't explicitly specified, *and*
we can't find the backtracer, we print a warning on start-up. We
don't do that in any other case because we don't want spurious warnings
everywhere.
rdar://118055527
When we crash, emit a message straight away that says we're working
on a backtrace. If starting the backtracer fails, report that also.
Finally, add a duration to the messages output by the backtracer, so
that we can see how long it took.
rdar://118055527
Make SwiftValue hash/equality work the same as SwiftObject
For Equatable types that are not Hashable, this proxies ObjC `-isEqual:` to Swift `Equatable` and returns a constant for ObjC `-hash`