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.
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
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 now this has SWIFT_RUNTIME_LIBRARY_VISIBILITY, but in the
future we might want to make it public so that IRGen can use it
to build packs out of concrete types.
This adds a bunch of new code but once I finish refactoring the other
demangling stuff, I should be able to remove
- gatherWrittenGenericArgs()
- _gatherGenericParameters()
- SubstGenericParametersFromWrittenArgs
This replaces a number of `#include`-s like this:
```
#include "../../../stdlib/public/SwiftShims/Visibility.h"
```
with this:
```
#include "swift/shims/Visibility.h"
```
This is needed to allow SwiftCompilerSources to use C++ headers which include SwiftShims headers. Currently trying to do that results in errors:
```
swift/swift/include/swift/Demangling/../../../stdlib/public/SwiftShims/module.modulemap:1:8: error: redefinition of module 'SwiftShims'
module SwiftShims {
^
Builds.noindex/swift/swift/bootstrapping0/lib/swift/shims/module.modulemap:1:8: note: previously defined here
module SwiftShims {
^
```
This happens because the headers in both the source dir and the build dir refer to SwiftShims headers by relative path, and both the source root and the build root contain SwiftShims headers (which are equivalent, but since they are located in different dirs, Clang treats them as different modules).
In order to be able to debug, for example, a Linux process from a macOS host, we
need to be able to initialize a ReflectionContext without Objective-C
interoperability. This patch turns ObjCInterOp into another template trait, so
it's possible to instantiate a non-ObjC MetadataReader on a system built with
ObjC-interop (but not vice versa).
This patch changes the class hierarchy to
TargetMetadata<Runtime>
|
TargetHeapMetadata<Runtime>
|
TargetAnyClassMetadata<Runtime>
/ \
/ TargetAnyClassMetadataObjCInterop<Runtime>
/ \
TargetClassMetadata<Runtime, TargetAnyClassMetadata<Runtime>> \
\
TargetClassMetadata<Runtime, TargetAnyClassMetadataObjCInterop<Runtime>>
TargetAnyClassMetadataObjCInterop inherits from TargetAnyClassMetadata because
most of the implementation is the same. This choice makes TargetClassMetadata a
bit tricky. In this patch I went with templating the parent class.
rdar://87179578
Added a new test to the test suite that round trips Swift types through
mangled names and checks that we get the same type back that we started
with.
rdar://37170485
There are a set of headers shared between the Swift compiler and the
runtime. Ensure that we explicitly use `llvm::ArrayRef` rather than
`ArrayRef` which is aliased to `::llvm::ArrayRef`. Doing so enables us
to replace the `ArrayRef` with an inline namespaced version fixing ODR
violations when the swift runtime is loaded into an address space with
LLVM.
This reduces the dependency on `LLVMSupport`. This is the first step
towards helping move towards a local fork of the LLVM ADT to ensure that
static linking of the Swift runtime and core library does not result in
ODR violations.
This replaces `LLVM_LIBRARY_VISIBILITY` with `SWIFT_LIBRARY_VISIBILTIY`
througout the runtime. The purpose of this attribution is unclear -
building with `-fvisibility=hidden` would accomplish this. This is an
entirely mechanical change replacing the macro with the Swift namespaced
variant instead.
SR-5289: Teach Mirror how to inspect weak, unowned, and unmanaged refs
Correctly reflect weak, unowned, and unmanaged references
to both Swift and Obj-C types (including existential references to
such types) that occur in both Swift class objects and in Swift
structs.
This includes the specific reported case (unowned reference to an
Obj-C object) and several related ones.
Related changes in this PR:
* Tweak internal bitmap used for tracking ownership modifiers
to reject unsupported combinations.
* Move FieldType into ReflectionMirror.mm
FieldType is really just an internal implementation detail
of this one source file, so it does not belong in an ABI header.
* Use TypeReferenceOwnership directly to track field ownership
This avoids bitwise copying of properties and localizes some
of the knowledge about reference ownership
* Generate a top-level "copyFieldContents" from ReferenceStorage.def
Adding new ownership types to ReferenceStorage.def will now
automatically produce calls to `copy*FieldContents` - failure
to provide a suitable implementation will fail the build.
* Add `deallocateBoxForExistentialIn` to match `allocateBoxForExistentialIn`
Caveat: The unit tests are not as strict as I'd like. Attempting to make them
so ran afoul of otherwise-unrelated bugs in dynamic casting.
* SR-5289: Support reflecting weak, unowned, and unmanaged refs
This refactors how we handle reference ownership
when reflecting fields of struct and class objects.
There are now explicit paths for each type of reference
and some simple exhaustiveness checks to fail the build
if a new reference type is added in the future without
updating this logic.
This is a one-to-many cache that's more speculative than the cache mapping mangled names to context descriptors. Entries found in the cache need to be verified for a match before they can be returned. However, this allows scanning conformance records up front and building up the cache in one scan rather than performing an expensive scan of all conformance records every time the mangled name cache misses.
rdar://problem/53560010
Generic parameters for a context are normally classified as "key",
meaning they have actual metadata provided at runtime, or non-key,
meaning they're derivable from somewhere else. However, a nested
context or constrained extension can take what would be a "key"
parameter in a parent context and make it non-key in a child context.
This messes with the mapping between the (depth, index) representation
of generic parameters and the flat list of generic arguments. Fix this
by (1) consistently substituting out extension contexts with the
contexts of the extended types, and (2) using the most nested context
to decide which parameters are key, instead of the context a parameter
was originally introduced in.
Note that (1) may have problems if/when extensions start introducing
their /own/ generic parameters. For now I tried to be consistent with
what was there.
rdar://problem/52364601
Build a static archive that can be linked into executables and take advantage of the Swift runtime's
hooking mechanism to work around the issue Doug fixed in https://github.com/apple/swift/pull/24759.
The Swift 5.0 version of swift_conformsToProtocol would return a false negative in some cases where
a subclass conforms using an inherited conformance, so work around this by successively retrying
the original implementation up the superclass chain to try to find a match.
This allows _swift_getClassOfAllocated to use a constant instead of loading from a global, and allows swift_isaMask to be computed without a static initializer. Debug builds verify that the #define matches the value from libobjc.
rdar://problem/22375602 rdar://problem/46385113
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
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.
This can be used by compiler-generated code as a size optimization for metadata access, using a
mangled name instead of possibly many open-coded metadata calls. It can also allow reflection
libraries outside of the standard library to turn type reference strings into in-process metadata
pointers in a robust way. rdar://problem/46451849