This is the first part of making class method dispatch resilient.
If we have the following class hierarchy:
// Module A
class Parent {
func foo() {}
}
class Child : Parent {}
// Module B
class Grandchild : Child {
override func foo() {
super.foo()
}
}
dispatch to `Parent.foo` will be static via a `function_ref`, so if
someone adds a `foo()` to `Child` later on, `Grandchild` won't know
about it without recompiling.
Stage in the IRGen portion of dynamic dispatch when calling methods on
`super`:
- Don't assert in IRGen if we see a native super_method instruction.
- Perform virtual lookup on superclass's metadata. If we see a
`super_method` instruction for a native class:
- Get the address of the superclass's metadata at offset 1
- Load the superclass's metadata
- Perform virtual lookup on this metadata instead
TODO: SILGen super_method instructions for native classes.
TODO: Devirtualize back down to static dispatch with a reslience lookup
mechanism.
rdar://problem/22749732
If a struct has fixed layout but contains fields which are opaque,
or if the struct itself is opaque, use a metadata accessor function
instead of loading the metadata directly.
Let's say that A and B are two structs defined in the same module,
and B has a fixed size. This patch adds support for these two cases:
1) Fixed-layout struct A contains resilient struct B
2) Resilient struct A contains resilient struct B
In case 1),
a) Inside X: A is fixed-size and has constant metadata
i) Direct metadata access can be performed on A and B
ii) Direct field access can be performed on A and B
d) Outside X: B has an opaque layout
i) Metadata accessor must be called for A and B
ii) Fields of A do not have constant offsets, instead the offsets
must be loaded from type metadata
Case 2) is the same as above except ii) does not apply, since fields
of resilient structs are manipulated via accessors.
Eventually, we will use metadata accessor functions for all public
struct and enum types.
NFC, but this set of access modes applies more generally to other kinds of metadata that may need to be guarded by accessors, such as witness tables.
Swift SVN r31838
Full type metadata isn't necessary to calculate the runtime layout of a dependent struct or enum; we only need the non-function data from the value witness table (size, alignment, extra inhabitant count, and POD/BT/etc. flags). This can be generated more efficiently than the type metadata for many types--if we know a specific instantiation is fixed-layout, we can regenerate the layout information, or if we know the type has the same layout as another well-known type, we can get the layout from a common value witness table. This breaks a deadlock in most (but not all) cases where a value type is recursive using classes or fixed-layout indirected structs like UnsafePointer. rdar://problem/19898165
This time, factor out the ObjC-dependent parts of the tests so they only run with ObjC interop.
Swift SVN r30266
Full type metadata isn't necessary to calculate the runtime layout of a dependent struct or enum; we only need the non-function data from the value witness table (size, alignment, extra inhabitant count, and POD/BT/etc. flags). This can be generated more efficiently than the type metadata for many types--if we know a specific instantiation is fixed-layout, we can regenerate the layout information, or if we know the type has the same layout as another well-known type, we can get the layout from a common value witness table. This breaks a deadlock in most (but not all) cases where a value type is recursive using classes or fixed-layout indirected structs like UnsafePointer. rdar://problem/19898165
Swift SVN r30243
It looks like John and Joe already did a good part of this. The previous
patch to enable polymorphic @objc_method signatures takes us further, and
I think this patch fills in the rest.
Fixes <rdar://problem/18505295>, <rdar://problem/20700287>.
Swift SVN r29259
It looks like John and Joe already did a good part of this. The previous
patch to enable polymorphic @objc_method signatures takes us further, and
I think this patch fills in the rest.
Fixes <rdar://problem/18505295>, <rdar://problem/20700287>.
Swift SVN r29137
Store the number of payload and no-payload cases, the case names, and a lazy case type accessor function for enums, like we do for stored properties of structs and classes. This will be useful for multi-payload runtime support, and should also be enough info to hack together a reflection implementation for enums.
For dynamic multi-payload enums to not be ridiculously inefficient, we'll need to track the size of the payload area in the enum, like we do the field offsets of generic structs and classes, so hack off a byte in the payload case count to track the offset of that field in metadata records. 16 million payloads ought to be enough for anyone, right? (and 256 words between the enum metadata's address point and the payload size offset)
Swift SVN r27789
The field type generator may end up producing recursive static references to metadata while we're generating metadata. Fixes rdar://problem/19838839.
Swift SVN r25534
Previously, we were not respecting the representation of the existential
metatype and were treating all existential metatypes as if the metatype
was a thick metatype. Instead now we properly grab the instance of the
class from the existential and then query the runtime for the
objc_class. This is done via the new entrypoint
emitHeapMetadataRefForUnknownHeapObject.
I also modified emitHeapMetadataRefForHeapObject to use
emitHeapMetadataRefForUnknownHeapObject instead of
emitLoadOfObjCHeapMetadataRef since the latter does not properly handle
tagged pointers. This bug was found on inspection when Joe and I were
talking about this change.
rdar://18841292
Swift SVN r23308
layouts. Introduce new SIL instructions to initialize
and open existential metatype values.
Don't actually, y'know, lift any of the restriction on
existential metatypes; just pointlessly burn extra
memory storing them.
Swift SVN r22592
If a type has to be passed or returned resiliently, it
will necessarily be passed indirectly, which is already
represented in SILFunctionType. There is no need to
represent this as a separate channel of information.
NFC. Also fixes a problem where the signature cache
for ExtraData::Block was writing past the end of an
array (but into the storage for an adjacent array
which was fortunately never used).
ExtraData should also disappear as a concept, but we're
still relying on that for existential protocol witnesses.
Swift SVN r21548
unexpected forematter from the superclass.
This requires a pretty substantial shift in the
generic-metadata allocation/initialization dance
because (1) we can't allocate class metadata without
knowing what the superclass is and (2) the offset
from the metadata cache entry to the address point is
no longer determined solely by the metadata pattern.
While I'm making invasive changes to metadata, fix
two race conditions in metadata creation. The first
is that we need to ensure that only one thread succeeds
at lazily creating a generic-metadata cache. The second
is that we need to ensure that only one thread actually
attempts to create a particular metadata; any others
should block until the metadata is successfully built.
This commit finishes rdar://17776354. LLDB will
need to adjust to the runtime-private metadata layout
changes.
Swift SVN r20537
functions, and make those functions memoize the result.
This memoization can be both threadsafe and extremely
fast because of the memory ordering rules of the platforms
we're targeting: x86 is very permissive, and ARM has a
very convenient address-dependence rule which happens to
exactly match the semantics we need.
Swift SVN r20381
Create a global alias into the metadata of @objc-visible classes at their address point, which should make these classes visible for linking from ObjC, fixing <rdar://problem/14449644>.
Swift SVN r15921
LLVM doesn't have interior symbols as a first-class concept, so generate module inline asm that defines the OBJC_CLASS symbol relative to the Swift metadata symbol. To prevent our system linkers from considering this symbol as the start of a new object and breaking apart class metadata objects, put the class metadata object into a no_dead_strip section.
This isn't quite enough to get the OBJC_CLASS symbol to be available--the symbol appears to show up in the .o as an undefined symbol and stripped out of the .dylib. John is investigating with the backend and linker teams as to why this is the case.
Swift SVN r14927
Emit vtable entries for abstract initializers. When we're constructing
an object using an abstract initializer based on a metatype value that
is not statically derivable, use the vtable entry to call the
subclass's allocating constructor.
Most of the IRGen work here is hacking around the lossy SILDeclRef ->
(Code|Function)Ref -> SILDeclRef conversion. I'd feel bad about this
if John hadn't already agreed to clean this up at some point.
Swift SVN r14238
Use the 'thin' bit set by SIL to decide whether a metatype lowers to an empty type or not. In GenPoly we still need to accommodate unlowered metatypes to keep protocol witnesses limping along; hopefully that code can be killed soon. With this change we now lower @cc(witness_method) consistently for static methods.
Swift SVN r11535
When we need a reference to protocol or protocol composition type metadata, ask for it through the runtime, instead of referencing statically-emitted protocol metadata.
Swift SVN r9871
When allocating and deallocating dependent generic class instances, load the instance size and alignment from the metadata instead of trying to use a static size from the compile-time class layout.
Swift SVN r9250
"SILConstant" doesn't really describe its role in SIL anymore, which is to provide a reference to a Swift declaration in a SIL instruction, such as a method or nominal type field.
Swift SVN r6559
Provide TypeInfo for class-bounded existentials, which represents them as an explosion comprising one witness table per subscribed protocol and then the class instance pointer as an ObjC-refcounted pointer. Provide lowerings for the SIL instructions that manipulate class-bounded existentials (except for existential-to-existential erasures, which aren't critical to getting basic operations working and will need some abstraction remapping to deal with class-bounded-to-opaque upcasts aside from the representation change).
Swift SVN r5579
Sever the last load-bearing link between SILFunction and SILConstant by naming SILFunctions with their mangled symbol names. Move the core of the mangler up to SIL, and teach SILGen how to use it to mangle a SILConstant.
Swift SVN r4964
Emit ObjC stubs and categories for methods defined in extensions of ObjC-compatible classes. This makes extensions of ObjC classes available to ObjC in statically compiled code. For immediate-mode code we'll still need to dynamically register extension methods using the ObjC runtime.
Swift SVN r4149
ObjC methods always need to be invoked through objc_msgSend, so they shouldn't have vtable slots, and Swift subclasses that override ObjC methods should always insert override slots into their vtables.
Swift SVN r3889
The test changes are that we're setting a class body on
some types that we weren't before. For some of these,
this is okay; for others, it's more questionable, but
ultimately not *harmful*.
Swift SVN r3746