Commit Graph

53 Commits

Author SHA1 Message Date
David Farler
14192bfa99 [IRGen] Use hidden visibility for __swift_reflection_version constant
This prevents it from having weak external linkage.

rdar://problem/27367632
2016-07-15 00:30:12 -07:00
David Farler
fd46a60785 IRGen: Emit reflection metadata version into Swift binaries
Emit a 16-bit constant that tracks the version of the reflection
metadata emitted into binaries. This can be used to cross-check
what is supported by the SwiftRemoteMirror library with the new
version API.

rdar://problem/27251582
2016-07-08 17:21:25 -07:00
Slava Pestov
95bc009e3e Reflection: Multi-payload enum layout
The approach here is to split this into two cases:

- If all case payloads have a fixed size, spare bits may be
  potentially used to differentiate between cases, and the
  remote reflection library does not have enough information to
  compute the layout itself.

  However, the total size must be fixed, so IRGen just emits a
  builtin type descriptor (which I need to rename to 'fixed type
  descriptor' since these are also used for imported value types,
  and now, certain enums).

- If at least one case has a size that depends on a generic
  parameter or is a resilient type, IRGen does not know the size,
  but this means fancy tricks with spare bits cannot be used either.
  The remote reflection library uses the same approach as the
  runtime, basically taking the maximum of the payload size and
  alignment, and adding a tag byte.

As with single-payload enums, we produce a new kind of
RecordTypeInfo, this time with a field for every enum case.
All cases start at offset zero (but of course this might change,
if for example we put the enum tag before the address point).

Also, just as with single-payload enums, there is no remote
'project case index' operation on ReflectionContext yet.

So the the main benefit from this change is that we don't entirely
give up when doing layout of class instances containing enums;
however, tools still cannot look inside the enum values themselves,
except in the simplest cases involving optionals.

Notably, the remote reflection library finally understands all
of the standard library's collection types -- Array, Character,
Dictionary, Set, and String.
2016-07-01 01:31:25 -07:00
John McCall
266fa150db Bring PolymorphicConvention back into GenProto.cpp and expose
just the targeted operation that GenReflection actually needs.

NFC.
2016-06-30 18:34:00 -07:00
Slava Pestov
48c928938a Reflection: Single-payload enum layout
Attempt to lay out single-payload enums, using knowledge of extra
inhabitants where possible.

- The extra inhabitants of an aggregate are the extra inhabitants of
  the first field. If the first field is empty, there are no extra
  inhabitants, and subsequent fields do not affect anything.

- Function pointers and metatypes have different extra inhabitants
  than Builtin.RawPointer, so have IRGen emit distinct builtin type
  descriptors for those.

- Opaque existentials do not have extra inhabitants.

- Weak references do not have extra inhabitants.

Also, fix IRGen to emit more accurate enum reflection metadata in
these two cases:

- We now record whether enum cases are indirect or not. An indirect
  case is the same as a payload case with Builtin.NativeObject.

- We now record whether a case is empty or not using the same logic
  as the rest of IRGen. Previously, we would incorrectly emit a
  payload type for a case with a payload that is an empty struct,
  for example.

At this point we don't have a way to get the currently inhabited
enum case from a value. However, this is still an improvement because
we can still reflect other fields of aggregates containing enums,
instead of just giving up.

Finally make some methods on TypeCoverter private, and use 'friend'
to allow them to be accessed from other internal classes, making the
public API simpler.
2016-06-30 12:57:14 -06:00
practicalswift
f7deb79dcb [gardening] Remove addObjCClassRecord()
The last in-repo usage was removed in 97fd1a7411
2016-06-07 19:38:57 +02:00
Saleem Abdulrasool
83b2b5994a IRGen: support reflection for swift 3 on COFF
COFF has restrictions on portable section length (8 characters).  Use a FourCC
identifier for the section on COFF.  Take the opportunity to replace a
std::string parameter with a StringRef.
2016-06-02 23:23:42 -07:00
Slava Pestov
60dff01093 Reflection: Simplify associated type metadata emission
Instead of hooking into nominal type and extension emission
and walking all conformances of those declarations, let's
just directly hook into the logic for emitting conformances.

