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`
Thanks to a missing `-` sign, we were returning garbage rather than
indicating that the memory region in question was inaccessible. This
mainly affects register dumps (since that's the time we expect to have
to cope with out-of-bounds reads).
rdar://117900760
Update PR #68720 with lessons learned in reviewing #69464
Background:
* SwiftValue can expose Swift value types (structs/enums)
to ObjC by wrapping them in an Obj-C object on the heap
* SwiftObject is the Obj-C type that Swift class objects all
inherit from (when viewed from Obj-C). This allows arbitrary
Swift class objects to be passed into Obj-C.
History:
* PR #4124 made Obj-C `-hash` and `-isEqual:` work for SwiftValue for Hashable Swift types
* PR #68720 extended SwiftValue to also support Equatable Swift types
* PR #69464 added similar support to SwiftObject
In the process of working through #69464, we found a better way
to handle an ObjC request for `-hash` for a type that is Swift
Equatable but not Hashable. This PR updates SwiftValue to use
the same approach. The approach considers three cases:
1. A Hashable type can forward both `-hash` and `-isEqual:` to
the Swift object.
2. A type that is neither Equatable nor Hashable can implement
`-isEqual:` as the identity check and `-hash` as returning
the address of the object in memory.
3. A type is that Equatable but not Hashable is more complex.
In this last case, we can easily forward `-isEqual:` to the
Equatable conformance but ObjC also requires us to
always provide a compatible `-hash` implementation.
The only way to do this is to have `-hash` return a constant,
but that is a very bad idea in general, so we're also including
a log message whenever we see a request for `-hash` on
a Swift value that is Equatable but not Hashable.
To limit performance problems from the logging itself, we
emit the log message only once for each type.
This is worth telling people about:
Since we're being asked for the hash value, that probably means someone is
trying to put this object into some form of set or dictionary. But we don't know
anything about the Equatable implementation, so the only valid hash value we can
possibly return is a constant. And hash table implementations typically degrade
into unsorted lists when provided constant hash values.
Note: In order to avoid hammering the logs, we only emit the
warning once for each class that hits this path.
There's no need for fatalError() to try to generate its own backtraces
when the runtime's backtracer is enabled. Not only is the code it uses
more fragile but it also doesn't support async or inline frames and it
can't look-up symbols properly either.
rdar://117470489
For an Equatable type, we need a hash implementation that
is compatible with any possible definition of `==`.
Conservatively, that means `-hash` must return a constant.
For non-Equatable types, we know that `==` is identity based,
so we can get better hash behavior by using the object address.
Caveat: This means that non-Equatable types will do two
protocol conformance checks on every call to `hash`.
Add a `SWIFT_STDLIB_OVERRIDABLE_RETAIN_RELEASE` CMake option. When set to true, swift_retain/release and the other functions in InstrumentsSupport.h can be overridden by setting the appropriate global function pointer, as is already the case. When set to false, those function pointers are removed and the functions always go into the default implementation.
Set `SWIFT_STDLIB_OVERRIDABLE_RETAIN_RELEASE` to false when building the minimal stdlib, and set it to true otherwise by default.
rdar://115987924
When forming runtime metadata for a function type that has either `any
Error` or `Never` as the specified thrown error type, drop the thrown
error type and normalize down to (untyped) `throws` or non-throwing,
as appropriate.
Extend function type metadata with an entry for the thrown error type,
so that thrown error types are represented at runtime as well. Note
that this required the introduction of "extended" function type
flags into function type metadata, because we would have used the last
bit. Do so, and define one extended flag bit as representing typed
throws.
Add `swift_getExtendedFunctionTypeMetadata` to the runtime to build
function types that have the extended flags and a thrown error type.
Teach IR generation to call this function to form the metadata, when
appropriate.
Introduce all of the runtime mangling/demangling support needed for
thrown error types.
If a Swift type implements Equatable and/or Hashable and
we then pass that object into ObjC, we want ObjC
`isEqual:` and `hashValue` to use that. This allows
ObjC code to build ObjC collections of Swift objects.
* Support for Hashable struct/enum types was implemented in #4124
* Support for Equatable struct/enum types was implemented in #68720
* This implements support for Hashable and Equatable _class_ types
Caveats:
1. This does a lot of dynamic lookup work for each operation, so is
inherently rather slow. Unlike the struct/enum case, there is no convenient
place to cache the conformance information, so it's not clear that there is a
viable way to make it significantly faster.
2. This is a behavioral change to low-level support code. There is a
risk of breaking code that may be relying on the old behavior.
Given this
```
@objc protocol P { func f() }
class C: P { func f() {} }
```
the casts `C.self is any P` and `C.self as? any P` should always fail,
because the metatype of `C.self` does not have an `f()` implementation.
These casts previously succeeded because the runtime implementation
deferred to Obj-C's `[o conformsToProtocol:p]`, and that behaves
differently depending on whether `o` is a class instance or
a Class itself.
Since these casts should never succeed, I've just modified the
Swift runtime logic to fail whenever the source of the cast
is an Obj-C Class and the target is a protocol existential.
Resolves: rdar://106973771
Experiment shows that the vast majority (~99.99%) of keys with equal hashes have equal bytes. Fast-path that case by doing a memcmp before doing the deeper comparison.
rdar://110478978
Using symbolic references instead of a text based mangling avoids the
expensive type descriptor scan when objective c protocols are requested.
rdar://111536582