Commit Graph

102 Commits

Author SHA1 Message Date
Arnold Schwaighofer
853388c930 Merge pull request #20478 from aschwaighofer/disable_dynamic_replacement_chaining
Add support to modify chaining behavior of dynamic replacements
2018-11-12 10:37:58 -08:00
John McCall
75e1df6ef8 [NFC] Minor conveniences for working with metadata. 2018-11-10 02:08:04 -05:00
Arnold Schwaighofer
fb7b223ba2 Add support to modify chaining behavior of dynamic replacements
Default to not chain dynamic replacements: Only one replacement and the
original implementation are active.
2018-11-09 13:17:09 -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
Arnold Schwaighofer
44b3a47e56 Merge pull request #20333 from aschwaighofer/dynamic_function_replacement
Dynamic function replacement
2018-11-07 13:08:46 -08:00
Doug Gregor
bc239d37a2 [Runtime] Use the Swift calling convention for swift_getAssociatedTypeWitness.
Runtime functions need to use the Swift calling convention for any function
returning MetadataResponse, so that we get the two values returned in separate
registers.

Fixes rdar://problem/45042971 and rdar://problem/45851050.
2018-11-07 09:26:30 -08:00
Arnold Schwaighofer
152e8db8bb IRGen and runtime implementation for dynamic replacements 2018-11-06 09:58:36 -08: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
a0e3258ba6 [ABI] Collapse generic witness table into protocol conformance record.
Collapse the generic witness table, which was used only as a uniquing
data structure during witness table instantiation, into the protocol
conformance record. This colocates all of the constant protocol conformance
metadata and makes it possible for us to recover the generic witness table
from the conformance descriptor (including looking at the pattern itself).

Rename swift_getGenericWitnessTable() to swift_instantiateWitnessTable()
to make it clearer what its purpose is, and take the conformance descriptor
directly.
2018-10-22 23:36:31 -07:00
Doug Gregor
41891f6266 [ABI] Move the resilient witness table into the conformance descriptor.
Place resilient witnesses in the protocol conformance descriptor,
tail-allocated after the conditional requirements, so they can be found by
reflection. Drop the resilient witness table and protocol descriptor from
the generic witness table.

Addresses rdar://problem/45228582.
2018-10-12 15:36:20 -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
a24729afb8 [ABI] Add a mangled superclass type to class context descriptors.
This allows us to recover the complete superclass type from metadata.
Currently unused, but we want to stub out the space in the ABI.
2018-10-03 20:55:17 -07:00
Doug Gregor
a4778e1c0c [ABI] Only emit resilient superclass descriptor references in class metadata.
The superclass descriptor reference in class context descriptors is only used
for metadata bound computations when the superclass is resilient. Only
include the superclass descriptor reference when the class has a resilient
superclass, using a trailing record. It’s a tiny space savings for
classes that don’t have resilient superclasses.
2018-10-03 20:05:28 -07:00
Doug Gregor
1416f8dd7d [Runtime] Witness table accessors no longer take the count. 2018-09-26 23:19:34 -07:00
Doug Gregor
c3d0ba8df4 [IRGen/Runtime] Witness tables with dependent associated types need instantiation.
Associated type witnesses in a witness table are cache entries, which are
updated by the runtime when the associated types are first accessed. The
presence of an associated type witness that involves type parameters requires
the runtime to instantiate the witness table; account for that in the runtime.
The presence of any associated type witness makes the witness table
non-constant.
2018-09-26 23:19:33 -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
Joe Groff
93d85997e8 Generalize extra inhabitants of tuples.
Like we did for structs, make it so that tuple types can also get extra inhabitants from whichever element with the most, not only the first. This lets us move all of the extra inhabitant handling functionality between structs and tuples in IRGen up to the common RecordTypeInfo CRTP base.
2018-09-20 15:39:44 -07:00
Doug Gregor
350391db9d [ABI] Use associated type descriptors for generic parameter references.
Generic parameter references, which occur in generic requirement
metadata, were hardcoding associated type indices. Instead, use
relative references to associated type descriptors and perform the
index calculation at runtime.

