Skip to content

iOS JIT: reclaim leaked __swift5/ObjC metadata in-process (avoid host relaunch) #225

@obj-p

Description

@obj-p

Follow-up to #221 / #224.

#224 bounds the iOS JIT metadata leak by relaunching the host app on memory pressure. That is the only portable reclaim today, but it costs a full-screen flash and @State loss. This issue tracks reclaiming the leak in-process so no relaunch is needed.

Why the leak exists

Each structural edit JIT-links a fresh generation whose __swift5_proto/__swift5_types (and ObjC class) metadata is registered with the runtime. The Swift runtime appends those records to an append-only global scan list with no unregister API at any visibility (confirmed via nm on iOS 26.2 libswiftCore), and the records point into that generation's __TEXT/__const. So the code pages can never be freed safely. Proven: ExecutionSession::removeJITDylib frees the memory but crashes in _objc_map_images on the next link (dangling runtime pointers). Measured growth ~1.4 MB per structural edit.

Candidate avenues (none free; ordered by practicality)

  1. Reduce/strip per-generation metadata. Use swiftc reflection levers (-disable-reflection-metadata, -reflection-metadata-level none) and/or skip registering __swift5_types for the thunk. If nothing in the runtime holds a pointer into a generation's code, removeJITDylib becomes a safe in-process reclaim. Load-bearing unknown: SwiftUI likely needs the View protocol conformance registered, and that conformance record re-pins the code. Gating measurement (skipped in iOS JIT: relaunch host on memory pressure to reclaim leaked metadata (#221) #224's Phase 0): metadata-vs-code attribution per generation. Bounded experiment: strip, measure per-edit growth, confirm the preview still renders and stays interactive.
  2. Ship a patched Swift runtime with an unregister function. Most thorough, least portable (ABI/version/loading across user toolchains and sim runtimes).
  3. Surgically mutate the runtime's private conformance/type scan lists from our process. Research-grade, fragile, version-specific.

If avenue 1 works, the host relaunch from #224 can be retired (or kept only as a backstop).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions