Commit Graph

137 Commits

Author SHA1 Message Date
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
Slava Pestov
4e39455173 Update ProtocolConformance.cpp 2020-02-17 17:54:26 -05:00
Slava Pestov
1ca2b61f7a Runtime: Less eager instantiation of type metadata in the conformance cache
The ConformanceCandidate constructor would eagerly instantiate metadata for
all non-generic types in the conformance cache. This was not the intention
of the code though, because it can compare nominal type descriptors --
which are emitted statically -- for those types that have them, namely
everything except for foreign and Objective-C classes.

Change the order of two calls so that the lazy path has a chance to run.
This fixes a crash when type metadata uses weakly-linked symbols
which are not available, which can come up in backward deployment
scenarios.

Fixes <rdar://problem/59460603>.
2020-02-17 16:24:42 -05:00
Ben Cohen
60b4f38660 Eliminate context descriptor cache (#29151) 2020-01-13 15:59:32 -08:00
Mike Ash
6295cecfa7 Merge pull request #26638 from mikeash/fix-protocol-conformances-on-unavailable-classes
[Runtime] Fix swift_conformsToProtocol crashing on conformances to unavailable classes.
2019-08-15 19:09:10 -04:00
pschuh
37c6414e77 Fix usage of uninitialized memory in swift_addNewDSOImage. (#26275)
This should address https://bugs.swift.org/browse/SR-6848.

Couldn't transform the unsafeGet to get because it would produce an
infinite loop.
2019-08-13 13:23:33 -07:00
Mike Ash
6473b9d7cd [Runtime] Fix swift_conformsToProtocol crashing on conformances to unavailable classes.
An extension on a class creates a conformance record that's always visible even when that class is not present at runtime. In that case, the type pointer in the conformance record is NULL. The runtime did not like this, and crashed. This fixes it to ignore such records instead.

rdar://problem/54054895
2019-08-13 14:39:20 -04:00
Mike Ash
a2ed459024 Fix _forEach*SectionAfter to update the start parameter. 2019-08-09 11:19:07 -07:00
Mike Ash
c09adf0394 Add caching based on ABI name to _findContextDescriptor.
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
2019-08-09 11:18:43 -07:00
Doug Gregor
54d3930ae8 [Runtime] Adjust to conforming type when instantiating witness table.
When we find a protocol conformance descriptor for a given type, make sure
we adjust to the conforming type of that descriptor (following the superclass
chain as needed) before instantiating the witness table.

Fixes rdar://problem/49741838.
2019-05-13 20:53:02 -07:00
Joe Groff
05dfec0cda Push the conformance accessor hack down into getTypeByMangledName. 2019-04-17 14:44:40 -07:00
David Zarzycki
b032d0b38f [Runtime] NFC: Move LLVM_ATTRIBUTE_USED from declaration to definition
This is both more correct and now required to keep building with
top-of-tree clang.
2019-03-08 12:35:53 -05:00
Erik Eckstein
a60086f1dd Runtime: use lambdas to avoid allocations in std::function
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
2019-03-06 14:37:03 -08:00
Erik Eckstein
3bd7f027f8 Runtime: use SmallVector instead of std::vector to avoid memory allocations in most cases.
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
2019-03-06 14:37:03 -08:00
Saleem Abdulrasool
618d525b91 runtime: enable stack traces on Windows
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.
2019-03-04 10:39:10 -08:00
John McCall
79d15816c4 Fix a race condition with the initialization of class metadata.
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.
2019-02-05 23:28:57 -05:00
John McCall
d07efd37e0 Requestify the mangling-to-metadata APIs.
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.
2019-02-05 16:20:48 -05:00
Doug Gregor
da772e9155 [Runtime] Make swift::swift_conformsToSwiftProtocol overridable.
This is a funnel point for looking up the protocol conformance descriptor
for a given conforming type + conformance. Make it overridable in case we
need to back-deploy changes or fixes.

Implements rdar://problem/46281660.
2018-11-27 23:37:11 -08:00
Doug Gregor
f9797b4eeb [Runtime] Add dummy "module name" parameter to swift::_conformsToSwiftProtocol.
We know we're going to want this parameter to handle lookup of
retroactive conformances when we've been given a module, so add it
now because we want this to be an overridable entry point.
2018-11-27 16:11:40 -08:00
Doug Gregor
d9bb81bc20 [Runtime] Cache protocol conformance descriptors, not witness tables.
The conformance cache was caching the witness table for a conformance
`T: P`, where `T` is a concrete type and `P` is a protocol. However, it
essentially picked one of potentially many witness tables for that
conformance, because retroactive conformances might produce different results
from different modules.

Make the conformance cache what is says it is: a cache of the conformance
descriptor for a given `T: P`, potentially filtered by a module (when
requested). Clients of the conformance cache can choose how to interpret
the protocol conformance descriptor, e.g., by instantiating a witness table.

We can bring back a specific conformance cache for swift_conformsToProtocol()
if it is profitable.

(cherry picked from commit 0af2af00a739a4d912d2a9c3b196449e4164484f)
2018-11-16 22:26:40 -08:00
John McCall
ff6d031482 Allow TypeReference to refer to protocol descriptors.
We should also allow references via manglings just to cover the
general case if we need it, but this is useful on its own so that
we can emit a reference to any natively-declared Swift type.
2018-11-16 00:39:10 -05:00
Doug Gregor
986b8f3f9f [Runtime] Make swift_getTypeByMangled(Name|Node) overridable.
Rename the funnel points for demangling strings/nodes to metadata to
swift_getTypeByMangled(Name|Node) and make them overridable. This will let
us back-deploy mangling improvements and bug fixes.
2018-11-15 16:43:38 -08:00
Doug Gregor
cd6d6be64d [Runtime] Consolidate runtime functions used for demangle-to-metadata.
Clean up the interfaces used to go from a mangled name or demangle tree to
metadata. Parameterize these interfaces for generic parameter substitutions
(already in use) and dependent conformance substitutions (speculative).
2018-11-15 15:57:44 -08:00
Doug Gregor
201c13ab01 [Runtime] Remove code for handling “flat” generic argument indices.
We no longer encode “flat” indices in the metadata, and have no need for
this now-dead decoding code.
2018-11-15 11:12:41 -08:00
Doug Gregor
c367c8e9cb [Runtime] Adjust "conforming type" based on a given conformance descriptor.
When we are looking for the specific type for a protocol conformance (e.g.,
because we may have a subclass of the type that declared conformances), don't
go back through swift_conformsToProtocol() multiple times, which
requires more lookups in the global conformance table. Instead, use
the (known) protocol conformance descriptor.
2018-11-13 20:45:03 -08:00
Doug Gregor
5758cdcfcc [ABI] Eliminate the special structure for generic parameter references.
TargetGenericParamRef is a specialized structure used to describe the
subject of a generic requirement, e.g., the “T.Assoc” in “T.Assoc: P”.
Replace it with a mangled name, for several reasons:

1) Mangled type names are also fairly concise, can often be shared, and
are a well-tested path
2) Mangled type names can express any type, which might be useful in the
future
3) This structure doesn’t accommodate specifically stating where the
conformances come from (to extract associated type witnesses). Neither
can mangled names, but we’d like to do that work in only one place.

