Commit Graph

507 Commits

Author SHA1 Message Date
Saleem Abdulrasool
13d56a4f56 IRGen: force lazy metadata initialization for PE/COFF
The metadata reference to the pre-exsting VWT cannot be supported on PE/COFF
due to the direct reference to a value in an external module that is in
static data (the model requires indirecting through memory).  Always
force the lazy initialization for the metadata on such platforms.

This requires a secondary change - to initialize the VWT as well.  This
is ideally moved into the runtime where we can do this uniformly.
2018-11-15 11:05:47 -08:00
Slava Pestov
dbd116119e IRGen: Only mark field offset globals as constant if they won't be updated at runtime
Even if we have a constant value, we might be emitting a legacy layout
that can be updated in place by newer runtimes. In this case, clients
cannot assume the field offsets are constant, and the globals cannot
be constant either.

Part of <rdar://problem/17528739>.
2018-10-31 20:45:18 -04:00
Slava Pestov
4cecc268dc IRGen: Emit Objective-C metadata update callbacks 2018-10-26 16:54:23 -04:00
Slava Pestov
87ec607233 IRGen: Add a new 'Legacy' lowering mode that loads type info from a YAML file
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>.
2018-10-04 23:33:17 -04:00
Slava Pestov
d9d64db53f IRGen: We no longer deallocate partially-initialized foreign classes
This was an old workaround for a bug that should no longer
happen now that convenience initializers only have allocating
entry points.
2018-10-04 20:01:23 -04: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
a7f668c89c IRGen: Clean up class metadata emission 2018-09-23 21:26:46 -07:00
Slava Pestov
5e56e486b5 IRGen: Clean up ivar descriptor emission 2018-09-23 21:26:46 -07:00
Saleem Abdulrasool
d281b98220 litter the tree with llvm_unreachable
This silences the instances of the warning from Visual Studio about not all
codepaths returning a value.  This makes the output more readable and less
likely to lose useful warnings.  NFC.
2018-09-13 15:26:14 -07:00
Slava Pestov
719ba2fb27 IRGen: Fix case where we would go through the vtable entry and not the dispatch thunk
Make sure we check resilience of the class defining the method,
and not the class with the override we're calling.
2018-09-07 21:57:16 -07:00
Slava Pestov
3808ae0d58 IRGen: Use method lookup function for resilient super method calls
Fixes <https://bugs.swift.org/browse/SR-3928>, <rdar://problem/31411193>.
2018-09-07 21:57:16 -07:00
Slava Pestov
b3060d8836 IRGen: Emit dispatch thunks while emitting nominal type descriptor 2018-08-31 00:20:38 -06:00
Slava Pestov
98b5eafcca IRGen: Split up doesClassMetadataRequireDynamicInitialization() into two predicates
- doesClassMetadataRequireRelocation() -- returns true if we must
  allocate new metadata at runtime and fill it in, because the class
  has multiple instantiations (generic case) or because the total size
  of the metadata is not known at compile time (resilient ancestry).

- doesClassMetadataRequireInitialization() -- weaker condition than
  the above. It's true if the metadata must be relocated, but it is
  also true if the metadata has otherwise fixed size but must be
  filled in dynamically. This occurs if the class has generic
  ancestry but is itself not generic, or if the class has
  resiliently-sized fields, or missing members.

