At least when built with optimization, the following test program should print “true” 3 times; instead it prints ”false” 3 times. This demonstrates that some references are not released as early as they could be, blocking a large class of CoW optimizations.
/// A simple boxed integer with value semantics.
struct X {
class Box {
var value: Int
init(value: Int) { self.value = value }
}
var box: Box
var value: Int { box.value }
init(_ x: Int) { box = .init(value: x) }
static func +=(lhs: inout X, rhs: X) {
if isKnownUniquelyReferenced(&lhs.box) {
lhs.box.value += rhs.value
}
else {
var r = rhs
if isKnownUniquelyReferenced(&r.box) {
// Never reached, even if rhs is no longer needed.
r.box.value += lhs.value
lhs = r
}
else {
lhs = lhs + r
}
}
}
static func +(lhs: X, rhs: X) -> X {
var lhs1 = lhs
if isKnownUniquelyReferenced(&lhs1.box) {
// Never reached, even if lhs is no longer needed.
lhs1 += rhs
return lhs1
}
var rhs1 = rhs
if isKnownUniquelyReferenced(&rhs1.box) {
// Never reached, even if rhs is no longer needed.
rhs1 += lhs1
return rhs1
}
return .init(lhs1.value + rhs1.value)
}
var boxID: ObjectIdentifier { .init(box) }
}
func testMe0() {
var a = X(3)
let idA = a.boxID
let b = X(5)
let idB = b.boxID
a += b
assert(a.boxID == idA) // a's storage reused
assert(b.boxID == idB) // b not mutated, holds same box
}
testMe0()
func testMe1() {
var a = X(3)
let idA = a.boxID
let b = X(5)
let idB = b.boxID
let a1 = a // second referece to a's box
a += b // b's lifetime is ending
assert(a1.boxID == idA) // a1 holds the same box it was given
print(a.boxID == idB) // false; should be true <===
}
testMe1()
func testMe2() {
let a = X(3)
let idA = a.boxID
let b = X(5)
let idB = b.boxID
let c = a + b // lifetimes of both a and b are ending
print(c.boxID == idA || c.boxID == idB) // false; should be true <===
}
testMe2()
func testMe3() {
var a = X(3)
let idA = a.boxID
let b = X(5)
let idB = b.boxID
a = a + b
assert(b.boxID == idB)
print(a.boxID == idA) // false; should be true <===
}
testMe3()
/cc @atrick saeta (JIRA User) because I thought they might be interested.
Additional Detail from JIRA
| | | |------------------|-----------------| |Votes | 1 | |Component/s | Compiler | |Labels | Bug | |Assignee | None | |Priority | Medium | md5: 6394984644ea260ec24bc29d52dc014dIssue Description:
At least when built with optimization, the following test program should print “
true
” 3 times; instead it prints ”false
” 3 times. This demonstrates that some references are not released as early as they could be, blocking a large class of CoW optimizations./cc @atrick saeta (JIRA User) because I thought they might be interested.