Associated types can now be reordered resiliently (without relying on 
sorting), which is the first main step toward rdar://problem/44167982.
2018-09-14 20:59:03 -07:00
Slava Pestov
ca58db21b4 Runtime: Introduce swift_lookUpClassMethod() 2018-09-07 21:50:58 -07:00
Slava Pestov
870c58e017 IRGen: Change method descriptor layout to be consistent with protocol requirements
Both now have a flags field followed by the implementation.
2018-09-04 14:46:34 -07:00
Slava Pestov
b7449d5621 IRGen/Runtime: Method override descriptors 2018-09-04 14:46:34 -07:00
Slava Pestov
04143abaf1 Runtime: Refactor getVTableOffset() and getFieldOffsetVectorOffset()
Instead of taking class metadata as a parameter, we can recover
the immediate member offset from the descriptor itself.
2018-09-04 14:46:34 -07:00
Slava Pestov
44c4497ac5 IRGen/Runtime: Protocol requirement descriptors don't need to reference the dispatch thunk 2018-08-31 00:16:22 -07:00
Slava Pestov
fcbe997e72 IRGen/Runtime: Use method descriptors instead of dispatch thunks as keys in resilient witness tables 2018-08-31 00:16:22 -07:00
Slava Pestov
1a5c0023d6 Rutime: Code review feedback from John 2018-08-24 00:52:36 -07:00
Slava Pestov
8be09fef74 IRGen/Runtime: Rename "InPlaceMetadata" to "SingletonMetadata"
It's not actually "in-place" for resilient classes, which have a
pattern with an allocation function.
2018-08-24 00:52:36 -07:00
Slava Pestov
03cb6d1ff4 IRGen/Runtime: Use a true-const pattern to initialize non-generic resilient class metadata
Previously we would emit class metadata for classes with resilient
ancestry, and relocate it at runtime once the correct size was known.

However most of the fields were blank, so it makes more sense to
construct the metadata from scratch, and store the few bits that we
do need in a true-const pattern where we can use relative pointers.
2018-08-23 23:40:08 -07:00
Slava Pestov
6150e34508 Runtime/IRGen: Two-phase metadata initialization for resilient classes
Similar to the non-resilient case, except we also emit a 'relocation
function'. The class descriptor now contains this relocation function
if the class has resilient ancestry, and the relocation function
calls the runtime's swift_relocateClassMetadata() entry point.

The metadata completion function calls swift_initClassMetadata() and
does layout, just like the non-resilient case.

Fixes <rdar://problem/40810002>.
2018-08-20 16:26:47 -07:00
Slava Pestov
a86a71de1e Runtime/IRGen: Two-phase metadata initialization for non-resilient classes
Note that this patch also consolidates the recursive metadata tests
into one place while adding an execution test.
2018-08-20 16:23:07 -07:00
Joe Groff
6f45c2a36e IRGen/Runtime: Reference field descriptor directly from type context descriptors.
This saves us some expensive cross-referencing and caching in the runtime, and lets us reclaim the `isReflectable` bit from the context descriptor flags (since a null field descriptor is a suitable and more accurate indicator of whether a type is reflectable).
2018-08-15 14:19:53 -07:00
Joe Groff
5b759f462e Typo in comment, NFC 2018-08-14 14:46:07 -07:00
John McCall
05c9671902 Change the ABI for the type descriptors of imported declarations.
- Instead of keeping multiple flags in the type descriptor flags,
  just keep a single flag indicating the presence of additional
  import information after the name.

- That import information consists of a sequence of null-terminated
  C strings, terminated by an empty string (i.e. by a double null
  terminator), each prefixed with a character describing its purpose.

- In addition to the symbol namespace and related entity name,
  include the ABI name if it differs from the user-facing name of the
  type, and make the name the user-facing Swift name.

There's a remaining issue here that isn't great: we don't correctly
represent the parent relationship between error types and their codes,
and instead we just use the Clang module as the parent.  But I'll
leave that for a later commit.
2018-08-01 18:37:08 -04:00
John McCall
873c02e317 Remove the need to set CTag on all imported tag declarations.
NFC; I'll change the schema to remove CTag in a separate patch.
2018-07-30 22:29:07 -04:00
John McCall
db8f23df74 Update the ABI for uniquing foreign type metadata.
- `swift_getForeignTypeMetadata` is now a request/response function.

- The initialization function is now a completion function, and the
  pointer to it has moved into the type descriptor.

- The cache variable is no longer part of the ABI; it's an
  implementation detail of the access function.

- The two points above mean that there is no special header on foreign
  type metadata and therefore that they can be marked constant when
  there isn't something about them that needs to be initialized.

The only foreign-metadata initialization we actually do right now is
of the superclass field of a foreign class, and since that relationship
is a proper DAG, it's not actually possible to have recursive
initialization problems.  But this is the right long-term thing to do,
and it removes one of the last two clients of once-based initialization.
2018-07-29 03:16:35 -04:00
Dante Broggi
6890810e68 fix typo in comment 2018-07-28 14:32:42 -04:00
John McCall
d10239313f Reference runtime-only ObjC classes with bare strings.
As part of this, rename TypeMetadataRecordKind to TypeReferenceKind
and consistently give it three bits of storage.

The better modelling of these type references appears to have been
sufficient to make dynamic conformance checks succeed, which is good
but unexpected.
2018-07-27 22:55:22 -04:00
Davide Italiano
44cccd011e Merge pull request #18205 from dcci/valuewittarget
[Runtime] Targetize the layout of ValueWitnessTable.
2018-07-25 14:00:26 -07:00
Davide Italiano
1c3c1904a4 [Runtime] Targetize the layout of ValueWitnessTable.
From what I see the only fields are DATA_VALUE_WITNESS which
all have type size_t. I converted them to use the target-dependent
`StoredSize`. While I was around I fixed also isValueInline()
to do the right thing (it was using ValueBuffer instead of
TargetValueBuffer) and all the getters for the data value witnesses.