For now, we don't actually care about the distinciton anywhere,
because we cannot do in-place initialization of class metadata yet.
2018-08-20 14:24:19 -07:00
Jordan Rose
537954fb93 [AST] Rename several DeclContext methods to be clearer and shorter (#18798)
- getAsDeclOrDeclExtensionContext -> getAsDecl

This is basically the same as a dyn_cast, so it should use a 'getAs'
name like TypeBase does.

- getAsNominalTypeOrNominalTypeExtensionContext -> getSelfNominalTypeDecl
- getAsClassOrClassExtensionContext -> getSelfClassDecl
- getAsEnumOrEnumExtensionContext -> getSelfEnumDecl
- getAsStructOrStructExtensionContext -> getSelfStructDecl
- getAsProtocolOrProtocolExtensionContext -> getSelfProtocolDecl
- getAsTypeOrTypeExtensionContext -> getSelfTypeDecl (private)

These do /not/ return some form of 'this'; instead, they get the
extended types when 'this' is an extension. They started off life with
'is' names, which makes sense, but changed to this at some point.  The
names I went with match up with getSelfInterfaceType and
getSelfTypeInContext, even though strictly speaking they're closer to
what getDeclaredInterfaceType does. But it didn't seem right to claim
that an extension "declares" the ClassDecl here.

- getAsProtocolExtensionContext -> getExtendedProtocolDecl

Like the above, this didn't return the ExtensionDecl; it returned its
extended type.

This entire commit is a mechanical change: find-and-replace, followed
by manual reformatted but no code changes.
2018-08-17 14:05:24 -07:00
Jordan Rose
f505c8b8a0 [IRGen] Add some PrettyStackTraces for metadata emission (#18727) 2018-08-15 12:51:20 -07:00
Doug Gregor
b08a6f56b4 [AST] Drop resilience expansion from TypeBase::getReferenceCounting().
We’re not using this parameter, and don’t expect to do so in the future,
so remove it. Also fold away TypeBase::usesNativeReferenceCounting()
and irgen::getReferenceCountingForType(), both of which are trivial.
2018-08-14 09:10:49 -07:00
Slava Pestov
e44721dd19 IRGen: Remove the 'access type'/'layout type' distinction from StructLayout
This was part of the old resilience workaround for classes and
is no longer used.
2018-08-10 00:42:34 -07:00
Slava Pestov
b26d8ca6ed IRGen: For classes with resiliently-sized fields, calculate both a fragile and resilient layout
Use the fragile layout to emit static metadata, and use the
resilient metadata for almost everything else.

Add some tests to ensure that we use runtime metadata, even
for classes with fully fragile layout.
2018-08-10 00:42:34 -07:00
Slava Pestov
9f5505d95c IRGen: Don't make values constant in getAddrOfSimpleVariable()
We also use this for field offset globals, which are not always
constant. I think in practice everything was getting set
correctly, but it was hard to follow the logic.
2018-08-10 00:42:34 -07:00
Slava Pestov
90f01deba2 IRGen: Remove tryEmitClassConstantFragileInstance{Size,AlignMask}() 2018-08-10 00:42:34 -07:00
Slava Pestov
b26f3efced IRGen: Remove ClassTypeInfo::getHeapAlignment() 2018-08-10 00:42:34 -07:00
Slava Pestov
69be7d93b2 IRGen: Split up ClassLayoutBuilder::ClassMetadataRequiresDynamicInitialization into fine-grained conditions 2018-08-10 00:42:34 -07:00
Slava Pestov
f594d5bfbf IRGen: Split off ClassLayout implementation into its own file 2018-08-07 05:34:29 -07:00
Slava Pestov
fc91a58d82 IRGen: [ClassLayout] Better fix for SR-4687
We cannot use field offset globals if *any* field of a generic class
with Objective-C ancestry is dependent.

This is because the Swift runtime first performs layout starting
from a static instance start offset, and then asks the Objective-C
runtime to slide the offsets based on the dynamic superclass size.

So if the class has a field of generic type, the alignment of that
type can change the offsets of fields *before* it as well as after.

So we cannot assuem that any fields in such a class have the same
offset across instantiations at all.

The previous fix captured the intent of the above, but it only
kicked in if the immediate superclass of the class was imported
from Objective-C. But really we need to do this for any class with
Objective-C ancestry.

While fixing this, re-organize the code in ClassLayoutBuilder a
little bit to untangle the stored property iteration from the
interesting FieldAccess adjustments that take place after.
2018-08-07 04:26:43 -07:00
Slava Pestov
d460d5def6 IRGen: Remove ASTTy field from StructLayout 2018-08-07 04:26:43 -07:00
Slava Pestov
92f1ddc981 IRGen: [ClassLayout] Don't compute FieldAccess for superclass fields
Previously we would recursively get the abstract layout for the fully
generic class type for every superclass. But really we only need to do
that for fields of the class itself, not any superclass fields, since
we throw out the superclass field information anyway.
2018-08-07 04:26:43 -07:00
Slava Pestov
bdb5eb3289 IRGen: [ClassLayout] Don't build a separate StructLayout for classes
The type info for a class described its layout using a combination of a
StructLayout and ClassLayout, with different information stored in both.

Since we never use a class as a struct, it's simpler to add the relevant
bits to ClassLayout, and not build a StructLayout at all.

Also, drop inherited properties from the ClassLayout -- they're no
longer needed.
2018-08-07 00:37:03 -07:00
Slava Pestov
7315893d3d IRGen: [ClassLayout] Only look for fields of the immediate class
When emitting fixed class metadata, we emit field offsets for all fields,
including those from superclasses, if any.

Get the ClassLayout for the correct class before looking up a field that
might potentially belong to a superclass. Soon, I'm going to slim down
ClassLayout instances to only store the fields belonging to the class
itself, removing the InheritedStoredProperites array altogether.
2018-08-07 00:34:55 -07:00
Slava Pestov
a4f06c40fc IRGen: [ClassLayout] Don't recursively compute layout of the same type
Even if two types are different, they might still have the same
type info, so don't call getLayout() without checking the type info
for identity first. This allows simplifying an early exit into an
assertion elsewhere.
2018-08-06 23:22:16 -07:00
Doug Gregor
4d39506c4a [IRGen] Use a more precise computation for the kind of reference count.
TypeBase::usesNativeReferenceCounting() was doing a lot of work to
find the class that a type refers to, then determine whether it
would use the native reference-counting scheme. Its primary caller
in IRGen would use an overly-conservative approximation to decide
between the “Objective-C” and “unknown” cases, which resulted in
uses of “unknown” reference counting for some obviously-ObjC cases
(e.g., values of “NSObject”).

Moreover, the approximation would try to call into the type checker
(because it relied unnecessarily on the superclass *type* of a class
declaration), causing an assertion.

Fixes rdar://problem/42828798.
2018-08-06 17:04:47 -07:00
Slava Pestov
bee6b09a02 IRGen: Remove emitClassFragileInstanceSizeAndAlignMask() 2018-08-02 19:41:59 -07:00
Slava Pestov
9e15390216 IRGen: Don't visit superclass in classHasIncompleteLayout() and make it static 2018-08-02 19:41:59 -07:00
Slava Pestov
864d9cdf58 IRGen: Add a new ClassLayout::HasFixedSize and use it
Asking isFixedLayout() on the class's StructLayout does not take
missing members or Objective-C sliding into account. Adding a new
bit that carries this information allows removing the hack where
across modules the size of a class was always loaded from metadata.

In practice we hope most classes will be resilient, but its
better to centralize the checking for what resilience means instead
of using different rules in different places.
2018-08-02 19:41:59 -07:00
Slava Pestov
7c0ee05a2f IRGen: Don't unconditionally use field offset globals for cross-module class field access
While most class field accesses go through accessors, a special
case is if you have a final field (or class) in a non-resilient
module. Then, we were allowed to directly access the field.

However, an earlier hack made it so that this access always went
through a field offset global, which is unnecessary in the case
where the class layout is fully known.

One consequence of this is that 'Array.count' would compile down
to a load from a global followed by an indirect load, instead of
a single load from a constant offset.
2018-08-02 02:01:01 -07:00
Slava Pestov
13eb3489e4 IRGen: Remove unused __getInstanceSizeAndAlignMask() hack 2018-08-01 00:22:29 -07:00
Doug Gregor
d07fa5ab69 Switch many callers of ClassDecl::getSuperclass() to ClassDecl::getSuperclassDecl().
ClassDecl::getSuperclass() produces a complete interface type describing the
superclass of a class, including any generic arguments (for a generic type).
Most callers only need the referenced ClassDecl, which is (now) cheaper
to compute: switch those callers over to ClassDecl::getSuperclassDecl().

Fixes an existing test for SR-5993.
2018-07-31 10:14:44 -07:00
Doug Gregor
2860557a77 [Name lookup] Use the declaration-based lookupQualified() where it’s easy.
Switch a number of callers of the Type-based lookupQualified() over to
the newer (and preferred) declaration-based lookupQualified(). These are
the easy ones; NFC.
2018-07-31 10:14:44 -07:00
John McCall
7a4aeed570 Implement generalized accessors using yield-once coroutines.
For now, the accessors have been underscored as `_read` and `_modify`.
I'll prepare an evolution proposal for this feature which should allow
us to remove the underscores or, y'know, rename them to `purple` and
`lettuce`.

`_read` accessors do not make any effort yet to avoid copying the
value being yielded.  I'll work on it in follow-up patches.

Opaque accesses to properties and subscripts defined with `_modify`
accessors will use an inefficient `materializeForSet` pattern that
materializes the value to a temporary instead of accessing it in-place.
That will be fixed by migrating to `modify` over `materializeForSet`,
which is next up after the `read` optimizations.

SIL ownership verification doesn't pass yet for the test cases here
because of a general fault in SILGen where borrows can outlive their
borrowed value due to being cleaned up on the general cleanup stack
when the borrowed value is cleaned up on the formal-access stack.
Michael, Andy, and I discussed various ways to fix this, but it seems
clear to me that it's not in any way specific to coroutine accesses.

rdar://35399664
2018-07-23 18:59:58 -04:00
Doug Gregor
90771a0c0c [AST] Minor fixes to only set the isObjC bit when interop is enabled. 2018-06-28 22:20:15 -07:00
John McCall
9022b5152f Rename accessor kinds from IsGetter -> IsGet, etc.
Introduce some metaprogramming of accessors and generally prepare
for storing less-structured accessor lists.

NFC except for a change to the serialization format.
2018-06-14 17:08:55 -04:00
Slava Pestov
d3868ad23d IRGen: Perform completely fragile layout for all classes, not just @objc ancestry
Otherwise, Objective C categories don't work for classes with
resilient fields, such as the value types defined in the Foundation
overlay.

Fixes <rdar://problem/40819319>, <https://bugs.swift.org/browse/SR-7882>.
2018-06-13 23:26:02 -07:00
David Zarzycki
8c0c55539f [SIL] NFC: Rename misleading getSwiftRValueType() to getASTType()
Reference storage types are not RValues. Also, use more SILType helper
methods to avoid line wrap.
2018-05-04 08:14:38 -04:00
Slava Pestov
cfd5ac0798 Small fixes for fragile class layout
- Narrow the fix to classes with @objc ancestry only

- Pass -enable-class-resilience in class resilience executable test so that
  we exercise resilience there

- Only enable fragile layout if the class has @objc ancestry

- Add an IRGen test
2018-04-10 00:00:45 -07:00
Slava Pestov
86970b05dd IRGen: Fragile layout of resiliently-typed class fields
Fixes <rdar://problem/38506059>.
2018-04-09 21:53:59 -07:00
Slava Pestov
d5868e5492 IRGen: ElementLayout now stores two TypeInfos
This allows us to perform fragile layout of resilient fields without
completely disabling value type resilience.
2018-04-09 21:53:45 -07:00
Pavel Yaskevich
78822bc23e [IRGen] Adjust element size of offset vector to 32-bit for structs
Type of elements contained by field offsets vector can be adjusted
to 32-bit integers (from being pointer sized) to safe space in the
binary since segment size is limited to 4 GB.

Resolves: rdar://problem/36560486
2018-04-03 13:32:06 -07:00
Sho Ikeda
08644c1d8f [gardening][IRGen] Replace typedef with using 2018-03-27 09:06:33 +09:00
John McCall
2de86ea086 Compute the ISA encoding correctly for Class-bounded archetypes.
rdar://24219110
2018-03-26 18:29:25 -04: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
Slava Pestov
b1f4430410 Runtime: Rename swift_initClassMetadata_UniversalStrategy()
Rename it to swift_initClassMetadata() just like we recently did
swift_initStructMetadata(), and add a StructLayoutFlags parameter
so we can version calls to this function in the future.

Maybe at some point this will become a separate ClassLayoutFlags
type, but at this point it doesn't matter because IRGen always
passes a value of 0.
2018-03-23 18:59:07 -06:00