Commit Graph

426 Commits

Author SHA1 Message Date
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
f64044e762 [Runtime] Improve fatal error when unable to demangle an associated type witness. 2018-09-26 23:19:33 -07:00
Doug Gregor
5f56d2faf9 [Runtime] Properly turn a const char* into a StringRef for a mangled name.
Use makeSymbolicMangledNameStringRef() to skip over null characters within
symbolic references.
2018-09-26 23:19:33 -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
Slava Pestov
4da47823a5 Runtime/IRGen: Add new initialization pattern for classes with backward deployment layout
If a class has a backward deployment layout:

- We still want to emit it using the FixedClassMetadataBuilder.

- We still want it to appear in the objc_classes section, and get an
  OBJC_CLASS_$_ symbol if its @objc.

- However, we want to use the singleton metadata initialization pattern
  in the metadata accessor.

- We want to emit metadata for all field types, and call the
  swift_updateClassMetadata() function to initialize the class
  metadata.

For now, this function just performs the idempotent initialization of
invoking a static method on the class, causing it to be realized with
the Objective-C runtime.
2018-09-23 21:26:46 -07:00
Slava Pestov
0088055f77 Runtime: Set up the class's runtime name in initGenericObjCClass() 2018-09-23 21:26:46 -07:00
Slava Pestov
0e4248375d Runtime: Introduce a new code path for initializing non-generic class metadata
It's a bit simpler because we don't have to change the ivar descriptors
back and forth.
2018-09-23 21:26:46 -07:00
Slava Pestov
62aecd31b7 Runtime: Split up swift_initClassMetadata()
- Rename _swift_initializeSuperclass() to copySuperclassMetadataToSubclass(),
- Factor out initClassFieldOffsetVector()
- Factor out initClassVTable()
- Factor out initGenericObjCClass()
2018-09-23 21:26:46 -07:00
Slava Pestov
6084dc285e Runtime: Only initialize metaclass superclass if superclass is generic
Otherwise, we emitted a static reference to its metaclass, so there's
no need to overwrite it here. This doesn't really improve anything,
it was just something I noticed while auditing this code in
preparation for a refactoring, so may as well fix it.
2018-09-23 21:26:46 -07:00
Slava Pestov
724830acd5 Runtime: Use the resilient metadata allocator instead of malloc() for resilient classes
Also move getResilientMetadataAllocator() and swift_relocateClassMetadata() to the top
of the "classes" section, instead of putting it in the middle.
2018-09-23 21:26:46 -07:00
Joe Groff
c87d2a8be2 Merge pull request #19340 from jckarter/generalize-tuple-extra-inhabitants
Generalize extra inhabitants of tuples.
2018-09-20 18:55:31 -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
72ff34e937 Merge pull request #19410 from DougGregor/runtime-remove-duplicate-witnes-check
[Runtime] Remove duplicate witness checking for now.
2018-09-19 22:26:15 -07:00
Doug Gregor
cc32f50691 [Runtime] Remove duplicate witness checking for now.
It's breaking on SwiftPM, so remove it for now and follow-up to
investigate with rdar://problem/44627274.
2018-09-19 20:16:52 -07:00
swift-ci
922c4f0808 Merge pull request #19403 from DougGregor/runtime-remove-warning 2018-09-19 19:12:24 -07:00
Doug Gregor
93f9dc8e76 [Runtime] Remove warning about "missing" witness table entries.
It introduces spurious results.
2018-09-19 15:41:33 -07:00
swift-ci
e5c9d6417e Merge pull request #19398 from DougGregor/resilient-table-init-empty-proto 2018-09-19 15:18:04 -07:00
Doug Gregor
3ed69d4ee7 [Runtime] Instantiate witness tables even with no resilient witnesses.
The witness table for an empty, resilient protocol might need to be
instantiated, if a newer version of the protocol contains defaulted
associated type requirements. In such cases, we would either fail to
instantiate or assert in the runtime. Replace the assertion with a
proper check (to require instantiation in such cases) and cope with
filling in defaults even when the provided generic witness table has
no resilient witnesses.
2018-09-19 14:00:28 -07:00
Doug Gregor
32fd274f5e Merge pull request #19391 from DougGregor/assoc-conformance-default-witnesses
[ABI] Associated conformance defaults
2018-09-19 13:15:46 -07:00
Doug Gregor
ef0aeed788 [Runtime] Reimplement initialization of resilient witness tables.
Replace the quadratic algorithm (currently O(m*n) where m is the number of requirements and n is the number of witnesses) with an O(m+n) algorithm.
Harden the algorithm a against bad and unexpected inputs:
* Fail if the requirement descriptor is out-of-bounds for the protocol
* Skip the witness if the requirement descriptor is null; this can happen
when the witness table was compiled against a newer version of the
protocol, but is deployed to a library containing an older version of the
protocol. It is expected.
* In debug builds of the runtime, complain if an entry is initialized twice
* In debug builds of the runtime, complain if an entry is NULL

