Commit Graph

221 Commits

Author SHA1 Message Date
Mike Ash
e15783ecd4 [Runtime] Fix concurrent lookups of types by name (again).
Fix a potential false positive if we check a class for a protocol conformance and its superclasses aren't yet instantiated.

This was partially fixed before, but we were incorrectly saying that all superclasses had been instantiated if they had been instatiated by the LAST check in conformsToProtocol. That left us open for a possible false positive in an earlier check to go unnoticed.

This change fixes it by checking for uninstantiated superclasses after each iteration over superclasses, not just the last one.

This change also makes the concurrentTypeByName test much more robust. The original test caught this bug only rarely, but the new one catches it it reliably. We now look up 1000 types per test run. Testing locally, we typically hit the race after less than 100 types.

rdar://82364236
2022-09-23 16:45:30 -04:00
Mike Ash
f2407bf0a7 [Runtime] Fix short-circuiting of shared cache conformance lookups.
We were skipping shared cache queries if the ObjC metadata or descriptor were outside the shared cache, but we need to skip only if they're both outside the shared cache. We also need to check foreign types even if the descriptor is outside the shared cache.

rdar://93931813
2022-06-17 16:45:22 -04:00
zoecarver
f972f664d3 [cxx-interop] Runtime support for foreign reference types. 2022-06-14 12:18:05 -07:00
Mike Ash
de93c3e182 [Runtime] Skip shared cache protocol conformance queries we know won't succeed.
The shared cache tables can only point to things within the shared cache, so if the protocol, ObjC class, or type descriptor are outside the shared cache, we know that the lookup will fail and we can skip it.

rdar://90427793
2022-05-10 15:25:23 -04:00
Saleem Abdulrasool
a8b0ee24dc runtime: blanket application of namespacing and inclusion of new
Apply a blanket pass of including `new` for the placement new allocation
and namespacing the call to the global placement new allocator.  This
should repair the Android ARMv7 builds.
2022-04-14 14:21:12 -07:00
Mike Ash
d61fee3884 [Runtime] Check the weak-linked _dyld_has_preoptimized_swift_protocol_conformances for NULL before calling it.
rdar://89522018
2022-03-02 14:24:12 -05:00
Mike Ash
99752c5d08 [Runtime] Fix dyld protocol conformances.
Leftover code was overwriting the result from the `on_disk` calls. Don't do that.

While we're in there, change the name of the `DYLD_CONFORMANCES_LOG` macro to `DYLD_CONFORMANCES_LOG` and fix up the wording to be more general.

rdar://89154273
2022-02-21 15:47:21 -05:00
Mike Ash
d262acfa04 [Runtime] Support precomputed protocol conformances outside the shared cache.
Extend the support for precomputed protocol conformances in the shared cache. When available, we'll query dyld for conformances in optimized images loaded outside the shared cache. This is a relatively small addition; where we previously checked the shared cache, we now check both. The order is conditionalized on `scanSectionsBackwards` to preserve that behavior. We also rename some identifiers to fit this more expansive use of preoptimized conformances.

rdar://87425446
2022-02-03 13:30:39 -05:00
Alastair Houghton
4a3612b873 Merge pull request #40955 from al45tair/problem/86368350
[Runtime] Fix a potential NULL pointer dereference.
2022-01-21 21:32:05 +00:00
Alastair Houghton
a0313e9538 [Runtime] Fix a potential NULL pointer dereference.
If we find multiple conformances for the same protocol, we generate a
warning.  This works fine for Swift types, but for Objective-C types
it's possible that while generating the warning we might find that the
type description is NULL.

Fix by using swift_getTypeName().

