Commit Graph

1019 Commits

Author SHA1 Message Date
Doug Gregor
441fee071a [Witness tables] Use a discriminator bit for default associated type witnesses
Indicate whether a particular associated type witness is a default (whose
mangled name is relative to the protocol) vs. being supplied as part of the
conformance (whose mangled name is relative to the conforming type). The
use of pointer identity to distinguish these cases can fail due to the
coalescing of these linker symbols.
2018-09-27 13:26:31 -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
d537249397 [IRGen] Remove all mention of (default|) associated type access functions.
Everything goes through swift_getAssociatedTypeWitness() now.
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
Slava Pestov
3b60ae153d AST: Rename AnyFunctionType::Param::getType() to getOldType() 2018-09-26 11:05:23 -07:00
Doug Gregor
789655836f [IRGen] Give property behavior conformances protocol conformance descriptors.
Protocol conformance descriptors are recorded in witness tables and are
needed to evaluate associated type witnesses. Start creating them for
property behavior conformances, but don’t put them in the section used
for reflection.
2018-09-25 20:49:22 -07:00
Arnold Schwaighofer
149b891785 IRGen: Witness method concrete wtable fulfillment
This is a rebase of John Mccall's patch from
https://github.com/rjmccall/swift/tree/concrete-wtable-fulfillment

SR-7657
rdar://40149340
2018-09-24 07:21:58 -07:00
Doug Gregor
b49780c67a [IRGen] Move the protocol conformance descriptor builder.
Place it right there next to the WitnessTableBuilder, because the
two should be the same thing. NFC
2018-09-21 11:27:34 -07:00
Doug Gregor
d076e41f32 [IRGen] Put associated conformance accessors in resilient witness table
For a resilient conformance, emit the associated conformance accessor
functions into the resilient witness table (keyed on the associated
conformance descriptor) rather than in the fixed part of the witness
table. This is another part of resilience for associated conformances,
and a step toward defaults for associated conformances.
2018-09-17 21:58:56 -07:00
Doug Gregor
8a9df1ce34 [IRGen] Implement resilient access pattern for associated conformances.
When referencing an associated conformance in a witness table for a
resilient protocol, use the associated conformance descriptor to compute
the index into the witness table at run-time.

Another part of rdar://problem/44167982.
2018-09-17 17:26:05 -07:00
Doug Gregor
2ef9363bd1 [ABI] Add default associated type witnesses to resilient protocols.
When an associated type witness has a default, record that as part of
the protocol and emit a default associated type metadata accessor into the
default witness table. This allows a defaulted associated type to be
added to a protocol resiliently.

This is another part of rdar://problem/44167982, but it’s still very
limiting because the new associated type cannot have any conformances.
2018-09-15 22:04:46 -07:00
Doug Gregor
0fa1590e16 [IRGen] Fix associated type resilience for 32-bit platforms. 2018-09-14 22:29:38 -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
Doug Gregor
6948073499 [IRGen] Simplify nondependent associated type witness metadata accessors.
When we’re creating an associated type witness metadata accessor for
resilience reasons, but the associated type witness doesn’t involve any
type parameters, directly form the type metadata reference (and don’t
cache it).

