Skip to content

Commit 4c6cc0a

Browse files
authored
Merge pull request #2672 from ahoppen/6.0/atomic-on-heap
[6.0] Heap allocate our atomics
2 parents 74c759f + f5d5abb commit 4c6cc0a

File tree

3 files changed

+25
-28
lines changed

3 files changed

+25
-28
lines changed

Sources/SwiftSyntax/CMakeLists.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,3 +82,6 @@ add_swift_syntax_library(SwiftSyntax
8282
generated/syntaxNodes/SyntaxNodesQRS.swift
8383
generated/syntaxNodes/SyntaxNodesTUVWXYZ.swift
8484
)
85+
86+
target_link_swift_syntax_libraries(SwiftSyntax PRIVATE
87+
_SwiftSyntaxCShims)

Sources/SwiftSyntax/SyntaxArena.swift

Lines changed: 12 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -10,21 +10,10 @@
1010
//
1111
//===----------------------------------------------------------------------===//
1212

13-
#if SWIFT_SYNTAX_BUILD_USING_CMAKE
14-
// The CMake bulid of swift-syntax does not build the _AtomicBool module because swift-syntax's CMake build is
15-
// Swift-only. Fake an `AtomicBool` type that is not actually atomic. This should be acceptable for the following
16-
// reasons:
17-
// - `AtomicBool` is only used for the `hasParent` assertion, so release compilers don't rely on it
18-
// - The compiler is single-threaded so it it is safe from race conditions on `AtomicBool`.
19-
fileprivate struct AtomicBool {
20-
var value: Bool
21-
22-
init(initialValue: Bool) {
23-
self.value = initialValue
24-
}
25-
}
13+
#if swift(>=6.0)
14+
private import _SwiftSyntaxCShims
2615
#else
27-
import _SwiftSyntaxCShims
16+
@_implementationOnly import _SwiftSyntaxCShims
2817
#endif
2918

3019
/// A syntax arena owns the memory for all syntax nodes within it.
@@ -69,7 +58,7 @@ public class SyntaxArena {
6958
///
7059
/// - Important: This is only intended to be used for assertions to catch
7160
/// retain cycles in syntax arenas.
72-
fileprivate var hasParent: AtomicBool
61+
fileprivate let hasParent: UnsafeMutablePointer<AtomicBool>
7362
#endif
7463

7564
/// Construct a new ``SyntaxArena`` in which syntax nodes can be allocated.
@@ -81,14 +70,17 @@ public class SyntaxArena {
8170
self.allocator = BumpPtrAllocator(initialSlabSize: slabSize)
8271
self.childRefs = []
8372
#if DEBUG || SWIFTSYNTAX_ENABLE_ASSERTIONS
84-
self.hasParent = AtomicBool(initialValue: false)
73+
self.hasParent = swiftsyntax_atomic_bool_create(false)
8574
#endif
8675
}
8776

8877
deinit {
8978
for child in childRefs {
9079
child.release()
9180
}
81+
#if DEBUG || SWIFTSYNTAX_ENABLE_ASSERTIONS
82+
swiftsyntax_atomic_bool_destroy(self.hasParent)
83+
#endif
9284
}
9385

9486
/// Allocates a buffer of `RawSyntax?` with the given count, then returns the
@@ -158,7 +150,7 @@ public class SyntaxArena {
158150

159151
#if DEBUG || SWIFTSYNTAX_ENABLE_ASSERTIONS
160152
precondition(
161-
!self.hasParent.value,
153+
!swiftsyntax_atomic_bool_get(self.hasParent),
162154
"an arena can't have a new child once it's owned by other arenas"
163155
)
164156
#endif
@@ -300,14 +292,14 @@ struct SyntaxArenaRef: Hashable, @unchecked Sendable {
300292
}
301293

302294
#if DEBUG || SWIFTSYNTAX_ENABLE_ASSERTIONS
303-
/// Accessor for ther underlying's `SyntaxArena.hasParent`
295+
/// Accessor for the underlying's `SyntaxArena.hasParent`
304296
var hasParent: Bool {
305-
value.hasParent.value
297+
swiftsyntax_atomic_bool_get(value.hasParent)
306298
}
307299

308300
/// Sets the `SyntaxArena.hasParent` on the referenced arena.
309301
func setHasParent(_ newValue: Bool) {
310-
value.hasParent.value = newValue
302+
swiftsyntax_atomic_bool_set(value.hasParent, newValue)
311303
}
312304
#endif
313305

Sources/_SwiftSyntaxCShims/include/AtomicBool.h

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,26 +14,28 @@
1414
#define SWIFTSYNTAX_ATOMICBOOL_H
1515

1616
#include <stdbool.h>
17+
#include <stdlib.h>
1718

1819
typedef struct {
1920
_Atomic(bool) value;
2021
} AtomicBool;
2122

22-
__attribute__((swift_name("AtomicBool.init(initialValue:)")))
23-
static inline AtomicBool atomic_bool_create(bool initialValue) {
24-
AtomicBool atomic;
25-
atomic.value = initialValue;
23+
static inline AtomicBool *_Nonnull swiftsyntax_atomic_bool_create(bool initialValue) {
24+
AtomicBool *atomic = malloc(sizeof(AtomicBool));
25+
atomic->value = initialValue;
2626
return atomic;
2727
}
2828

29-
__attribute__((swift_name("getter:AtomicBool.value(self:)")))
30-
static inline bool atomic_bool_get(AtomicBool *atomic) {
29+
static inline bool swiftsyntax_atomic_bool_get(AtomicBool *_Nonnull atomic) {
3130
return atomic->value;
3231
}
3332

34-
__attribute__((swift_name("setter:AtomicBool.value(self:_:)")))
35-
static inline void atomic_bool_set(AtomicBool *atomic, bool newValue) {
33+
static inline void swiftsyntax_atomic_bool_set(AtomicBool *_Nonnull atomic, bool newValue) {
3634
atomic->value = newValue;
3735
}
3836

37+
static inline void swiftsyntax_atomic_bool_destroy(AtomicBool *_Nonnull atomic) {
38+
free(atomic);
39+
}
40+
3941
#endif // SWIFTSYNTAX_ATOMICBOOL_H

0 commit comments

Comments
 (0)