This seems to be the single most common bridge cast,
and repeated lookup seems to be a performance issue
for the common operation of bridging a string-valued
NSDictionary into Swift. Spending a couple of static
words of memory to memoize it should be a nice perf win.
Resolves rdar://55237013
* SR-12161 Casting P.self to P.Type regressed in iOS13.4 beta
An earlier fix for certain protocol casts inadvertently disabled
the check for a protocol being cast to its own metatype.
This rearranges the code so that identical types always succeed.
It also updates swift_dynamicCastMetatypeUnconditional to
include recent changes to swift_dynamicCastMetatype.
Note: These fixes only apply to debug/non-optimized builds.
Cast optimizations still break a lot of these cases.
SR-3871: Dynamic casting of existentials stored in Obj-C references
Arbitrary Swift objects get packaged into __SwiftValue containers so
that pointers to them can be passed into Obj-C. (Obviously, Obj-C
code can't do anything particularly useful with such pointers other
than refcount them and give them back to Swift code.) Those values come
back into Swift as either `Any` (existential box) or `AnyObject`
(anonymous object pointer) values. Dynamically casting those requires
first inspecting the outer value to get access to the actual type and
value in the __SwiftValue container.
The tryDynamicCastBoxedSwiftValue() function that handles this
was missing a check for the `Any` case, which is why directly
casting from `Any` would routinely fail.
Resolves SR-3871
Rather than attempting Error bridging early when trying to dynamically
cast to NSError or NSObject, treat it as the *last* thing we do when
all else fails. Push most of this code over into Objective-C-specific
handling rather than #ifdef'd into the main casting logic to make that
slightly more clear.
One oddity of Error/NSError bridging is that a class that conforms to
Error can be dynamically cast to NSObject via Error bridging. This has
always been known to the static compiler, but the runtime itself was
not always handling such a cast uniformly. Do so now,
uniformly. However, this forced us to weaken an assertion, because
casting a class type to NSError or NSObject can produce an object with
a different identity.
Fixes rdar://problem/57393991.
* SR-7732: Dynamic casting CFError to Error results in a memory leak
The special handling for casting CFError/NSError to Swift Error
type was using cleanup code that didn't correctly handle this case.
This replaces the cleanup code with a more targeted version.
Fixes: SR-7732
Fixes: rdar://problem/40423061
* Whitespace fixes
* Don't rely on localizable strings to verify test behavior.
I've verified this simplified test still leaks with
the original code and does not leak with the fixed code.
* Don't test against old runtimes that predate this fix
* Explicitly test both NSError and CFError
This is cleaner and it fixes a bunch of cases the old code didn't handle: @objc protocols, class bounds, and superclass constraints.
rdar://problem/56044443
This fixes cases like `type is T.Type` when T is generic specialized to a protocol type.
Note: the compiler can still optimize these checks away and will optimize this check down to `false` in some cases. We'll want to fix that as well.
rdar://problem/56044443
This makes for a cleaner and less implicit-context-heavy API, and makes it easier for symbolic
reference resolvers to do context-dependent things (like map the in-memory base address back to a
remote address in MetadataReader).
The swift side signature for `swift_swiftValueConformsTo` is:
`func swift_swiftValueConformsTo<T>(_: T.self) -> Bool`
This translates to:
`bool swift_swiftValueConformsTo(const Metadata *, const Metadata *)`
The elided parameter would be passed invalid values.. Running this on
Windows with optimizations triggered an optimization where the parameter
happened to be null as `rdx` is the second parameter rather than the 4th
parameter.
This is essentially a long-belated follow-up to Arnold's #12606.
The key observation here is that the enum-tag-single-payload witnesses
are strictly more powerful than the XI witnesses: you can simulate
the XI witnesses by using an extra case count that's <= the XI count.
Of course the result is less efficient than the XI witnesses, but
that's less important than overall code size, and we can work on
fast-paths for that.
The extra inhabitant count is stored in a 32-bit field (always present)
following the ValueWitnessFlags, which now occupy a fixed 32 bits.
This inflates non-XI VWTs on 32-bit targets by a word, but the net effect
on XI VWTs is to shrink them by two words, which is likely to be the
more important change. Also, being able to access the XI count directly
should be a nice win.
Currently ignored, but this will allow future compilers to pass down source location information for cast
failure runtime errors without backward deployment constraints.
_dynamicCastToAnyHashable assumed that _swift_convertToAnyHashableIndirect takes its argument at +1, but that is no longer the case.
rdar://problem/44686587
When checking conformance requirements against an @objc protocol, also
check for an @objc existential using protocol_conformsToProtocol().
Fixes rdar://problem/45685649.
When searching the superclasses at runtime, e.g., to find a suitable
protocol conformance record, also consider the superclasses of CF
types, which were recorded in the metadata but otherwise unused.
Have clients pass the requirement base descriptor to
swift_getAssociatedTypeWitness(), so that the witness index is just one
subtraction away, avoiding several dependent loads (witness table ->
conformance descriptor -> protocol descriptor -> requirement offset)
in the hot path.
Rather than storing associated type metadata access functions in
witness tables, initially store a pointer to a mangled type name.
On first access, demangle that type name and replace the witness
table entry with the resulting type metadata.
This reduces the code size of protocol conformances, because we no
longer need to create associated type metadata access functions for
every associated type, and the mangled names are much smaller (and
sharable). The same code size improvements apply to defaulted
associated types for resilient protocols, although those are more
rare. Witness tables themselves are slightly smaller, because we
don’t need separate private entries in them to act as caches.
On the caller side, associated type metadata is always produced via
a call to swift_getAssociatedTypeWitness(), which handles the demangling
and caching behavior.
In all, this reduces the size of the standard library by ~70k. There
are additional code-size wins that are possible with follow-on work:
* We can stop emitting type metadata access functions for non-resilient
types that have constant metadata (like `Int`), because they’re only
currently used as associated type metadata access functions.
* We can stop emitting separate associated type reflection metadata,
because the reflection infrastructure can use these mangled names
directly.
The signature of this function pointer was incorrect, because it had not
yet been updated for the metadata request/response architecture. We
were getting lucky (!).
These functions don't accept local variable heap memory, although the names make it sound like they work on anything. When you try, they mistakenly identify such things as ObjC objects, call through to the equivalent objc_* function, and crash confusingly. This adds Object to the name of each one to make it more clear what they accept.
rdar://problem/37285743
In a generic requirement, distinguish between Swift and
Objective-C protocols using a spare bit within the relative
(indirectable) reference to the protocol.
Use ProtocolDescriptorRefs within the runtime representation of
existential type metadata (TargetExistentialTypeMetadata) instead of
bare protocol descriptor pointers. Start rolling out the use of
ProtocolDescriptorRef in a few places in the runtime that touch this
code. Note that we’re not yet establishing any strong invariants on
the TargetProtocolDescriptorRef instances.
While here, replace TargetExistentialTypeMetadata’s hand-rolled pointer
arithmetic with swift::ABI::TrailingObjects and centralize knowledge of
its layout better.
Since the mangling scheme and set of standard library types is effectively
fixed now, introduce known mangling substitutions for a number of new
standard library types, filling out the S[A-Za-z] space.
Reduces standard library binary size by ~195k.
libstdc++ included with GCC 4.8 does not define `std::max_align_t` as
required by the C++11 specification. As a workaround, explicitly create
the definition locally. This was fixed in GCC 4.9 and later.
The real work is done in checkDynamicCastFromOptional. This code tried to unwrap the source and returned the payload on success. It only did this once, so a type like Optional<Optional<Int>> would come out as Optional<Int> and then a cast to Int would fail.
This change makes checkDynamicCastFromOptional recursive, which makes it unwrap as many levels of Optional as it encounters.
Fixes rdar://problem/40171034 and SR-7664.