While here… update all of the IRGen/SILGen test cases perturbed by the
introduction of resilient associated type access patterns.
2018-09-14 20:59:03 -07:00
Doug Gregor
cab6bfa6af [ABI] Emit associated type witnesses resiliently.
Emit associated type witnesses into resilient conformance tables, so they
can be re-ordered within the protocol without breaking clients. This will
(eventually) permit adding new, defaulted associated types to protocols
resiliently.
2018-09-14 20:59:03 -07:00
Doug Gregor
73f51a1a17 [IRGen] Implement resilient associated type witness access pattern.
When accessing the associated type witness metadata for a resilient
protocol, compute the index based on the difference between the
associated type’s descriptor and the protocol requirement base descriptor
to determine the offset into the witness table.
2018-09-14 20:59:03 -07:00
Slava Pestov
c3481ab8c3 IRGen: Refuse to compute witness table layouts of resilient protocols
It's not correct to depend on the order of entries in a witness table
if the protocol is resilient, so don't even try.
2018-09-07 11:22:35 -07:00
Doug Gregor
2e608547ba [IRGen] Use the requirement signature to determine dependent conformances.
The “inherited protocols” are as-written, rather than the minimized
set we should be using in IRGen.
2018-09-05 13:51:26 -07:00
Slava Pestov
b7449d5621 IRGen/Runtime: Method override descriptors 2018-09-04 14:46:34 -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
e78f16fb69 AST: ProtocolConformance::subst() doesn't need to take substType 2018-08-25 00:31:07 -07:00
Arnold Schwaighofer
622ccfaf6f Merge pull request #18760 from aschwaighofer/conditional_conf_instantiation
IRGen: Bind local type metadata from conformance's type in a conditional conformance's instantiation function
2018-08-17 06:06:38 -07:00
Jordan Rose
ef06972428 [IRGen] Simplify the ownership of ProtocolInfo (#18704)
Rather than keep a singly-linked list of ProtocolInfo objects to free,
just rely on them being cached in the single DenseMap in
TypeConverter.
2018-08-16 13:09:36 -07:00
Arnold Schwaighofer
437e938904 IRGen: Bind local type metadata from conformance's type in a conditional conformance's instantiation function
rdar://43096256
SR-8495
2018-08-16 12:25:41 -07:00
Jordan Rose
f505c8b8a0 [IRGen] Add some PrettyStackTraces for metadata emission (#18727) 2018-08-15 12:51:20 -07:00
Jordan Rose
84f471b031 [IRGen] Handle ProtocolInfo for protocols whose members aren't used (#18692)
Certain uses of protocols only formally need the requirement
signature, not any of the method requirements. This results in IRGen
seeing a protocol where none of the members have been validated except
the associated types. Account for this by allowing ProtocolInfo to
only contain the layout for the base protocols and associated types,
if requested.

Note that this relies on the layout of a witness table always putting
the "requirement signature part" at the front, or at least at offsets
that aren't affected by function requirements.

rdar://problem/43260117
2018-08-14 11:10:02 -07:00
Slava Pestov
41aebf8e5a IRGen: Simplify NominalMetadataVisitor's treatment of generic requirements
We don't need to substitute the superclass type as we walk up a
class hierarchy, or look up the generic parameters and conformances
to check if they're concrete, since we're always just emitting
null pointers in place of the generic parameters and requirements,
to be filled at runtime.

Also, don't leave space for generic parameters and requirements from
Objective-C superclasses, since that's not how they're represented.
2018-08-14 00:20:12 -07:00
Jordan Rose
d52dad3732 [IRGen] Extract getConformance from ProtocolInfo (#18681)
We were using this just as a convenient way to share an existing
DenseMap, but it's not really related; we don't need to compute
witness table layout just to generate a conformance reference.

I started working on this because the "Cub" source compat project was
hitting issues here, but now I can't reproduce it. Still, this is a
reasonable cleanup.
2018-08-13 17:16:41 -07: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
John McCall
dc052e6364 Resolve metadata cycles through non-generic value types with resilient layout.
The central thrust of this patch is to get these metadata initializations
off of `swift_once` and onto the metadata-request system where we can
properly detect and resolve dependencies.  We do this by first introducing
runtime support for resolving metadata requests for "in-place"
initializations (committed previously) and then teaching IRGen to actually
generate code to use them (this patch).

A non-trivial amount of this patch is just renaming and refactoring some of
existing infrastructure that was being used for in-place initializations to
try to avoid unnecessary confusion.

The remaining cases that are still using `swift_once` resolution of
metadata initialization are:

- non-generic classes that can't statically fill their superclass or
  have resilient internal layout

- foreign type metadata

Classes require more work because I'd like to switch at least the
resilient-superclass case over to using a pattern much more like what
we do with generic class instantiation.  That is, I'd like in-place
initialization to be reserved for classes that actually don't need
relocation.

Foreign metadata should also be updated to the request/dependency scheme
before we declare ABI stability.  I'm not sure why foreign metadata
would ever require a type to be resolved, but let's assume it's possible.

Fixes part of SR-7876.
2018-07-25 15:21:55 -04: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
Ben Cohen
2b04e9f105 Suppress a number of warnings in no-assert builds (#17721)
* Supress a number of warnings about things used only in asserts

* Re-use a couple of variables instead of supressing the warning
2018-07-04 07:15:14 -07:00
Robert Widmann
26d2795efc Excise simpler uses of getInput 2018-06-11 17:29:29 -07:00
Joe Groff
b859f7a4a1 Merge pull request #16923 from jckarter/type-of-mixed-class
IRGen: Use `swift_getObjectType` to get the `type(of:)` mixed classes.
2018-06-04 10:41:09 -07:00
Joe Groff
94a3eaa1ab IRGen: Use swift_getObjectType to get the type(of:) mixed classes.
A Swift subclass of an ObjC class can be dynamically subclassed, but `type(of:)` shouldn't return the artificial subclass, since that's not what -class does for ObjC classes, and people expect `Bundle(for: type(of: c))` to work like `[NSBundle bundleForClass: [c class]]` would in ObjC. Fixes rdar://problem/37319860.
2018-05-31 12:56:27 -07:00
Slava Pestov
ebb1198d57 AST: There's no longer any reason to pass SubstitutionMap by const reference
SubstitutionMaps are now just a trivial pointer-sized value, so
pass them by value instead.

I did have to move a couple of functors from Type.h to SubstitutionMap.h
to resolve some issues with forward declarations.
2018-05-19 00:45:36 -07:00
Adrian Prantl
c241ff305e Emit compiler-generated debug locations for outlined transparent functions.
In the majority of the use-cases transparent functions are inlined by
the mandatory inliner which by design drops all debug info and
pretends the inlined instructions were always part of the
caller. Since an outlined copy of the function is often still
generated, attaching debug locations to it is inconsistent and can
create the false impression that it were possible to set a breakpoint
in such a function when in reality these functions are only there for
very few edge cases.

<rdar://problem/40258813>
2018-05-17 16:38:04 -07:00
Arnold Schwaighofer
b83941795a Unique synthesized foreign type conformances
- Add swift_getForeignWitnessTable to unique non-unique foreign type
   witness tables

 - IRGen: Call the foreign witness uniquing runtime function

rdar://24958043
2018-05-14 13:52:41 -07:00
Doug Gregor
ef020c74aa Eliminate all vestiges of Substitution and SubstitutionList.
Introduced during the bring-up of the generics system in July, 2012,
Substitution (and SubstitutionList) has been completely superseded by
SubstitutionMap. R.I.P.
2018-05-11 21:43:40 -07:00
Slava Pestov
757a7a425e IRGen: Fix protocol conformances for Objective-C runtime classes
We were emitting foreign type metadata for this case, because of an
invalid usage of ClassDecl::isForeign(), which also returns true
for runtime-only classes.

Fixes <rdar://problem/39117602>.
2018-04-10 18:04:38 -07:00
Joe Groff
0bfe25072b Merge pull request #15798 from jckarter/objc-value-metatype
IRGen: Make type(of:) behavior consistent in ObjC bridged contexts.
2018-04-09 11:13:27 -07:00
Joe Groff
a4aa054838 IRGen: Make type(of:) behavior consistent in ObjC bridged contexts.
When we use type(of: x) on a class in an ObjC bridged context, the optimizer turns this into a SIL `value_metatype @objc` operation, which is supposed to get the dynamic type of the object as an ObjC class. This was previously lowered by IRGen into a `object_getClass` call, which extracts the isa pointer from the object, but is inconsistent with the `-class` method in ObjC or with the Swift-native behavior, which both look through artificial subclasses, proxies, and so on. This inconsistency led to observably different behavior between debug and release builds and between ObjC-bridged and native entry points, so provide an alternative runtime entry point that replicates the behavior of getting a native Swift class. Fixes SR-7258.
2018-04-06 15:17:04 -07:00
Arnold Schwaighofer
ae0f98d601 IRGen: Ensure collocation of relative pointers in resilient witness tables
Ensure collocation by recording the dependence between witness table and
witness before functions are processed. Debug info of inlined function
scopes can reference the witness and will cause the wrong IRGenModule to
be associated before lazy witness tables are processed.

No, I am not sure that this is the only instance of this but the same
solution can apply to other instances if we find them.

rdar://39116991
2018-04-06 10:03:54 -07:00
Slava Pestov
2f0440eafe IRGen: Force witness thunks to be emitted in the same thread as the witness table
Otherwise, they might end up in a different translation unit,
and we will be unable to form a relative reference.
2018-03-29 15:23:20 -07:00
Slava Pestov
588448684b IRGen: Emit resilient witness tables 2018-03-29 14:03:58 -07:00
Slava Pestov
72b56ec66b Runtime: New mechanism for resilient witness table instantiation 2018-03-29 14:03:58 -07:00
Slava Pestov
0edce39a24 IRGen: Remove unused parameters from isDependentConformance() 2018-03-29 14:03:58 -07:00
Slava Pestov
30a3e75fe9 IRGen: Fix dependent witness table linkage
Witness tables for conformances that require runtime instantiation
should not be public, because it is an error to directly reference
such a symbol from outside the module.

Use a different mangling for witness table patterns and give them
non-public linkage.
2018-03-28 20:58:14 -07:00
Slava Pestov
d1da8f3471 IRGen: Conformance records for dependent conformances should reference the witness table accessor function
... and not the pattern, which is about to get non-public linkage.
2018-03-28 20:13:12 -07:00
John McCall
a906f43329 Allow type metadata to be incomplete.
Most of the work of this patch is just propagating metadata states
throughout the system, especially local-type-data caching and
metadata-path resolution.  It took a few design revisions to get both
DynamicMetadataRequest and MetadataResponse to a shape that felt
right and seemed to make everything easier.

The design is laid out pretty clearly (I hope) in the comments on
DynamicMetadataRequest and MetadataResponse, so I'm not going to
belabor it again here.  Instead, I'll list out the work that's still
outstanding:

- I'm sure there are places we're asking for complete metadata where
  we could be asking for something weaker.

- I need to actually test the runtime behavior to verify that it's
  breaking the cycles it's supposed to, instead of just not regressing
  anything else.

- I need to add something to the runtime to actually force all the
  generic arguments of a generic type to be complete before reporting
  completion.  I think we can get away with this for now because all
  existing types construct themselves completely on the first request,
  but there might be a race condition there if another asks for the
  type argument, gets an abstract metadata, and constructs a type with
  it without ever needing it to be completed.

- Non-generic resilient types need to be switched over to an IRGen
  pattern that supports initialization suspension.

- We should probably space out the MetadataStates so that there's some
  space between Abstract and Complete.

- The runtime just calmly sits there, never making progress and
  permanently blocking any waiting threads, if you actually form an
  unresolvable metadata dependency cycle.  It is possible to set up such
  a thing in a way that Sema can't diagnose, and we should detect it at
  runtime.  I've set up some infrastructure so that it should be
  straightforward to diagnose this, but I haven't actually implemented
  the diagnostic yet.

- It's not clear to me that swift_checkMetadataState is really cheap
  enough that it doesn't make sense to use a cache for type-fulfilled
  metadata in associated type access functions.  Fortunately this is not
  ABI-affecting, so we can evaluate it anytime.

- Type layout really seems like a lot of code now that we sometimes
  need to call swift_checkMetadataState for generic arguments.  Maybe
  we can have the runtime do this by marking low bits or something, so
  that a TypeLayoutRef is actually either (1) a TypeLayout, (2) a known
  layout-complete metadata, or (3) a metadata of unknown state.  We could
  do that later with a flag, but we'll need to at least future-proof by
  allowing the runtime functions to return a MetadataDependency.
2018-03-26 12:18:04 -04:00