This fixes an issue where we would apparently emit duplicate
conformances, as well as unnecessary conformances that are
defined elsewhere.
2016-05-26 19:33:00 -07:00
Slava Pestov
7a46b0f23f Reflection: Emit descriptors for referenced imported protocols
When we encounter a protocol typeref, we have to know if its @objc,
class-bound, or opaque, so make sure we provide the necessary
information when imported protocols are referenced.
2016-05-26 19:33:00 -07:00
Slava Pestov
97fd1a7411 Reflection: Emit field metadata for @objc classes
While we can skip emitting metadata for imported classes (clients
should ask the Objective-C runtime instead) it was not correct to
do so for Swift-defined classes that used Objective-C reference
counting.
2016-05-26 19:32:59 -07:00
Slava Pestov
e2cf23d971 Reflection: Don't emit builtin descriptors for imported classes
Previously we would emit both a builtin descriptor and field
descriptor for imported classes, but we only need the latter.

Untangle some code and fix a crash with imported Objective-C
generics in the process.

Fixes <rdar://problem/26498484>.
2016-05-26 19:32:59 -07:00
Slava Pestov
72e308679c Reflection: Record builtin and imported types referenced from captures 2016-05-26 19:32:58 -07:00
Slava Pestov
a86e39dd4c Reflection: Don't emit associated type records for conformances without associated types
This saves a bit of space. We don't care about conformances per se
in remote reflection, only what the associated types are.
2016-05-26 19:32:57 -07:00
Slava Pestov
803a6b095b Reflection: Emit metadata for fixed-layout SIL boxes
We were recovering metadata from generic boxes by reading
the instantiated payload metadata from the box's metadata,
but this approach doesn't work for fixed-size boxes, whose
metadata does not store the payload metadata at all.

Instead, emit a capture descriptor with no metadata sources
and a single capture, using the lowered AST type appearing
in the alloc_box instruction that emitted the box.

Since box metadata is shared by all POD types of the same
size, and all single-retainable pointer payloads, the
AST type might not accurately reflect what is actually in
the box.

However, this type is *layout compatible* with the box
payload, at least enough to know where the retainable
pointers are, because after all IRGen uses this type to
synthesize the destructor.

Fixes <rdar://problem/26314060>.
2016-05-26 19:32:57 -07:00
David Farler
aa86d1dd07 SwiftRemoteMirror: Fix crash emitting capture descriptors involving implicit self
When emitting capture descriptors for functions with a smaller number of parameters
than SIL parameters, the compiler can crash indexing into the heap layout's element
types, because the capture index underflows to UINT_MAX.

rdar://problem/26404583
2016-05-20 20:53:10 -07:00
David Farler
83c17d29b7 Remove -enable-refleciton-builtins flag, now unnecessary
We can always potentially emit 'builtin' reflection metadata, since
that now includes imported types referenced by the module.

rdar://problem/26259668
2016-05-12 20:49:35 -07:00
David Farler
fe2872fae1 SwiftRemoteMirror: Lower types with imported / Objective-C types
- Lower Objective-C class typerefs as strong references with unknown
reference counting.
- Lower other imported C types as builtin blobs of their known
size, alignment, etc.

In the future, it might be beneficial to track which stored properties
of imported types are pointers, for better conservative scanning of
outgoing pointers to the heap.

rdar://problem/26240258
rdar://problem/26240394
2016-05-12 20:49:32 -07:00
Slava Pestov
c056b25f44 IRGen: Fix capture descriptor emission 2016-05-09 13:40:58 -07:00
Slava Pestov
d6c04816d6 Reflection: We need to distinguish metatype from reference sources
Getting metadata from a metatype source just means loading from an offset;
with a reference source we have to dereference the isa pointer first.

Thanks to @bitjammer for pointing out this was broken.
2016-05-05 14:58:33 -07:00
Slava Pestov
bb8d1d3416 IRGen: Fixes for capture descriptor emission
- Fix caller/callee confusion, and use the right SIL function type
  for obtaining the generic signature.
- Correctly interpret the NecessaryBindings structure and the
  substitutions therein.
- Fix alignment for capture and builtin type descriptors
- Put capture descriptor typerefs in the correct section