Fixes rdar://problem/44434793, which covers the second bullet (backward 
deployment).
2018-09-19 11:46:29 -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
Joe Groff
08419544e4 Fix linker error in debug builds. (#19355) 2018-09-17 16:41:36 -07:00
Joe Groff
fbd21e1bd4 Merge pull request #19296 from jckarter/opaque-existential-extra-inhabitants
Give opaque existential containers extra inhabitants.
2018-09-17 10:48:20 -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
Joe Groff
b4abe8503a Give opaque existential containers extra inhabitants.
We can use the extra inhabitants of the type metadata field as extra inhabitants of the entire
existential container, allowing `Any?` and similar types to be the same size as non-optional
existentials.
2018-09-14 12:07:58 -07:00
Slava Pestov
ca58db21b4 Runtime: Introduce swift_lookUpClassMethod() 2018-09-07 21:50:58 -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
fcbe997e72 IRGen/Runtime: Use method descriptors instead of dispatch thunks as keys in resilient witness tables 2018-08-31 00:16:22 -07:00
John McCall
140ee562d3 Merge pull request #18840 from rjmccall/dematerializeForSet
Replace materializeForSet with the modify coroutine
2018-08-27 21:02:24 -04:00
Joe Groff
75d9e567dd Merge pull request #18630 from jckarter/extra-inhabitants-from-any-fixed-layout-struct-field
IRGen: Use any field of fixed-layout structs for extra inhabitants.
2018-08-27 09:46:42 -07:00
John McCall
b80618fc80 Replace materializeForSet with the modify coroutine.
Most of this patch is just removing special cases for materializeForSet
or other fairly mechanical replacements.  Unfortunately, the rest is
still a fairly big change, and not one that can be easily split apart
because of the quite reasonable reliance on metaprogramming throughout
the compiler.  And, of course, there are a bunch of test updates that
have to be sync'ed with the actual change to code-generation.

This is SR-7134.
2018-08-27 03:24:43 -04: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
50a037d8ed Runtime: Set the superclass in swift_initClassMetadata()
Now that we don't need the superclass before calling
swift_relocateClassMetadata(), it seems simpler to set it
here instead of doing it in various places in IRGen.
2018-08-20 16:23:07 -07:00
Slava Pestov
3256ee43c0 Runtime: swift_relocateClassMetadata() calculates metadata bounds from the class descriptor
Using the superclass metadata here no longer makes sense with two-phase
init, in case the superclass metadata depends on the class being
instantiated.

It would also be nice to rework the resilient class metadata 'pattern'
to be its own data structure that's true const, instead of just the
prefix of a real class metadata, but for now let's keep the existing
crappy design.
2018-08-20 16:23:07 -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
Slava Pestov
24a9a5156c IRGen: In-place initialization for classes with generic ancestry and resiliently-sized fields
If a class has generic ancestry or resiliently-sized fields, but is
itself not generic and does not have resilient ancestry, we must
perform runtime metadata initialization, but we can initialize
the metadata in-place.

As with generic classes or classes with resilient ancestry, we
copy generic requirements and field offset vectors from the
superclass. We also calculate the layout of the class's direct
fields at runtime.

Unlike the fully resilient case, we don't copy vtable entries
from the superclass, or install the direct class's vtable
entries from the type context descriptor. Instead, we statically
emit the vtable as with fixed-size class metadata.

Both the in-place and resilient case call the same runtime
entry point to initialize class metadata; the new HasStaticVTable
flag in ClassLayoutFlags is used to select between the two
behaviors concerning the vtable.
2018-08-20 16:22:35 -07:00
Joe Groff
c11aacc576 KeyPaths: Put an override shim on swift_getKeyPath.
This will let future compilers that support new key path features backward-deploy logic for interpreting new kinds of key path patterns.
2018-08-16 13:15:21 -07:00
Joe Groff
9f02ecd1a5 IRGen: Use any field of structs for extra inhabitants.
This allows us to layout-optimize Optional<T> when T is a struct with an
extra-inhabitant-bearing field anywhere in its definition, not only at
the beginning. rdar://problem/43019427
2018-08-14 12:53:06 -07:00
Joe Groff
fb05ede036 Runtime: Don't attempt to round-trip mangled names for private types.
By design, we don't want private or function-nested types to be accessible by mangled name, since they don't have stable identities, and they could inadvertently become ABI if someone serialized a mangled string and expected to deserialize it into a type. Fixes rdar://problem/39826794 .
2018-08-08 13:52:59 -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
436a8b273d Add runtime functions to compute tuple layouts from element layouts.
Previously, when a tuple type had non-fixed layout, we would compute
a layout by building the metadata for that tuple type and then
extracting the layout from the VWT.  This can be quite expensive
because it involves constructing the exact metadata for types like
arrays and functions despite those types being fixed-layout across
all instantiations.  It also tends to cause unnecessary recursive-type
issues, especially with enums where tuples are currently used to model
cases with mutliple payloads.  Since we just need a layout, computing
it directly from element layouts instead of constructing metadata for
the formal type lets us take advantage of all the other fast paths for
layout construction, e.g. for fixed types and single-field aggregates.

This is a good improvement overall, but it also serves to alleviate
some of the problems of rdar://40810002 / SR-7876 in a way that
might be suitable for integration to 4.2.
2018-07-29 18:27:27 -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
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