Skip to content

Commit

Permalink
Update Swift interop memory management
Browse files Browse the repository at this point in the history
  • Loading branch information
kotlarmilos committed Feb 22, 2024
1 parent 40ba112 commit dee97b2
Showing 1 changed file with 1 addition and 1 deletion.
2 changes: 1 addition & 1 deletion proposed/swift-interop.md
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ CoreCLR and NativeAOT currently block the `VectorX<T>` types from P/Invokes as t

##### Automatic Reference Counting and Lifetime Management

Swift has a strongly-defined lifetime and ownership model. This model is specified in the Swift ABI and is similar to Objective-C's ARC (Automatic Reference Counting) system. When .NET calls into Swift, the .NET GC is responsible for managing all managed objects. Types projected from Swift into C# should adhere to the `IDisposable` interface. The projection tooling will generate finalizers, and it's the responsibility of users to utilize finalizers and manage memory explicitly from the managed code. Furthermore, it should employ thin wrappers over the Swift memory allocator, accessible through the `NativeMemory` class, to ensure explicit memory release.. It's important to ensure that when a Swift callee function allocates an "unsafe" or "raw" pointer types, such as UnsafeMutablePointer and UnsafeRawPointer, where explicit control over memory is needed, and the pointer is returned to .NET, the memory is not dereferenced after the call returns. Also, if a C# managed object is allocated in a callee function and returned to Swift, the .NET GC will eventually collect it, but Swift will keep track using ARC, which represents an invalid case and should be handled by projection tools.
Swift has a strongly-defined lifetime and ownership model. This model is specified in the Swift ABI and is similar to Objective-C's ARC (Automatic Reference Counting) system. When .NET calls into Swift, the .NET GC is responsible for managing all managed objects. Types projected from Swift into C# should adhere to the `IDisposable` interface. The projection tooling will generate finalizers, and it's the responsibility of users to utilize finalizers and manage memory explicitly from the managed code. Furthermore, it should employ thin wrappers over the Swift memory allocator, accessible through the `NativeMemory` class, to ensure explicit memory release. It's important to ensure that when a Swift callee function allocates an "unsafe" or "raw" pointer types, such as UnsafeMutablePointer and UnsafeRawPointer, where explicit control over memory is needed, and the pointer is returned to .NET, the memory is not dereferenced after the call returns. Also, if a C# managed object is allocated in a callee function and returned to Swift, the .NET GC will eventually collect it, but Swift will keep track using ARC, which represents an invalid case and should be handled by projection tools.

The Binding Tools for Swift tooling handles these explicit lifetime semantics with generated Swift code. In the new Swift/.NET interop, management of these lifetime semantics will be done by the Swift projection layer and not by the raw calling-convention support. If any GC interaction is required to handle the lifetime semantics correctly, we should take an approach more similar to the `ComWrappers` support (higher-level, less complex interop interface) rather than the Objective-C interop support (lower-level, basically only usable by the ObjCRuntime implementation).

Expand Down

0 comments on commit dee97b2

Please sign in to comment.