The sections to which the start/stop symbols are being applied do not
guarantee pointer alignment. In particular, the field metadata is
aligned to a 4-byte boundary, which is less then the pointer alignment
of `uintptr_t`. This results in extra padding in the data which is
going to cause the iteration to run off the end. A similar byte
alignment is forced for the markers in the ELF case as well. This fixes
one of the reflection tests on Windows where we were attempting to
decode the padding as an entry.
This adds a new tail-allocated field to class context descriptors storing
a pointer to an Objective-C class stub.
When the stub is present, we use the new _objc_realizeClassFromSwift()
entry point to realize the class instead of calling objc_readClassPair().
This should attach categories to the realized class, if they were emitted
to reference the stub.
This caused an issue where the runtime was unable to find subclasses of
resilient subclasses of NSObject until they were first registered by their
sugared name with NSClassFromString or were instantiated directly.
rdar://48892003
Extract common code from the old and new remangler into a common base class.
This lets the old remangler benefit from the changes I did recently in the new remangler.
This is needed for Windows which does not support cross-module data
references without indirection. By lazy initializing the data, we can
indirect through the IAT for the data pointer and fill in the parent
pointer.
Recent Swift uses 2 as the is-Swift bit when running on newer versions, and 1 on older versions. Since it's difficult or impossible to know what we'll be running on at build time, make the selection at runtime.
Instead of capturing SubstGenericParametersFromMetadata and SubstGenericParametersFromWrittenArgs by value, capture by reference.
This avoids those instances to be copied and thus avoids a lot of mallocs.
SR-10028
rdar://problem/48575729
This dramatically reduces the number of needed malloc calls.
Unfortunately I had to add the implementation of SmallVectorBase::grow_pod to the runtime, as we don't link LLVM. This is a bad hack, but better than re-inventing a new SmallVector implementation.
SR-10028
rdar://problem/48575729
We would not previously symbolicate the stack trace and as a result
would not display the stack trace. Add symbolication support to the
runtime to actually make use of the captured stack trace. This allows
us to get a stack trace when the standard library or swift code reports
a fatal error.
The assertions here are based around the idea that `std::atomic` is
trivially constructible which is not a guarantee that the standard fully
provides. The default initialization of the `std::atomic` type may
leave it in an undetermined state. These were caught using the Visual
C++ preview runtime.
Ideally, the object constructor would use a placement new operator.
However, prior to C++17, the C++ standard mandated that there be a
NULL pointer check in the placement new operator. This is something
which is no longer the case with C++17. Switch to the placement new
operator for C++17 and newer and enable that codepath for Windows as
well (which seemingly elides the null-pointer check with clang-cl).
This initialization pattern can only be used if there is a backward deployment
layout (IRGen calls this ClassMetadataStrategy::FixedOrUpdate) or if we are
running on a newer Objective-C runtime that supports class metadata update
hooks (IRGen calls this ClassMetadataStrategy::Update).
If neither condition holds, we must trap here to avoid undefined behavior.
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 done by disallowing nodes with children to also have index or text payloads.
In some cases those payloads were not needed anyway, because the information can be derived later.
In other cases the fix was to insert an additional child node with the index/text payload.
Also, implement single or double children as "inline" children, which avoids needing a separate node vector for children.
All this reduces the needed size for node trees by over 2x.
In our initial approach for resolving metadata dependency cycles with classes, non-transitively complete superclass metadata was fetched by the subclass's metadata completion function and passed to `swift_initClassMetadata`. That could mean generating quite a lot of code in the completion function, and so we fairly recently changed it so that `swift_initClassMetadata` instead fetched the superclass metadata via a demangling. Unfortunately, the metadata demangler only fetches _abstract_ metadata by default, and class metadata cannot be considered even non-transitively complete when its superclass reference not at that stage. If the superclass metadata is being completed on one thread, and a subclass is being completed on another, and the subclass installs the incomplete superclass metadata in its superclass field and attempts to register the subclass with the Objective-C runtime, the runtime may crash reading the incompletely-initialized superclass.
The proper fix is to make `swift_initClassMetadata` fetch non-transitively complete metadata for the superclass, delaying completion if that metadata is unavailable. Unfortunately, that can't actually be implemented on top of `swift_initClassMetadata` because that function has no means of reporting an unsatisfied dependency to its caller, and we can no longer simply change its signature without worrying about a small of internal code that might still be using it. We cannot simply perform a blocking metadata request in `swift_initClassMetadata` because it is deeply problematic to block within a metadata completion function. The solution is therefore to add a `swift_initClassMetadata2` which has the ability to report unsatisfied dependencies. That was done in #22386; this patch builds on that by teaching the compiler to generate code to actually use it. It is therefore not safe to use this patch if you might be running on an OS that only provides the old runtime function, but that should be a temporary Apple-internal problem.
Fixes rdar://47549859.
Note that I've called out a couple of suspicious places where we
are requesting abstract metadata for superclasses but probably
need to be requesting something more complete.
MetadataLookup gives special treatment to imported Objective-C classes,
since there's no nominal type descriptor and metadata is obtained
directly by calling into the Objective-C runtime.
Remote reflection also gives special treatment to imported Objective-C
classes; they don't have field descriptors.
However, the ASTDemangler needs to treat them like ordinary classes,
in particular it wants to preserve the generic arguments here so that
we can round-trip debug info.
If we nest a type inside a local context inside a generic type,
we have to look through the local context(s) to find the outer
generic type when stripping off generic arguments.
We don't support nominal types inside generic local context
right now, but this can happen with type aliases.
The part of the tag stored in the payload can currently be up to
8 bytes in size (though only the 'low' 4 bytes can be non-zero).
On little-endian machines this doesn't matter, we can always just
store up to 4 bytes and zero the remaining payload bytes. On big-
endian systems however we may need to store more than 4 bytes.
The store implementation now mirrors the runtime code that fetches
the tag on big-endian systems which already treats the payload tag
as an 8 byte integer.
This is a spot fix but longer term we might want to consider
refactoring this code to reduce the number of differences between
big- and little-endian implementations. For example, we could
centralise some of the copying logic and/or make the payload tag
a 4 byte field on all platforms.
Debug info uses a special mangling where type aliases can be
represented without being desugared; attempt to reconstruct
the TypeAliasType in this case.