> On Nov 7, 2017, at 8:58 PM, Joe Groff via swift-dev <swift-dev@swift.org> 
> wrote:
> 
> I’m trying to plan out changes to our type metadata record formats for ABI 
> stability. I’ll start by looking at the current situation and then make 
> suggestions about things we ought to change. We want to settle on a design 
> that leaves room for future expansion and runtime changes, and still allows 
> efficient access to the most frequently-accessed parts of metadata. I’ll be 
> looking exclusively at metadata records themselves for this message, leaving 
> other data structures for separate scrutiny. I'd appreciate all your feedback.
> 

Overall, I think this is a nice description of the problem.  A few comments:

  - One notable omission here is that you don't discuss nominal type 
descriptors at all.

  - For the structural types (tuples, functions, existentials, metatypes), I 
don't think there's any particular reason to abstract access to the component 
types.  If there are future changes to these types that require additional data 
to be stored, I don't see any reason that that couldn't be stored compatibly 
with the current layout.  We should make sure that all of these metadata have 
some space to encode flags and that reads of those flags are appropriately 
delimited, as opposed to e.g. assuming that an entire word is used to store a 
single enum.

  - I think having a single "value type" metadata kind for enums / structs 
makes sense, assuming we can discriminate them via the NTD.

  - I feel like we're not boxing ourselves in too much to assume a layout of 
the generic requirements.  Having a base offset already imposes a pretty steep 
compatibility requirement — e.g. even if we significantly generalized a type's 
generic signature, we would still need to store old requirements (when actually 
obeyed) in the appropriate places for the old signature, or else the old 
pattern just doesn't work at all.  As long as we can extend that with more 
information later, we don't really suffer from making layout assumptions today.

John.
> Tuple metadata records are accessed by calling the 
> swift_getTupleTypeMetadata* runtime functions.
> 
> The compiler expects access to the following fields:
> 
> Information   Projection strategy
> Element offsets       fixed offset
> If we wanted to be able to satisfy type metadata requirements for element 
> types from tuple metadata, we could also provide access to:
> 
> Information   Projection strategy
> Element types TBD
> Functions
> 
> Function metadata records are accessed by calling the 
> swift_get*FunctionTypeMetadata* runtime functions.
> 
> The compiler does not currently emit any projections into function type 
> metadata.
> 
> If we wanted to be able to satisfy type metadata requirements for input or 
> output types from function metadata, we could also provide access to:
> 
> Information   Projection strategy
> Return type   TBD
> Argument types        TBD
> Existentials, existential metatypes
> 
> Existential metadata records are accessed by calling the 
> swift_getExistentialTypeMetadata* runtime functions.
> 
> The compiler does not currently generate any code that reaches into 
> existential metadata records.
> 
> If we wanted to be able to satisfy type metadata requirements for input or 
> output types from function metadata, we could also provide access to:
> 
> Information   Projection strategy
> Generic signature     TBD
> Metatypes
> 
> Metatype metadata records are accessed by calling the 
> swift_getMetatypeMetadata function.
> 
> The compiler does not currently generate any code that reaches into metatype 
> metadata records.
> 
> If we wanted to be able to satisfy type metadata requirements for the 
> instance type from metatype metadata, we could also provide access to:
> 
> Information   Projection strategy
> Instance type TBD
> Objective-C wrappers
> 
> Class objects for natively-Objective-C classes are not Swift metadata by 
> themselves, so need a wrapper metadata record. This wrapper metadata is only 
> produced by the Swift runtime (and could be produced more efficiently by 
> future cooperation with the ObjC runtime). The compiler accesses Objective-C 
> class metadata by calling the swift_getObjCClassMetadata function, which may 
> return either a wrapper or pass through the input class object if it is 
> already valid metadata.
> 
> The compiler generates code against the following:
> 
> Information   Projection strategy
> Class object  runtime call swift_getObjCClassFromMetadata
> Core Foundation class
> 
> Foreign class metadata records are generated by Swift’s Clang importer for 
> imported Core Foundation class types. The records require runtime 
> canonicalization to determine which metadata record uniquely identifies the 
> type, since there is no home Swift module for the CF type. The compiler does 
> not currently generate code against any fields of the metadata.
> 
> Recommended changes
> 
> Abstract away fixed offsets across modules and for structural metadata
> 
> Anything we lock down fixed offsets for in the ABI should justify itself by 
> being necessary for performance or code size reasons. Unspecialized code 
> relies heavily on:
> 
> the value witness table
> stored property offsets
> generic arguments
> and these are the things that nominal type metadata currently makes directly 
> available, for the most part. Anything else we emit direct access to (such as 
> nominal type descriptors) should definitely be abstracted behind a runtime 
> call. For structural type metadata (tuples, functions, existentials, 
> metatypes), we already do so for most of the layout details, with the one 
> exception of tuple element offsets, which are exposed for performance of 
> unspecialized code.
> 
> For concrete nominal types, the compiler also currently generates metadata 
> records that are expected to be directly usable as metadata. This is a nice 
> code size optimization that’d be unfortunate to give up. At least for 
> internal or private types, the emitted metadata format and all of the code 
> that ought to be reaching into it are together in one resilience boundary, so 
> one could say that the precise metadata record format for internal value 
> types is a private contract of the compiler. However, even for public fragile 
> types, it would be beneficial still to be able to directly export the symbol 
> as usable metadata. For the performance-sensitive field offset and generic 
> argument vectors, we could nonetheless avoid hard-coding offsets in the 
> compiler. We could still guarantee that the generic arguments followed by 
> (fragile) stored property offsets are stored contiguously, and abstract the 
> base offset to the contiguous data structure. Possibilities for accessing the 
> base offset include:
> 
> Require a runtime call to get it
> Place the base offset somewhere else in the metadata
> Export the base offset as a separate symbol (possibly an absolute symbol, if 
> it’s knowable at compile time for the home module, or a global variable, if 
> it requires runtime computation).
> For classes with resilient ancestry, we already must have an approach that 
> allows the offset to be computed at instantiation time and efficiently 
> accessed in unspecialized code afterward. Technique (3) is proven by the 
> Objective-C runtime and should be sufficient for our needs. It would impose a 
> two- or three-instruction cost per type to load the base offset, which would 
> sit on the dependency chain for any generic type or field offset loads based 
> on that base offset, but would give us the flexibility to add new information 
> to metadata records in future compilers.
> 
> Make most metadata kinds private to the runtime
> 
> The compiler does not emit any code that looks at metadata kinds for 
> projection purposes. It does, however, use metadata kinds when it builds 
> metadata records for nominal types. However, the metadata kind is already 
> redundantly coded in the nominal type descriptor, so we could conceivably 
> reduce the exposure of metadata kinds to a single “value type” kind (in 
> addition to the “isa-pointer-in-the-kind-field-means-class” kind, imposed by 
> ObjC compatibility).
> 
> 
> -Joe
> _______________________________________________
> swift-dev mailing list
> swift-dev@swift.org
> https://lists.swift.org/mailman/listinfo/swift-dev

_______________________________________________
swift-dev mailing list
swift-dev@swift.org
https://lists.swift.org/mailman/listinfo/swift-dev

Reply via email to