Add new SIL-level tests to precisely trigger various scenarios.
2016-05-05 13:47:54 -07:00
Slava Pestov
c22ac4d0e3 IRGen: Didn't mean to remove this part 2016-04-30 15:38:30 -07:00
Slava Pestov
96218acf66 IRGen: Only emit capture descriptors if -enable-reflection-metadata frontend flag is passed in
Also, simplify the IRGen/reflection_metadata.swift test a bit; there's no
reason to split it up into two files.
2016-04-30 15:36:00 -07:00
David Farler
a1ff1e6a7b Eagerly emit reflection metadata as decls are emitted
Rather than collection nominal type and extension decls and emit
reflection metadata records in one go, we can emit them as they
are encountered and instead collection builtin types referenced
by those at the end.
2016-04-29 17:07:55 -07:00
Slava Pestov
be870fdec4 IRGen: Emit capture descriptors in their own section
Now that reflection metadata is in TEXT, we can have relative references
to capture descriptors from closure context metadata.
2016-04-29 16:00:09 -07:00
Slava Pestov
51ae5a89a3 Reflection: Place reflection metadata in TEXT segment 2016-04-29 15:47:27 -07:00
David Farler
5594fc5339 Collect builtins referenced by captures
If there are any builtin types referenced by closure captures
[in the standard library], make sure to collect them so we emit
reflection metadata for them in the builtin section.
2016-04-29 14:28:32 -07:00
John McCall
6c92c324f6 Rename IRGenModuleDispatcher to just IRGenerator and transfer
ownership of some of the basic structures to it.
2016-04-27 09:42:03 -07:00
Slava Pestov
00e0c89b30 IRGen: Emit reflection info for protocols
For now, just enough for lowering.

Perhaps we should have a way to always just get this information
from metadata instead, since protocol metadata is always static
and not instantiated.

This would require the static "object file" interface used by
swift-reflection-dump to take a callback for symbol lookup.
2016-04-25 20:08:48 -07:00
David Farler
b6985b5cfe Build fix: React to API changes in ReflectionMetadataBuilder
NFC.
2016-04-23 00:08:28 -07:00
David Farler
f24f445997 Merge pull request #2274 from apple/closure-metadata
Start emitting capture descriptors for closure metadata
2016-04-22 23:43:00 -07:00
Slava Pestov
0d34bc21ef IRGen: Emit reflection metadata for certain builtin types when -enable-reflection-builtins flag is passed in
These types are not directly referenced as fields of aggregate types,
but are needed for reflection type lowering.

Also, use a SetVector to collect referenced builtin types, instead of
a SmallPtrSet, to ensure compiler output is deterministic.
2016-04-22 22:36:05 -07:00
David Farler
c360ba85b7 Emit typerefs and metadata source strings as relative offsets to globals
MCJIT doesn't like offset relocations into the data sections, so the
capture descriptors and their typerefs/metadata source encoded strings
will need to be emitted as globals and not go into the reflection data
sections.
2016-04-22 19:09:06 -07:00
David Farler
c05e48b116 Add CaptureDescriptor struct definition
For convenience when reading looking at heap closure metadata.

Also move the capture typerefs above the metadata sources, since
they're more likely to be accessed than generic metadata sources.
2016-04-22 19:09:06 -07:00
David Farler
6a51ae84b2 Add Self- and SelfWitnessTable metadata sources to capture descriptors
These can show up in partial applications of functions with the
witness_method calling convention.
2016-04-22 19:09:06 -07:00
David Farler
09d0cfee8d Hang closure capture descriptors from their heap metadata
Now we can discern the types of values in heap boxes at runtime!
Closure reference captures are a common way of creating reference
cycles, so this provides some basic infrastructure for detecting those
someday.

A closure capture descriptor has the following:

- The number of captures.
- The number of sources of metadata reachable from the closure.
  This is important for substituting generics at runtime since we
  can't know precisely what will get captured until we observe a
  closure.
- The number of types in the NecessaryBindings structure.
  This is a holding tank in a closure for sources of metadata that
  can't be gotten from the captured values themselves.
- The metadata source map, a list of pairs, for each
  source of metadata for every generic argument needed to perform
  substitution at runtime.
  Key: The typeref for the generic parameter visible from the closure
  in the Swift source.
  Value: The metadata source, which describes how to crawl the heap from
  the closure to get to the metadata for that generic argument.
- A list of typerefs for the captured values themselves.

Follow-up: IRGen tests for various capture scenarios, which will include
MetadataSource encoding tests.

