Tuesday, February 5, 2019

Swift 5 Exclusivity Enforcement

Andrew Trick:

The Swift 5 release enables runtime checking of “Exclusive Access to Memory” by default in Release builds, further enhancing Swift’s capabilities as a safe language. In Swift 4, these runtime checks were only enabled in Debug builds.

[…]

In essence, a variable cannot be accessed via a different name for the duration in which the same variable is being modified as an inout argument or as self within a mutating method.

[…]

The overhead of the memory access checks could affect the performance of the Release binary. The impact should be small in most cases; if you see a measurable performance regression, please file a bug so we know what we need to improve. As a general guideline, avoid performing class property access within the most performance critical loops, particularly on different objects in each loop iteration. If that isn’t possible, making the class properties private or internal can help the compiler prove that no other code accesses the same property inside the loop.

[…]

The combination of compile-time and run-time exclusivity checks described above are necessary to enforce Swift’s memory safety. Fully enforcing those rules, rather than placing the burden on programmers to follow the rules, helps in at least five ways[…]

Update (2019-02-26): Russ Bishop:

This has some interesting interactions with atomics, especially when running under the Thread Sanitizer (TSAN). If you’ve ever seen a TSAN report on some simple Swift code that looks obviously correct then you’re probably running into this issue[…]

[…]

The problem lies in the Law Of Exclusivity. The ampersand operator in Swift is not the same as C’s address of operator. It is the inout operator.

[…]

The takeway is this: Under the Swift memory model the UnsafeLock shown above is illegal. The correct strategy is to allocate storage for the lock yourself[…]

He does this using an UnsafeMutablePointer.

1 Comment RSS · Twitter

It seems that documentation is lacking in regard to what constitutes a violation in regard to use of class properties, when structs are not used.

https://www.swift.org/blog/swift-5-exclusivity/ (section Motivation) shows class properties, but the nameSet inside Names is a struct type.

I cannot find a single example anywhere on the net that produces a runtime violation when classes are used whose properties aren't structs. However I can observe runtime cost (in a microbenchmark of an important piece of our code) in the order of 25% of runtime code in swift_beginAccess (even when we aren't using structs in the relevant code).

I wonder if you have an example violation with classes (with non-struct properties) that is detected at runtime.

Leave a Comment