Unfortunately, declarations cannot be marked with their COMDAT groups.
This fixes multithreaded IRGen where we would emit declarations for the
global initializers with COMDATs causing the IR Verifier to object. The
existing test cases cover this scenario.
Protocol descriptors for resilient protocols relatively-reference
default witness thunks, so when using -num-threads N with N > 1,
we must ensure the default witness thunk is emitted in the same
LLVM module.
We were wastefully emitting an accessor if a field had a type, for
example if my field type was (() -> (X, Array<Y>>) we would force
the emission of a function to construct (() -> (X, Array<Y>)) even
though all we care about is the type metadata for X and Y.
Conversely, we would skip the field type if it contained an
archetype, even if it otherwise contained metadata that we need
to force to emit, for instance something like (T, X) where T is
a generic parameter and X is a nominal type.
A final side effect is we no longer try to emit type metadata for
one-element tuples when emitting enum payload metadata, which is
something I want to assert against.
Enable COMDATing in `createFunction`. This is particularly important
for the emission of the GetEnumTagSinglePayload. The function emission
is marked as linkonce ODR but does not get COMDAT'ed currently, breaking
emission on PE/COFF targets like Windows.
We visited them twice, which led to registering them twice. Add a test
for this feature so that we don't regress on this or on the use of
non-extended types in the future (see previous commits).
These are only used in two places in the Apple Objective-C runtime:
- A protocol's "extended method types" list
- Block type descriptors
We were using them when dynamically registering a protocol with the
Objective-C runtime, but that's just expecting "normal" types; the
"extended method types" list is never present in such a protocol.
Objective-C class references (which show up in the __objc_classrefs
section) are always coalesced by the linker. When we relatively
address them (which occurs in protocol conformance records), the
linker may compute the relative offset *before* coalescing, leading to
an incorrect result. The net effect is a protocol conformance record
that applies to the wrong Objective-C class, causing all sorts of
runtime mayhem.
Switch relatively-addressed Objective-C classes over to using the
Objective-C runtime name of the class. It's a less efficient encoding
(since we need to go through objc_lookUpClass), but it avoids the
linker bug.
Fixes rdar://problem/46428085 by working around the linker bug.
Otherwise with the new resilient witness table emission pattern, we might miss
conformances for refined protocols, since the witness table itself is never
referenced, only the conformance descriptor is.
Fixes <rdar://problem/46133018>.
Group the section for the replacements on PE/COFF. The group is needed
to ensure that we are able to order the marker for the start and stop
properly. Without the grouping there is no way to guarantee the
ordering.
When a (file)private entity occurs inside a generic context, we still need
information about the genericity of the enclosing context to demangle
to metadata. Emit complete context descriptors for parents of anonymous
contexts.
Fixes rdar://problem/46109026.
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.
We were emitting relative references to entities that might be in
another translation unit. Use a GOT entry or thunk where appropriate.
Fixes <rdar://problem/45901706>.
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).
A dynamically replaceable function calls through a global variable that
holds the function pointer.
struct ChainEntry {
void *(funPtr)();
struct ChainEntry *next;
}
ChainEntry dynamicallyReplaceableVar;
void dynamicallyReplaceableFunction() {
dynamicallyReplaceableVar.funPtr()
}
dynamic replacements will be chainable so the global variable also
functions as the root entry in the chain of replacements.
A dynamic replacement functions can call the previous implementation by
going through its chain entry.
ChainEntry chainEntryOf_dynamic_replacement_for_foo;
void dynamic_replacement_for_foo() {
// call the previous (original) implementation.
chainEntryOf_dynamic_replacement_for_foo.funPtr();
}
Use relative references instead of pointers so that the pattern can be true-const. Instead of trying
to instantiate a constant key path literal in-place, point to a cache variable that we can store
a pointer to the shared instance into when instantiated. Now that the pattern format has diverged
significantly from the instance format, simplify and refactor the instantiation code using a walker
for the pattern format instead of trying to reuse the code for working with instantiated instances.
rdar://problem/42674576
In order to handle LinkOnceODR semantics correctly across various object
formats, introduce a new helper ApplyIRLinkage. This abstracts the need
to create a COMDAT group and set it on the GlobalValue. Adjust all
sites where we set the IR linkage attributes to use this mechanism
instead to avoid having to track down symbols not being added to a
COMDAT group.
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.
Extending the mangling of symbolic references to also include indirect
symbolic references. This allows mangled names to refer to context
descriptors (both type and protocol) not in the current source file.
For now, only permit indirect symbolic references within the current module,
because remote mirrors (among other things) is unable to handle relocations.
Co-authored-by: Joe Groff <jgroff@apple.com>
Simplify calls to getAddrOfLLVMVariableOrGOTEquivalent() and
getAddrOfLLVMVariable() by moving the computation of the alignment and
default type into LinkEntity.
Co-authored-by: Joe Groff <jgroff@apple.com>
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.
The instantiation of an Objective-C class or definition of an Objective-C
category can depend (at runtime) on Swift metadata, which is triggered
(only) by mangled name round-trip verification. Teach the JIT to call
the registration functions for Objective-C classes and categories
after we’ve called all of the metadata registration functions.
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.
The YAML format is the same one produced by the -dump-type-info
frontend mode.
For now this is only enabled if the -read-type-info-path frontend
flag is specified.
Progress on <rdar://problem/17528739>.
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.