This change exposed an existing bug where we improperly calculated the
generic parameter counts for extensions of nested generic types. Fix that
bug here (which broke an execution test).
2018-11-08 13:58:17 -08:00
Doug Gregor
dd154f6668 [Runtime] Rename swift_instantiateWitnessTable() -> swift_getWitnessTable()
This runtime function doesn’t always perform instantiation; it’s how we
get a witness table given a conformance, type, and set of instantiation
arguments. Name it accordingly.
2018-10-25 20:35:27 -07:00
Doug Gregor
b5bc06e552 [ABI] Eliminate witness table accessors.
Witness table accessors return a witness table for a given type's
conformance to a protocol. They are called directly from IRGen
(when we need the witness table instance) and from runtime conformance
checking (swift_conformsToProtocol digs the access function out of the
protocol conformance record). They have two interesting functions:

1) For witness tables requiring instantiation, they call
swift_instantiateWitnessTable directly.
2) For synthesized witness tables that might not be unique, they call
swift_getForeignWitnessTable.

Extend swift_instantiateWitnessTable() to handle both runtime
uniquing (for #2) as well as handling witness tables that don't have
a "generic table", i.e., don't need any actual instantiation. Use it
as the universal entry point for "get a witness table given a specific
conformance descriptor and type", eliminating witness table accessors
entirely.

Make a few related simplifications:

* Drop the "pattern" from the generic witness table. Instead, store
  the pattern in the main part of the conformance descriptor, always.
* Drop the "conformance kind" from the protocol conformance
  descriptor, since it was only there to distinguish between witness
  table (pattern) vs. witness table accessor.
* Internalize swift_getForeignWitnessTable(); IRGen no longer needs to
  call it.

Reduces the code size of the standard library (+assertions build) by
~149k.

Addresses rdar://problem/45489388.
2018-10-25 20:35:27 -07:00
Doug Gregor
c5e226bb16 [Runtime] Use CF superclass metadata in runtime lookups.
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.
2018-10-16 21:42:02 -07:00
Doug Gregor
aba018c1e8 [ABI] Pass requirement base descriptor to swift_getAssociatedTypeWitness().
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.
2018-10-10 22:45:59 -07:00
Doug Gregor
1416f8dd7d [Runtime] Witness table accessors no longer take the count. 2018-09-26 23:19:34 -07:00
Doug Gregor
5d2f55751a [Runtime] Substitute into associated types using the original conforming type
When producing an associated type witness from a mangled name, adjust the
conforming type metadata to find the original conforming type, which may
be a superclass of the conforming type given.
2018-09-26 23:19:34 -07:00
Doug Gregor
b531b3923f [ABI] Use mangled names for associated type witnesses.
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.
2018-09-26 23:19:33 -07:00
Doug Gregor
5a87435b8e [Runtime] Simplify ProtocolConformanceDescriptor::getWitnessTable().
Use SubstGenericParametersFromMetadata to handle substitutions when
checking generic requirements, extending SubstGenericParametersFromMetadata
for this purpose.
2018-09-22 20:51:03 -07:00
Doug Gregor
3f79cb9976 [Runtime] Replace outdated signature for associated type access functions.
The resolution of generic parameter references, which is used for
checking generic requirements at runtime, was written in terms of an
outdated signature for associated type access functions that did not
account for the MetadataRequest parameter or MetadataResponse result.
Use the existing AssociatedTypeAccessFunction typedef instead.

Fixes SR-7553 / rdar://problem/39769906
2018-09-21 23:47:02 -07:00