rdar://problem/24989531
2016-04-22 19:09:06 -07:00
Slava Pestov
98abbdb332 Emit reflection metadata, but not reflection names, by default
This allows the reflection type lowering test to pass with the
default build configuration.
2016-04-21 15:15:30 -07:00
Slava Pestov
c76b1f1cec Reflection: Record the nominal type kind in the field descriptor
Tested by upcoming type lowering patch, for now NFC.
2016-04-18 21:17:41 -07:00
David Farler
ff67f7f6af [GenReflection] Emit associated type reflection metadata via extensions
Don't leave behind conformances gotten through extensions when
emitting associated type reflection metadata.
2016-04-15 17:48:27 -07:00
Slava Pestov
824bd7544d IRGen: Emit typerefs for all builtin types referenced from reflection metadata sections
In order to perform layout, the remote mirrors library needs to know
about the size, alignment and extra inhabitants of builtin types.

Ideally we would emit a reflection info section in libswiftRuntime.o,
but in the meantime just duplicate builtin type metadata for all
builtin types referenced from the current module instead.

In practice only the stdlib and a handful of overlays like the SIMD
overlay use builtin types, and only a few at a time.

Tested manually by running swift-reflection-tool on the standard
library -- I'll add automated tests by using -parse-stdlib to
reference Builtin types in a subsequent patch that adds more layout
logic.

NFC if -enable-reflection-metadata is off.
2016-04-15 00:12:11 -07:00
Slava Pestov
f236383865 Reflection: Fix metadata for empty cases
Also change std::endl to '\n' in the dumper, since std::endl flushes
the output stream.
2016-04-14 23:44:45 -07:00
Slava Pestov
25f7632f37 IRGen: Record enum payload type, not the constructor type
If we have a 'case Foo(T)' inside 'enum E', we only want to keep
'T' around, not 'E.Type -> T -> E'.
2016-04-14 17:02:41 -07:00
Slava Pestov
55b2b3f278 IRGen: Use 4 byte alignment for reflection metadata section
Otherwise, we will insert padding if the field metadata section size
is not a multiple of the word size, which will cause a crash when
we later try to read it.
2016-04-14 15:31:14 -07:00
David Farler
7e8b8f83e8 Emit reflection metadata by default
This turns on the remote reflection metadata by default for swift
invocations and the standard library. The size delta for all of the
sections is:

Section __swift3_typeref: 20176
Section __swift3_reflstr: 2556
Section __swift3_fieldmd: 8172
Section __swift3_assocty: 18112

Recognizing that this is a nontrivial increase in binary size, we can
reduce this with a few methods:

- Trie for strings (typerefs and field names are both strings) but would
  need an implementation
- Compress the entire sections: this would need an implementation
  available on all platforms where we support the functionality.
- Don't use the AST mangler but a custom mangling, which may be slightly
  more compact because it can specialize by need and maybe not include
  some mangle nodes that typerefs don't need.
2016-03-18 17:50:32 -07:00
David Farler
be34129c43 Include protocols in DependentMemberTypeRef
This is necessary for proper uniquing when looking up associated
types.
2016-03-17 19:02:01 -07:00
David Farler
4fc146a14a [GenReflection] Use declared type for associated type record keys
Similiar to the change to field reflection metadata, don't use the
interface for the key of associated type lookup, because the nominal
type descriptors don't include generics in their mangled name strings.
2016-03-07 17:43:13 -08:00
David Farler
b8345e2ffd [GenReflection] Use pretty stack trace when emitting metadata 2016-03-07 17:43:13 -08:00
David Farler
96386b03be Don't use interface type as field descriptor key
Nominal type descriptors use declared types for their mangled names,
so we need to use them when scanning the fieldmd section for a
matching record. This is fine because the descriptor can tell us
about the type's generics. Individual field records continue to use
the interface type.
2016-03-07 17:43:12 -08:00
David Farler
cd6d05e23f Move paltry linker section name length assert into Mach-O case
This is where it really matters - the section name has to be 16
characters or less.
2016-03-07 17:43:12 -08:00
David Farler
161a56ce8f Remove unnecessary if auto check - NFC 2016-03-07 17:43:12 -08:00
David Farler
744806a742 [Reflection] Add Foreign, ObjC, and Opaque type references
These likely don't have Swift type metadata but might be useful to
record or instantiate based on what kind of metadata is encountered for
the sake of memory tools.
2016-03-02 21:25:04 -08:00