Skip to content

Commit dc04ac3

Browse files
committed
Fix inline vector storage lifetime during subgraph updates
1 parent 3628d2f commit dc04ac3

2 files changed

Lines changed: 48 additions & 1 deletion

File tree

‎Sources/ComputeCxx/Vector/Vector.h‎

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,11 @@ class vector {
3131
using size_type = _size_type;
3232

3333
private:
34-
T _inline_buffer[_inline_capacity];
34+
// Elements are constructed and destroyed explicitly. After relocation to
35+
// the heap, the inline storage must not destroy the old element copies.
36+
union {
37+
T _inline_buffer[_inline_capacity];
38+
};
3539
T *_Nullable _buffer = nullptr;
3640
size_type _size = 0;
3741
size_type _capacity = _inline_capacity;

‎Tests/ComputeTests/Shared/Subgraph/SubgraphUpdateTests.swift‎

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,49 @@ import Testing
22

33
@Suite
44
struct SubgraphUpdateTests {
5+
@Test
6+
func updatePreservesChildrenBeyondInlineCapacity() async {
7+
await #expect(processExitsWith: .success) {
8+
struct CountingRule: StatefulRule {
9+
typealias Value = Int
10+
var count = 0
11+
12+
mutating func updateValue() {
13+
count += 1
14+
value = count
15+
}
16+
}
17+
18+
withGraph {
19+
let parent = Subgraph.current!
20+
let flags = Subgraph.Flags(rawValue: 1)
21+
let children = (0..<64).map { _ in Subgraph(graph: parent.graph) }
22+
let attributes = children.map { child in
23+
parent.addChild(child)
24+
return child.apply {
25+
let attribute = Attribute(CountingRule())
26+
attribute.flags = flags
27+
return attribute
28+
}
29+
}
30+
31+
for expectedValue in 1...3 {
32+
for attribute in attributes {
33+
attribute.invalidateValue()
34+
}
35+
parent.update(flags: flags)
36+
for child in children {
37+
precondition(child.isValid)
38+
}
39+
for attribute in attributes {
40+
precondition(attribute.value == expectedValue)
41+
}
42+
}
43+
withExtendedLifetime(children) {}
44+
}
45+
}
46+
}
47+
548
@Test
649
func updateIterativelyEvaluatesDirtiedAttributesDuringTheSamePass() {
750
class Counter {

0 commit comments

Comments
 (0)