<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><br class=""><div><blockquote type="cite" class=""><div class="">On Nov 7, 2017, at 8:58 PM, Joe Groff via swift-dev <<a href="mailto:swift-dev@swift.org" class="">swift-dev@swift.org</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><meta http-equiv="Content-Type" content="text/html; charset=utf-8" class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class=""><p style="color: rgb(17, 17, 17); font-family: "Helvetica Neue", Helvetica, Arial, Verdana, sans-serif; word-wrap: break-word; margin: 1.3125em 0px; font-size: 1.1429em; line-height: 1.3125em;" class="">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.</p></div></div></blockquote><div><br class=""></div></div><div>Overall, I think this is a nice description of the problem. A few comments:</div><div><br class=""></div><div> - One notable omission here is that you don't discuss nominal type descriptors at all.</div><div><br class=""></div><div> - 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.</div><div><br class=""></div><div> - I think having a single "value type" metadata kind for enums / structs makes sense, assuming we can discriminate them via the NTD.</div><div><br class=""></div><div> - 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.</div><div><br class=""></div><div>John.</div><div><blockquote type="cite" class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class=""><p style="color: rgb(17, 17, 17); font-family: "Helvetica Neue", Helvetica, Arial, Verdana, sans-serif; word-wrap: break-word; margin: 1.3125em 0px; font-size: 1.1429em; line-height: 1.3125em;" class="">Tuple metadata records are accessed by calling the <code style="line-height: 1;" class="">swift_getTupleTypeMetadata*</code> runtime functions.</p><p style="color: rgb(17, 17, 17); font-family: "Helvetica Neue", Helvetica, Arial, Verdana, sans-serif; word-wrap: break-word; margin: 1.3125em 0px; font-size: 1.1429em; line-height: 1.3125em;" class="">The compiler expects access to the following fields:</p><table style="margin: -1px 0px 1.3125em; border-spacing: 0px; border: 1px solid rgba(0, 0, 0, 0.247059); border-collapse: collapse; empty-cells: hide; padding: 0px; table-layout: fixed; color: rgb(17, 17, 17); font-family: "Helvetica Neue", Helvetica, Arial, Verdana, sans-serif; font-size: 15px;" class=""><colgroup style="border-spacing: 0px;" class=""><col style="border-spacing: 0px;" class=""><col style="border-spacing: 0px;" class=""></colgroup><thead style="border-spacing: 0px; background-color: rgba(0, 0, 0, 0.14902); border-width: 1px; border-style: solid; border-color: rgba(0, 0, 0, 0.14902) rgba(0, 0, 0, 0.14902) rgba(0, 0, 0, 0.2);" class=""><tr style="border-spacing: 0px; background-color: rgba(255, 255, 255, 0.0588235);" class=""><th style="border-spacing: 0px; font-size: 1.1em; line-height: 1.3; padding: 0.5em 1em 0px;" class="">Information</th><th style="border-spacing: 0px; font-size: 1.1em; line-height: 1.3; padding: 0.5em 1em 0px;" class="">Projection strategy</th></tr></thead><tbody style="border-spacing: 0px; background-color: rgba(0, 0, 0, 0.0470588);" class=""><tr style="border-spacing: 0px; background-color: rgba(255, 255, 255, 0.0588235);" class=""><td style="word-wrap: break-word; border-spacing: 0px; font-size: 1.1em; line-height: 1.3; padding: 0.5em 1em 0px;" class="">Element offsets</td><td style="word-wrap: break-word; border-spacing: 0px; font-size: 1.1em; line-height: 1.3; padding: 0.5em 1em 0px; background-color: rgba(200, 200, 200, 0.247059);" class="">fixed offset</td></tr></tbody></table><p style="color: rgb(17, 17, 17); font-family: "Helvetica Neue", Helvetica, Arial, Verdana, sans-serif; word-wrap: break-word; margin: 1.3125em 0px; font-size: 1.1429em; line-height: 1.3125em;" class="">If we wanted to be able to satisfy type metadata requirements for element types from tuple metadata, we could also provide access to:</p><table style="margin: -1px 0px 1.3125em; border-spacing: 0px; border: 1px solid rgba(0, 0, 0, 0.247059); border-collapse: collapse; empty-cells: hide; padding: 0px; table-layout: fixed; color: rgb(17, 17, 17); font-family: "Helvetica Neue", Helvetica, Arial, Verdana, sans-serif; font-size: 15px;" class=""><colgroup style="border-spacing: 0px;" class=""><col style="border-spacing: 0px;" class=""><col style="border-spacing: 0px;" class=""></colgroup><thead style="border-spacing: 0px; background-color: rgba(0, 0, 0, 0.14902); border-width: 1px; border-style: solid; border-color: rgba(0, 0, 0, 0.14902) rgba(0, 0, 0, 0.14902) rgba(0, 0, 0, 0.2);" class=""><tr style="border-spacing: 0px; background-color: rgba(255, 255, 255, 0.0588235);" class=""><th style="border-spacing: 0px; font-size: 1.1em; line-height: 1.3; padding: 0.5em 1em 0px;" class="">Information</th><th style="border-spacing: 0px; font-size: 1.1em; line-height: 1.3; padding: 0.5em 1em 0px;" class="">Projection strategy</th></tr></thead><tbody style="border-spacing: 0px; background-color: rgba(0, 0, 0, 0.0470588);" class=""><tr style="border-spacing: 0px; background-color: rgba(255, 255, 255, 0.0588235);" class=""><td style="word-wrap: break-word; border-spacing: 0px; font-size: 1.1em; line-height: 1.3; padding: 0.5em 1em 0px;" class="">Element types</td><td style="word-wrap: break-word; border-spacing: 0px; font-size: 1.1em; line-height: 1.3; padding: 0.5em 1em 0px; background-color: rgba(200, 200, 200, 0.247059);" class="">TBD</td></tr></tbody></table><h3 id="functions" style="color: rgb(17, 17, 17); margin: 21px 0px; font-size: 20px; line-height: 21px; font-family: "Helvetica Neue", Helvetica, Arial, Verdana, sans-serif;" class="">Functions</h3><p style="color: rgb(17, 17, 17); font-family: "Helvetica Neue", Helvetica, Arial, Verdana, sans-serif; word-wrap: break-word; margin: 1.3125em 0px; font-size: 1.1429em; line-height: 1.3125em;" class="">Function metadata records are accessed by calling the <code style="line-height: 1;" class="">swift_get*FunctionTypeMetadata*</code> runtime functions.</p><p style="color: rgb(17, 17, 17); font-family: "Helvetica Neue", Helvetica, Arial, Verdana, sans-serif; word-wrap: break-word; margin: 1.3125em 0px; font-size: 1.1429em; line-height: 1.3125em;" class="">The compiler does not currently emit any projections into function type metadata.</p><p style="color: rgb(17, 17, 17); font-family: "Helvetica Neue", Helvetica, Arial, Verdana, sans-serif; word-wrap: break-word; margin: 1.3125em 0px; font-size: 1.1429em; line-height: 1.3125em;" class="">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:</p><table style="margin: -1px 0px 1.3125em; border-spacing: 0px; border: 1px solid rgba(0, 0, 0, 0.247059); border-collapse: collapse; empty-cells: hide; padding: 0px; table-layout: fixed; color: rgb(17, 17, 17); font-family: "Helvetica Neue", Helvetica, Arial, Verdana, sans-serif; font-size: 15px;" class=""><colgroup style="border-spacing: 0px;" class=""><col style="border-spacing: 0px;" class=""><col style="border-spacing: 0px;" class=""></colgroup><thead style="border-spacing: 0px; background-color: rgba(0, 0, 0, 0.14902); border-width: 1px; border-style: solid; border-color: rgba(0, 0, 0, 0.14902) rgba(0, 0, 0, 0.14902) rgba(0, 0, 0, 0.2);" class=""><tr style="border-spacing: 0px; background-color: rgba(255, 255, 255, 0.0588235);" class=""><th style="border-spacing: 0px; font-size: 1.1em; line-height: 1.3; padding: 0.5em 1em 0px;" class="">Information</th><th style="border-spacing: 0px; font-size: 1.1em; line-height: 1.3; padding: 0.5em 1em 0px;" class="">Projection strategy</th></tr></thead><tbody style="border-spacing: 0px; background-color: rgba(0, 0, 0, 0.0470588);" class=""><tr style="border-spacing: 0px; background-color: rgba(255, 255, 255, 0.0588235);" class=""><td style="word-wrap: break-word; border-spacing: 0px; font-size: 1.1em; line-height: 1.3; padding: 0.5em 1em 0px;" class="">Return type</td><td style="word-wrap: break-word; border-spacing: 0px; font-size: 1.1em; line-height: 1.3; padding: 0.5em 1em 0px; background-color: rgba(200, 200, 200, 0.247059);" class="">TBD</td></tr><tr style="border-spacing: 0px; background-color: rgba(200, 200, 200, 0.247059);" class=""><td style="word-wrap: break-word; border-spacing: 0px; font-size: 1.1em; line-height: 1.3; padding: 0.5em 1em 0px; background-color: rgba(255, 255, 255, 0.0588235);" class="">Argument types</td><td style="word-wrap: break-word; border-spacing: 0px; font-size: 1.1em; line-height: 1.3; padding: 0.5em 1em 0px;" class="">TBD</td></tr></tbody></table><h3 id="existentialsexistentialmetatypes" style="color: rgb(17, 17, 17); margin: 21px 0px; font-size: 20px; line-height: 21px; font-family: "Helvetica Neue", Helvetica, Arial, Verdana, sans-serif;" class="">Existentials, existential metatypes</h3><p style="color: rgb(17, 17, 17); font-family: "Helvetica Neue", Helvetica, Arial, Verdana, sans-serif; word-wrap: break-word; margin: 1.3125em 0px; font-size: 1.1429em; line-height: 1.3125em;" class="">Existential metadata records are accessed by calling the <code style="line-height: 1;" class="">swift_getExistentialTypeMetadata*</code> runtime functions.</p><p style="color: rgb(17, 17, 17); font-family: "Helvetica Neue", Helvetica, Arial, Verdana, sans-serif; word-wrap: break-word; margin: 1.3125em 0px; font-size: 1.1429em; line-height: 1.3125em;" class="">The compiler does not currently generate any code that reaches into existential metadata records.</p><p style="color: rgb(17, 17, 17); font-family: "Helvetica Neue", Helvetica, Arial, Verdana, sans-serif; word-wrap: break-word; margin: 1.3125em 0px; font-size: 1.1429em; line-height: 1.3125em;" class="">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:</p><table style="margin: -1px 0px 1.3125em; border-spacing: 0px; border: 1px solid rgba(0, 0, 0, 0.247059); border-collapse: collapse; empty-cells: hide; padding: 0px; table-layout: fixed; color: rgb(17, 17, 17); font-family: "Helvetica Neue", Helvetica, Arial, Verdana, sans-serif; font-size: 15px;" class=""><colgroup style="border-spacing: 0px;" class=""><col style="border-spacing: 0px;" class=""><col style="border-spacing: 0px;" class=""></colgroup><thead style="border-spacing: 0px; background-color: rgba(0, 0, 0, 0.14902); border-width: 1px; border-style: solid; border-color: rgba(0, 0, 0, 0.14902) rgba(0, 0, 0, 0.14902) rgba(0, 0, 0, 0.2);" class=""><tr style="border-spacing: 0px; background-color: rgba(255, 255, 255, 0.0588235);" class=""><th style="border-spacing: 0px; font-size: 1.1em; line-height: 1.3; padding: 0.5em 1em 0px;" class="">Information</th><th style="border-spacing: 0px; font-size: 1.1em; line-height: 1.3; padding: 0.5em 1em 0px;" class="">Projection strategy</th></tr></thead><tbody style="border-spacing: 0px; background-color: rgba(0, 0, 0, 0.0470588);" class=""><tr style="border-spacing: 0px; background-color: rgba(255, 255, 255, 0.0588235);" class=""><td style="word-wrap: break-word; border-spacing: 0px; font-size: 1.1em; line-height: 1.3; padding: 0.5em 1em 0px;" class="">Generic signature</td><td style="word-wrap: break-word; border-spacing: 0px; font-size: 1.1em; line-height: 1.3; padding: 0.5em 1em 0px; background-color: rgba(200, 200, 200, 0.247059);" class="">TBD</td></tr></tbody></table><h3 id="metatypes" style="color: rgb(17, 17, 17); margin: 21px 0px; font-size: 20px; line-height: 21px; font-family: "Helvetica Neue", Helvetica, Arial, Verdana, sans-serif;" class="">Metatypes</h3><p style="color: rgb(17, 17, 17); font-family: "Helvetica Neue", Helvetica, Arial, Verdana, sans-serif; word-wrap: break-word; margin: 1.3125em 0px; font-size: 1.1429em; line-height: 1.3125em;" class="">Metatype metadata records are accessed by calling the <code style="line-height: 1;" class="">swift_getMetatypeMetadata</code> function.</p><p style="color: rgb(17, 17, 17); font-family: "Helvetica Neue", Helvetica, Arial, Verdana, sans-serif; word-wrap: break-word; margin: 1.3125em 0px; font-size: 1.1429em; line-height: 1.3125em;" class="">The compiler does not currently generate any code that reaches into metatype metadata records.</p><p style="color: rgb(17, 17, 17); font-family: "Helvetica Neue", Helvetica, Arial, Verdana, sans-serif; word-wrap: break-word; margin: 1.3125em 0px; font-size: 1.1429em; line-height: 1.3125em;" class="">If we wanted to be able to satisfy type metadata requirements for the instance type from metatype metadata, we could also provide access to:</p><table style="margin: -1px 0px 1.3125em; border-spacing: 0px; border: 1px solid rgba(0, 0, 0, 0.247059); border-collapse: collapse; empty-cells: hide; padding: 0px; table-layout: fixed; color: rgb(17, 17, 17); font-family: "Helvetica Neue", Helvetica, Arial, Verdana, sans-serif; font-size: 15px;" class=""><colgroup style="border-spacing: 0px;" class=""><col style="border-spacing: 0px;" class=""><col style="border-spacing: 0px;" class=""></colgroup><thead style="border-spacing: 0px; background-color: rgba(0, 0, 0, 0.14902); border-width: 1px; border-style: solid; border-color: rgba(0, 0, 0, 0.14902) rgba(0, 0, 0, 0.14902) rgba(0, 0, 0, 0.2);" class=""><tr style="border-spacing: 0px; background-color: rgba(255, 255, 255, 0.0588235);" class=""><th style="border-spacing: 0px; font-size: 1.1em; line-height: 1.3; padding: 0.5em 1em 0px;" class="">Information</th><th style="border-spacing: 0px; font-size: 1.1em; line-height: 1.3; padding: 0.5em 1em 0px;" class="">Projection strategy</th></tr></thead><tbody style="border-spacing: 0px; background-color: rgba(0, 0, 0, 0.0470588);" class=""><tr style="border-spacing: 0px; background-color: rgba(255, 255, 255, 0.0588235);" class=""><td style="word-wrap: break-word; border-spacing: 0px; font-size: 1.1em; line-height: 1.3; padding: 0.5em 1em 0px;" class="">Instance type</td><td style="word-wrap: break-word; border-spacing: 0px; font-size: 1.1em; line-height: 1.3; padding: 0.5em 1em 0px; background-color: rgba(200, 200, 200, 0.247059);" class="">TBD</td></tr></tbody></table><h3 id="objective-cwrappers" style="color: rgb(17, 17, 17); margin: 21px 0px; font-size: 20px; line-height: 21px; font-family: "Helvetica Neue", Helvetica, Arial, Verdana, sans-serif;" class="">Objective-C wrappers</h3><p style="color: rgb(17, 17, 17); font-family: "Helvetica Neue", Helvetica, Arial, Verdana, sans-serif; word-wrap: break-word; margin: 1.3125em 0px; font-size: 1.1429em; line-height: 1.3125em;" class="">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 <code style="line-height: 1;" class="">swift_getObjCClassMetadata</code> function, which may return either a wrapper or pass through the input class object if it is already valid metadata.</p><p style="color: rgb(17, 17, 17); font-family: "Helvetica Neue", Helvetica, Arial, Verdana, sans-serif; word-wrap: break-word; margin: 1.3125em 0px; font-size: 1.1429em; line-height: 1.3125em;" class="">The compiler generates code against the following:</p><table style="margin: -1px 0px 1.3125em; border-spacing: 0px; border: 1px solid rgba(0, 0, 0, 0.247059); border-collapse: collapse; empty-cells: hide; padding: 0px; table-layout: fixed; color: rgb(17, 17, 17); font-family: "Helvetica Neue", Helvetica, Arial, Verdana, sans-serif; font-size: 15px;" class=""><colgroup style="border-spacing: 0px;" class=""><col style="border-spacing: 0px;" class=""><col style="border-spacing: 0px;" class=""></colgroup><thead style="border-spacing: 0px; background-color: rgba(0, 0, 0, 0.14902); border-width: 1px; border-style: solid; border-color: rgba(0, 0, 0, 0.14902) rgba(0, 0, 0, 0.14902) rgba(0, 0, 0, 0.2);" class=""><tr style="border-spacing: 0px; background-color: rgba(255, 255, 255, 0.0588235);" class=""><th style="border-spacing: 0px; font-size: 1.1em; line-height: 1.3; padding: 0.5em 1em 0px;" class="">Information</th><th style="border-spacing: 0px; font-size: 1.1em; line-height: 1.3; padding: 0.5em 1em 0px;" class="">Projection strategy</th></tr></thead><tbody style="border-spacing: 0px; background-color: rgba(0, 0, 0, 0.0470588);" class=""><tr style="border-spacing: 0px; background-color: rgba(255, 255, 255, 0.0588235);" class=""><td style="word-wrap: break-word; border-spacing: 0px; font-size: 1.1em; line-height: 1.3; padding: 0.5em 1em 0px;" class="">Class object</td><td style="word-wrap: break-word; border-spacing: 0px; font-size: 1.1em; line-height: 1.3; padding: 0.5em 1em 0px; background-color: rgba(200, 200, 200, 0.247059);" class="">runtime call <code style="line-height: 1;" class="">swift_getObjCClassFromMetadata</code></td></tr></tbody></table><h3 id="corefoundationclass" style="color: rgb(17, 17, 17); margin: 21px 0px; font-size: 20px; line-height: 21px; font-family: "Helvetica Neue", Helvetica, Arial, Verdana, sans-serif;" class="">Core Foundation class</h3><p style="color: rgb(17, 17, 17); font-family: "Helvetica Neue", Helvetica, Arial, Verdana, sans-serif; word-wrap: break-word; margin: 1.3125em 0px; font-size: 1.1429em; line-height: 1.3125em;" class=""><strong style="line-height: 1;" class="">Foreign class metadata</strong> 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.</p><h1 id="recommendedchanges" style="font-size: 37px; line-height: 42px; margin-top: 42px; margin-bottom: 21px; font-family: "Helvetica Neue", Helvetica, Arial, Verdana, sans-serif;" class="">Recommended changes</h1><h2 id="abstractawayfixedoffsetsacrossmodulesandforstructuralmetadata" style="color: rgb(17, 17, 17); font-size: 27px; line-height: 42px; margin-top: 42px; margin-bottom: 21px; font-family: "Helvetica Neue", Helvetica, Arial, Verdana, sans-serif;" class="">Abstract away fixed offsets across modules and for structural metadata</h2><p style="color: rgb(17, 17, 17); font-family: "Helvetica Neue", Helvetica, Arial, Verdana, sans-serif; word-wrap: break-word; margin: 1.3125em 0px; font-size: 1.1429em; line-height: 1.3125em;" class="">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:</p><ul style="margin-top: 21px; margin-bottom: 21px; padding-left: 1.5em; color: rgb(17, 17, 17); font-family: "Helvetica Neue", Helvetica, Arial, Verdana, sans-serif; font-size: 15px;" class=""><li style="font-size: 16.5px;" class="">the value witness table</li><li style="font-size: 16.5px;" class="">stored property offsets</li><li style="font-size: 16.5px;" class="">generic arguments</li></ul><p style="color: rgb(17, 17, 17); font-family: "Helvetica Neue", Helvetica, Arial, Verdana, sans-serif; word-wrap: break-word; margin: 1.3125em 0px; font-size: 1.1429em; line-height: 1.3125em;" class="">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.</p><p style="color: rgb(17, 17, 17); font-family: "Helvetica Neue", Helvetica, Arial, Verdana, sans-serif; word-wrap: break-word; margin: 1.3125em 0px; font-size: 1.1429em; line-height: 1.3125em;" class="">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 <strong style="line-height: 1;" class="">base offset</strong> to the contiguous data structure. Possibilities for accessing the base offset include:</p><ol style="margin-top: 21px; margin-bottom: 21px; padding-left: 1.5em; list-style-position: inside; color: rgb(17, 17, 17); font-family: "Helvetica Neue", Helvetica, Arial, Verdana, sans-serif; font-size: 15px;" class=""><li style="font-size: 16.5px;" class="">Require a runtime call to get it</li><li style="font-size: 16.5px;" class="">Place the base offset somewhere else in the metadata</li><li style="font-size: 16.5px;" class="">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).</li></ol><p style="color: rgb(17, 17, 17); font-family: "Helvetica Neue", Helvetica, Arial, Verdana, sans-serif; word-wrap: break-word; margin: 1.3125em 0px; font-size: 1.1429em; line-height: 1.3125em;" class="">For classes with resilient ancestry, we already <em style="line-height: 1;" class="">must</em> 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.</p><h2 id="makemostmetadatakindsprivatetotheruntime" style="color: rgb(17, 17, 17); font-size: 27px; line-height: 42px; margin-top: 42px; margin-bottom: 21px; font-family: "Helvetica Neue", Helvetica, Arial, Verdana, sans-serif;" class="">Make most metadata kinds private to the runtime</h2><p style="color: rgb(17, 17, 17); font-family: "Helvetica Neue", Helvetica, Arial, Verdana, sans-serif; word-wrap: break-word; margin: 1.3125em 0px; font-size: 1.1429em; line-height: 1.3125em;" class="">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).</p><div class=""><br class=""></div><div class="">-Joe</div></div>_______________________________________________<br class="">swift-dev mailing list<br class=""><a href="mailto:swift-dev@swift.org" class="">swift-dev@swift.org</a><br class="">https://lists.swift.org/mailman/listinfo/swift-dev<br class=""></blockquote></div><br class=""></body></html>