rdar://86368350
2022-01-21 17:42:02 +00:00
Adrian Prantl
fede775269 Make Objective-C interoperability configurable in the runtime
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
2022-01-20 18:28:18 -08:00
tbkka
184488d3f2 Conditionalize the fix for SR-14635 (#40822)
* Refactor Bincompat

Organize everything around internal functions that test for
a particular OS version.

Correctly handle cases where we don't know the version of the app.

Make all bincompat functions consistently return `true` for the
legacy semantics, `false` for new semantics.  Consistently name
them all to reflect this.

* Conditionalize the support for SR-14635

SR-14635 pointed out a hole in the updated dynamic casting logic
that allowed certain casts that should have been illegal.

In particular, when casting certain types to Obj-C protocols,
the Swift value gets boxed; we would permit the cast to succeed
whenever the resulting box satisfied the protocol.  For example,
this allowed any Swift value to be cast to `NSCopying` regardless of
whether or not it implemented the required `copy(with:)` method.

This was fixed in #37683 to reject such casts but of course some folks were
depending on this behavior to pass Swift data into Obj-C functions.
(The properly supported approach for passing arbitrary Swift data into
Obj-C functions is to cast the Swift value to `AnyObject`.)

This change makes that new behavior conditional.  For now,
the legacy semantics are enabled on Apple platforms and the
new semantics are in use everywhere else.  This will allow
us to gradually enable enforcement of the new behavior over
time.

* Just skip this test on Apple platforms, since it is inconsistently implemented there (and is therefore not really testable)
2022-01-14 11:56:25 -08:00
Jonathan Grynspan
099fdc2e41 Fix an issue on COFF/ELF targets where the runtime would register each loaded image twice (at least early on.) 2022-01-01 11:39:25 -05:00
Arnold Schwaighofer
cf3951394a Revert "Fix an issue on COFF/ELF targets where the runtime would register each loaded image twice (at least early on.)" 2021-12-21 07:15:08 -08:00
Jonathan Grynspan
7fe5ea7398 Fix an issue on COFF/ELF targets where the runtime would register each loaded image twice (at least early on.) 2021-12-20 15:15:02 -05:00
Mike Ash
aec4ec4c4a [Runtime] Weakly import dyld protocol conformance functions.
This allows us to build against a macOS 12 SDK and test on macOS 11.

rdar://81133606
2021-07-29 14:42:30 -04:00
Mike Ash
b37252d418 [Runtime] Fix infinite recursion in protocol conformance checking on class Sub: Super<Sub>.
Conformance checks now walk the superclass chain in two stages: stage 1 only walks superclasses that have already been instantiated. When there's a negative result and there's an uninstantiated superclass, then stage 2 will walk the uninstantiated superclasses.

The infinite recursion would occur in this scenario:

    class Super<T: P> {}
    class Sub: Super<Sub>, P {}

Instantiating the metadata for Super requires looking up the conformance for Sub: P. Conformance checking for Sub would instantiate the metadata for Super to check for a Super: P conformance.

The compiler does not allow the conformance to come from a superclass in this situation. This does not compile:

    class Super<T: P>: P {}
    class Sub: Super<Sub> {}

Therefore it's not necessary to look at Super when finding the conformance for Sub: P in this particular case. The trick is knowing when to skip Super.

We do need to instantiate Super in the general case, otherwise we can get false negatives. This was addressed in a80fe8536b, which walks the full superclass chain during conformance checks, even if the superclass has not yet been instantiated. Unfortunately, that causes this infinite recursion.

This fix modifies that fix to make superclass instantiation conditional. The result is the ability to choose between the old algorithm (which skipped uninstantiated superclasses, albeit somewhat by accident) and the new one. A small wrapper then runs the check with the old algorithm, and then only if the old algorithm fails and there is an uninstantiated superclass, it runs with the new one.

Uninstantiated superclasses are uncommon and transient (you only run into this while metadata is in the process of being constructed) so 99.9999% of the time we'll just run the first stage and be done, and performance should remain the same as before.

rdar://80532245
2021-07-22 13:46:01 -04:00
Mike Ash
06ff648825 [Runtime] Fix protocol conformance checks on pure ObjC classes.
The getSuperclassForMaybeIncompleteMetadata function assumes Swift metadata, and can malfunction strangely when given a pure ObjC class. This is rare, as we usually get the Swift wrapper metadata instead, but possible when using calls like objc_copyClassList.

Fix this by checking for isTypeMetadata before doing anything that assumes Swift-metadata-ness.

rdar://80336030
2021-07-08 17:45:43 -04:00
Mike Ash
53fe241c0e Merge pull request #37973 from mikeash/fix-protocol-conformance-KVO
[Runtime] Fix crash in protocol conformance checks on KVO artificial subclasses.
2021-06-23 09:12:32 -04:00
Mike Ash
c3aa44368a [Runtime] Fix crash in protocol conformance checks on KVO artificial subclasses.
tryGetCompleteMetadataNonblocking crashes on artificial subclasses due to the NULL type descriptor. Explicitly check for artificial subclasses in getSuperclassForMaybeIncompleteMetadata and immediately return their Superclass field. Artificial subclasses are always fully initialized so we don't need to do anything special for them.

rdar://72583931
2021-06-17 14:45:58 -04:00
Alastair Houghton
4794b4b28c [Runtime] Detect and log redundant subclass/superclass conformances.
When we rely on a protocol conformance, and the type in question has multiple
conformances to that protocol in its inheritance chain, emit a runtime warning.

It's quite tricky to cause this problem - you need a type in one dylib that is
extended to conform to a protocol in another dylib, subclassed in another module
and then some subclass has protocol conformance added as well.  If they're in
the same module, the compiler will give an error and prevent the problem
completely.

rdar://73364629
2021-06-17 19:28:27 +01:00
Mishal Shah
23c3b15f5f Support Xcode 13 beta
* Updating availability versions
* Remove all remaining overlays in stdlib/public/Darwin/*:
   - ObjectiveC
   - Dispatch
   - CoreFoundation
   - CoreGraphics
   - Foundation
2021-06-07 12:04:31 -07:00
Mike Ash
a80fe8536b [Runtime] Fix concurrent _typeByName with generic arguments, protocol conformances, and superclasses.
When constructing generic type metadata, we can end up checking protocol conformances for metadata that isn't fully built, and in particular the superclass field may not be set up yet. Handle this case properly by falling back to looking up the superclass by mangled name from the nominal type descriptor when necessary.

Previously we were just chasing Superclass fields, which would cause us to terminate the search early sometimes when concurrently looking up the same type from multiple threads. When a protocol conformance is on a superclass, this causes the search to fail incorrectly, causing type lookup failures.

This only arises on the very first attempt to instantiate a given type, since the lookup will be cached (and all metadata fully initialized) after the first success.

rdar://72583931
2021-06-03 11:25:36 -04:00
Mike Ash
6aab257c33 [Concurrency] Add compatibility overrides to Concurrency library.
Take the existing CompatibilityOverride mechanism and generalize it so it can be used in both the runtime and Concurrency libraries. The mechanism is preprocessor-heavy, so this requires some tricks. Use the SWIFT_TARGET_LIBRARY_NAME define to distinguish the libraries, and use a different .def file and mach-o section name accordingly.

We want the global/main executor functions to be a little more flexible. Instead of using the override mechanism, we expose function pointers that can be set by the compatibility library, or by any other code that wants to use a custom implementation.

rdar://73726764
2021-03-22 11:09:06 -04:00
Mike Ash
5193d76c74 [Runtime] Fixed shared cache protocol conformance lookup with subclasses.
Match the logic used in the non-shared-cache case, where we walk up the class hierarchy to find the class where the conformance actually applies. This is important in cases like:

  class Super<T> : Proto {}
  class Sub: Super<Int> {}

Looking up the conformance `Sub: Proto` without this logic causes it to attempt to find the witness table for `Sub<Int>`, which fails. The correct logic looks up the witness table for `Super<Int>`.

While we're in there, fix a bug in the shared cache validation code (std::find wasn't checked for failure correctly) and add a `SWIFT_DEBUG_ENABLE_SHARED_CACHE_PROTOCOL_CONFORMANCES` environment variable to allow us to turn the shared cache integration off at runtime.

rdar://75431771
2021-03-17 11:46:11 -04:00
Mike Ash
e06c978cf8 [Runtime] NULL/availability check shared cache calls.
Avoid a dynamic linker failure if the calls aren't available at runtime.

rdar://74965969
2021-03-04 09:49:09 -05:00
Mike Ash
2b3a627375 [Runtime] Conditionalize shared cache conformance acceleration on ObjC interop.
rdar://74698200
2021-02-24 13:06:34 -05:00
Mike Ash
f35b110cf7 [Runtime] Support precomputed protocol conformances in the shared cache.
When available, take advantage of precomputed protocol conformances in the shared cache on Darwin platforms to accelerate conformance lookups and cut down on memory usage.

We consult the precomputed conformances before doing the runtime's standard conformance lookup. When a conformance is precomputed, this avoids the slow linear scan of all loaded conformances for the first access, and it avoids the memory cost of storing the conformance in the cache.

When the shared cache has no images overridden (the normal case), then we can also skip scanning conformances in the shared cache in all circumstances, because the precomputed conformances will always cover those results. This greatly speeds up the slow linear scan for the initial lookup of anything that doesn't have a conformance in the shared cache, including lookups with conformances in apps or app frameworks, and negative lookups.

A validation mode is available by setting the SWIFT_DEBUG_VALIDATE_SHARED_CACHE_PROTOCOL_CONFORMANCES environment variable. When enabled, results from the precomputed conformances are compared with the results from a slow scan of the conformances in the shared cache. This extremely slow, but good at catching bugs in the system.

When the calls for precomputed conformances are unavailable, the new code is omitted and we remain in the same situation as before, with the runtime performing all lookups by scanning conformance sections in all loaded Swift images.

rdar://71128983
2021-02-11 12:34:23 -05:00
Mike Ash
3a2ea08d75 [Runtime] Fix race condition in protocol conformance lookups that caused false negatives.
In the uncached case, we'd scan conformances, cache them, then re-query the cache. This worked fine when the cache always grew, but now we clear the cache when loading new Swift images into the process. If that happens between the scan and the re-query, we lose the entry and return a false negative.

Instead, track what we've found in the scan in a separate local table, then query that after completing the scan.

While we're in there, fix a bug in TypeLookupError where operator= accidentally copied this->Context instead of other.Context. This caused the runtime to crash when trying to print error messages due to the false negative.

Add a no-parameter constructor to TypeLookupErrorOr<> to distinguish the case where it's being initialized with nothing from the case where it's being initialized with nullptr.
2021-02-08 19:28:27 -05:00
Mike Ash
216e555ad6 [Runtime] Mark swift_asprintf with __attribute__((__format__))
This gives us build-time warnings about format string mistakes, like we would get if we called the built-in asprintf directly.

Make TypeLookupError's format string constructor a macro instead so that its callers can get these build-time warnings.

This reveals various mistakes in format strings and arguments in the runtime, which are now fixed.

rdar://73417805
2021-01-22 10:54:45 -05:00
Mike Ash
32d1c22057 [Runtime] Scan backwards within conformance sections when scanSectionsBackwards is true.
This more closely matches the previous behavior.

rdar://73362732
2021-01-19 16:07:28 -05:00
Mike Ash
9ac3b0ee3b [Runtime] Add a disabled workaround for protocol conformance checking to check conformances in reverse order.
rdar://problem/72049977
2020-12-14 12:59:18 -05:00
Alejandro Alonso
424802fb34 Revert SE-0283 (#34492)
Reverted despite build failures.
2020-10-29 17:32:06 -07:00
Azoy
b985817046 [Runtime] Add Native Windows support for builtin conformances
Force C name mangling for Windows
2020-10-23 12:50:27 -04:00
Azoy
4ff28f2b40 Implement Tuple Hashable Conformance 2020-10-22 18:28:02 -04:00
Azoy
fd950ebbf3 Implement Tuple Comparable Conformance
Add protocol witnesses for all Comparable requirements
2020-10-22 18:27:07 -04:00
Azoy
e60ef84bd2 Implement Tuple Equatable Conformance 2020-10-22 18:24:28 -04:00
Azoy
4b71d6776e [ABI] Introduce MetadataKind TypeRef 2020-10-22 18:24:28 -04:00
John McCall
0fb407943f [NFC] Rename swift_runtime_unreachable to swift_unreachable and make it use LLVM's support when available. 2020-10-03 02:54:56 -04:00
Mike Ash
fd6922f92d Add error reporting when looking up types by demangled name. 2020-08-28 14:43:51 -04:00
Mike Ash
ecd6d4ddec Add a new ConcurrentReadableHashMap type. Switch the protocol conformance cache
to use it.

ConcurrentReadableHashMap is lock-free for readers, with writers using a lock to
ensure mutual exclusion amongst each other. The intent is to eventually replace
all uses ConcurrentMap with ConcurrentReadableHashMap.

ConcurrentReadableHashMap provides for relatively quick lookups by using a hash
table. Rearders perform an atomic increment/decrement in order to inform writers
that there are active readers. The design attempts to minimize wasted memory by
storing the actual elements out-of-line, and having the table store indices into
a separate array of elements.

The protocol conformance cache now uses ConcurrentReadableHashMap, which
provides faster lookups and less memory use than the previous ConcurrentMap
implementation. The previous implementation caches
ProtocolConformanceDescriptors and extracts the WitnessTable after the cache
lookup. The new implementation directly caches the WitnessTable, removing an
extra step (potentially a quite slow one) from the fast path.

The previous implementation used a generational scheme to detect when negative
cache entries became obsolete due to new dynamic libraries being loaded, and
update them in place. The new implementation just clears the entire cache when
libraries are loaded, greatly simplifying the code and saving the memory needed
to track the current generation in each negative cache entry. This means we need
to re-cache all requested conformances after loading a dynamic library, but
loading libraries at runtime is rare and slow anyway.

rdar://problem/67268325
2020-08-20 13:05:30 -04:00
Nate Chandler
9e6d68e45b [Runtime] Let existential types satisfy superclass requirements.
Previously, when an attempt was made to instantiate a generic metadata
whose argument was constrained to subclass a superclass Super with an
existential type E that had a superclass constraint to a subclass Sub of
that same superclass Super, the instantiation would fail at runtime,
despite the fact that the generic instantiation was allowed to
type-check.

The result was a runtime failure to instantiate generic metadata
resulting eventually in a crash.

Here, handling for that situation is added.  When checking generic
requirements at runtime, when a superclass requirement is encountered,
an existential type is checked for.  If that existential type has a
superclass constraint and if that superclass constraint is a subclass of
the superclass requirement, the check is determined to be satisfactory.

rdar://problem/64672291
2020-07-02 17:19:55 -07:00
Anthony Latsis
9fd1aa5d59 [NFC] Pre- increment and decrement where possible 2020-06-01 15:39:29 +03:00
Mike Ash
ad09919891 [Runtime] Expose the protocol conformance state as a _swift_debug variable.
Have Remote Mirror look that up instead of the C++ mangled name.

rdar://problem/55481578
2020-05-29 08:31:03 -07:00
Mike Ash
2dd3b94852 [Runtime] Remove inactive code that looked up entries in the protocol conformance cache by type descriptor 2020-05-29 08:31:03 -07:00
Saleem Abdulrasool
c050a26aeb runtime: further isolate runtime from LLVMSupport
This cleans up some more `llvm::` leakage in the runtime when built into
a static library.  With this change we are down to 3 leaking symbols in
the static library related to a missed ADT (`StringSwitch`).
2020-05-28 12:42:11 -07:00
Saleem Abdulrasool
e72b43f374 runtime: namespace SmallVectorImpl for inline namespace
This adjusts the use of `SmallVectorImpl` to allow the runtime to use
inline namespaces for its local copy of LLVMSupport.
2020-05-13 11:10:47 -07:00
Saleem Abdulrasool
2ea11b5428 runtime: remove use of swift/LLVM.h (NFC)
Rather than using the forward declaration for the LLVMSupport types,
expect to be able to use the full declaration.  Because these are
references in the implementation, there is no reason to use a forward
declaration as the full types need to be declared for use.  The LLVM
headers will provide the declaration and definition for the types.  This
is motivated by the desire to ensure that the LLVMSupport symbols are
properly namespaced to avoid ODR violations in the runtime.
2020-05-07 13:37:31 -07:00
Saleem Abdulrasool
b74f42602a runtime: add and switch to SWIFT_USED (NFC)
This further trims dependencies to LLVMSupport by introducing the
equivalent `SWIFT_USED` macro.
2020-05-06 21:19:14 -07:00
Nate Chandler
2863f1964d [Runtime] Handle incomplete class metadata in _checkGenericRequirements.
When constructing the metadata for a type Gen<T : Super>
where Super is a superclass constraint, the generic argument K at which
the metadata for Gen is being instantiated is verified to be a subclass
of Super via _checkGenericRequirements.

Previously, that check was done using swift_dynamicCastMetatype.  That
worked for the most part but provided an incorrect answer if the
metadata for K was not yet complete.  These classes are incomplete more
often thanks to __swift_instantiateConcreteTypeFromMangledNameAbstract.

That issue occurred concretely in the following case:

  Framework with Library Evolution enabled:

    open class Super { ... }
    public struct Gen<T : Super> {
    }

  Target in a different resilience domain from that framework:

    class Sub : Super {
      var gen: Gen<Sub>?
    }

Here, the mechanism for checking whether the generic argument K at which
the metadata for Gen is being instantiated handles the case where K's
metadata is incomplete.  At worst, every superclass name from super(K)
up to Super are demangled to instantiate metadata.  A number of faster
paths are included as well.

rdar://problem/60790020
2020-04-03 13:28:54 -07:00