Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Swift Runtime Library

Yuta Saito
December 13, 2019

Swift Runtime Library

Yuta Saito

December 13, 2019
Tweet

More Decks by Yuta Saito

Other Decks in Programming

Transcript

  1. ϝϞϦ֬อ // 24 byte struct Pet { let name: String

    // 16 byte let age: Int // 8 byte } let pet = Pet(name: ..., age: ...) // malloc 24 byte 7
  2. // 8 byte class View { var point: (x: Float,

    y: Float) // 8 byte required init(...) { } func copy() -> Self { return Self(...) // malloc n byte } } // 24 byte class TextView: View { var text: String // 16 byte required init(...) { } } let view: View = TextView(...) // ͜ͷ࣌఺Ͱview͕TextViewͰ͋Δ͜ͱΛอূͰ͖ͳ͍ɻ let anotherView: View = view.copy() 8
  3. struct RelativePointer<Pointee> { var offset: Int32 mutating func pointee() ->

    Pointee { withUnsafePointer(to: &self) { [offset] pointer in let base = UnsafeRawPointer(pointer) let advanced = base.advanced(by: Int(offset)) return advanced.assumingMemoryBound(to: Pointee.self) }.pointee } } 19
  4. struct RelativeIndirectablePointer<Pointee> /* where alignof(Pointee) => 2 */ { let

    offsetWithIndirectFlag: Int32 mutating func pointee() -> Pointee { let offset: Int32 if isIndirect { offset = offsetWithIndirectFlag & ~isIndirectMask } else { offset = offsetWithIndirectFlag } return withUnsafePointer(to: &self) { pointer -> UnsafePointer<Pointee> in let rawPointer = UnsafeRawPointer(pointer) var ptr = rawPointer.advanced(by: Int(offset)) if isIndirect { ptr = ptr.load(as: UnsafeRawPointer.self) } return ptr.assumingMemoryBound(to: Pointee.self) }.pointee } var isIndirect: Bool { offsetWithIndirectFlag & isIndirectMask != 0 } var isIndirectMask: Int32 { 0x01 } } 22
  5. struct RelativeDirectPointerIntPair<Pointee, IntTy: BinaryInteger> /* where alignof(Pointee) => 2 */

    { let offsetWithInt: Int32 mutating func pointee() -> Pointee { let offset = offsetWithInt & ~intMask return withUnsafePointer(to: &self) { pointer -> UnsafePointer<Pointee> in let rawPointer = UnsafeRawPointer(pointer) let advanced = rawPointer.advanced(by: Int(offset)) return advanced.assumingMemoryBound(to: Pointee.self) }.pointee } var value: IntTy { IntTy(offsetWithInt & intMask) } var intMask: Int32 { Int32( min( MemoryLayout<Pointee>.alignment, MemoryLayout<Int32>.alignment ) - 1 ) } } 24
  6. Ҿ਺ʹ { i32, i32 }ͷߏ଄͕౉ͬͯ͘Δɻ union Input { struct {

    RelativePointer<CChar> typeName; // 4byte int32_t negativeTypeNameLength; // 4byte } nonCached; TypeMetadata *cached; // 8 byte } 27
  7. ූ߸෇͖64bit੔਺ͱͯ͠ݟͨ࣌ɺෛ਺Ͱ͋Ε͹Ωϟογϡͳ ͠ɺਖ਼਺Ͱ͋Ε͹Ωϟογϡ͋Γɺͱͯ۠͠ผͰ͖Δɻ TypeMetadata *__swift_instantiateConcreteTypeFromMangledName(Input input) { if ((int64_t)input > 0)

    { return input.cached; } else { const auto typeNameLength = -input.nonCached.negativeTypeNameLength; ... // Some heavy operations ... return ...; } } 28