<rdar://problem/41546568>
2018-07-25 11:37:57 -07:00
John McCall
dadb51e708 Support in-place value metadata initialization in the runtime. 2018-07-25 03:00:36 -04:00
Doug Gregor
191db1ea65 [Runtime] TargetProtocolDescriptor is not a TrailingGenericContextObjects.
Protocols are never generic, so don't inherit from
TrailingGenericContextObjects. Instead, directly use
swift::ABI::TrailingObjects. Since protocols are never generic, this
doesn't actually affect layout at all; it's cleanup.
2018-07-24 11:31:02 -07:00
Doug Gregor
3039fb3d0e Eliminate now-unused (Literal)(Target)ProtocolDescriptorList.
These were used to encode the “inherited protocols” for Objective-C
Protocol structures. These are no longer a part of either Swift protocol
descriptors or the part of Objective-C Protocol structures that the
Swift runtime inspects.
2018-07-24 04:27:23 -07:00
Doug Gregor
a54a6d8d7f [ABI] Rework protocol descriptor metadata.
Reimplement protocol descriptors for Swift protocols as a kind of
context descriptor, dropping the Objective-C protocol compatibility
layout. The new protocol descriptors have several advantages over the
current implementation:

* They drop all of the unused fields required for layout-compatibility
  with Objective-C protocols.
* They encode the full requirement signature of the protocol. This
  maintains more information about the protocol itself, including
  (e.g.) correctly encoding superclass requirements.
* They fit within the general scheme of context descriptors, rather than
  being their own thing, which allows us to share more code with
  nominal type descriptors.
* They only use relative pointers, so they’re smaller and can be placed
  in read-only memory

 Implements rdar://problem/38815359.
2018-07-23 22:12:42 -07:00
Doug Gregor
a777c5c6a9 [Metadata reader] Separate ObjC and Swift protocol descriptor reading.
When reading the protocol metadata from existential type metadata,
check the “isObjC” bit and handle the reading of the Objective-C
protocol name (using TargetObjCProtocolPrefix) separately from the reading the name of a Swift protocol (using TargetProtocolDescriptor).
More preparation for separating the layout of these two entities.
2018-07-23 17:08:59 -07:00
Doug Gregor
7727e5e62e [Runtime] Use a prefix Objective-C protocol layout to extract the name.
Introduce TargetObjCProtocolPrefix, which describes just enough of the
Objective-C runtime’s Protocol structure to extract the name without
having to call Objective-C’s protocol_getName().
2018-07-23 17:08:59 -07:00
Doug Gregor
89e322032a [Runtime] Minor cleanups to reduce dependency on Swift/ObjC protocol overlap.
As a small step toward splitting apart the Swift and Objective-C protocol
descriptors, eliminate most places where we rely on a shared representation.
2018-07-23 17:08:58 -07:00
Doug Gregor
c7a02a26a1 [ABI] Distinguish Swift/ObjC protocols in TargetGenericRequirement.
In a generic requirement, distinguish between Swift and
Objective-C protocols using a spare bit within the relative
(indirectable) reference to the protocol.
2018-07-22 22:48:57 -07:00
Doug Gregor
03c3baab6e [Runtime] TargetProtocolDescriptorRef cleanups.
Eliminate an unnecessary nullptr constructor and make the Metadata
unit test compile when Objective-C interoperability is disabled.
2018-07-22 21:05:45 -07:00
Doug Gregor
bec722df57 [Runtime/IRGen] Switch swift_getExistentialTypeMetadata() to ProtocolDescriptorRef.
Switch one entry point in the runtime (swift_getExistentialTypeMetadata)
to use ProtocolDescriptorRef rather than a protocol descriptor. Update
IRGen to produce ProtocolDescriptorRef instances for its calls, setting
the discriminator bit appropriately.

Within the runtime, verify that all instances of ProtocolDescriptorRef have
the right layout, i.e., the discriminator bit is set for @objc protocols
but not Swift protocols.
2018-07-21 07:48:34 -07:00
Doug Gregor
3464929638 [ABI] Rework existential type metadata to use ProtocolDescriptorRef.
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.
2018-07-20 20:54:49 -07:00
Doug Gregor
e5921ab029 [ABI] Introduce TargetProtocolDescriptorRef.
TargetProtocolDescriptorRef provides a reference to either a Swift or
an Objective-C protocol, using a spare bit to indicate which kind of
protocol it is. At present, the protocol descriptor also has this
information (so this is redundant), but that will change shortly.

There are no clients of TargetProtocolDescriptorRef yet.
2018-07-20 20:54:49 -07:00