Insertion of ___swift_instantiateGenericMetadata

When looking through my app's initializers with DYLD_INSERT_LIBRARIES, I see a function that calls into ___swift_instantiateGenericMetadata. It was hard to even find this function, as symbolication with atos failed for it, and I'm curious why it exists and under which conditions it's created. The Swift project source code doesn't seem very clear on it. I'd like to minimize the number of initializers in my app, due to the difficulty of monitoring their startup time impact.

___swift_instantiateGenericMetadata is invoked as part of generating the metadata for a generic type, such as Array<Int>. It's merely a calling convention thunk that reduces the code size of some register shuffling that would otherwise occur in almost every generic type's metadata instantiation function. It is never invoked directly, but is invoked if you do something that requires the metadata of a generic type. There should not be any static initializer functions that invoke it directly, and in general, Swift never emits static initializers. What are you looking for specifically when you say you want to "minimize the number of initializers"?

The following class, which has a few usages, leads to an extra initializer during startup:

import UIKit

class CustomLayerView<T: CALayer>: UIView {
    override class var layerClass: AnyClass { T.self }

    var customLayer: T {
        guard let castedLayer = layer as? T else { fatalError("fail") }
        return castedLayer
    }
}

Looking at an order file, I see:

_$s7SPTTing12GradientViewCMa
_$s7SPTTing12GradientViewCMr
_$s7SPTTing15CustomLayerViewCMa
___swift_instantiateGenericMetadata
_$s7SPTTing15CustomLayerViewCMi
_$s7SPTTing15CustomLayerViewCMr
...
_main

So, CustomLayerView and a consumer of it, CustomGradientView, have some setup at this point. When I remove these classes and its consumers, the initialization work goes away.

Those entry points are part of the metadata of the type. The metadata accessor will only get invoked when the class is actually used, though, not as a static initializer. This is akin to the startup realization that happens for ObjC classes, though for Swift it happens at first use instead of at process launch before main.

Terms of Service

Privacy Policy

Cookie Policy