Skip to content

Commit dcd692d

Browse files
authored
Merge pull request #820 from apple/revert-807-arena-lock
2 parents 6ba87a8 + badbda0 commit dcd692d

File tree

4 files changed

+21
-148
lines changed

4 files changed

+21
-148
lines changed

Sources/SwiftParser/Parser.swift

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,8 @@ extension Parser {
4242
// Extended lifetime is required because `SyntaxArena` in the parser must
4343
// be alive until `Syntax(raw:)` retains the arena.
4444
return withExtendedLifetime(parser) {
45-
parser.arena.assumingSingleThread {
46-
let rawSourceFile = parser.parseSourceFile()
47-
return Syntax(raw: rawSourceFile.raw).as(SourceFileSyntax.self)!
48-
}
45+
let rawSourceFile = parser.parseSourceFile()
46+
return Syntax(raw: rawSourceFile.raw).as(SourceFileSyntax.self)!
4947
}
5048
}
5149
}

Sources/SwiftParser/Syntax+StringInterpolation.swift

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -73,9 +73,7 @@ extension SyntaxExpressibleByStringInterpolation {
7373
var parser = Parser(buffer)
7474
// FIXME: When the parser supports incremental parsing, put the
7575
// interpolatedSyntaxNodes in so we don't have to parse them again.
76-
return parser.arena.assumingSingleThread {
77-
return Self.parse(from: &parser)
78-
}
76+
return Self.parse(from: &parser)
7977
}
8078
}
8179

Sources/SwiftSyntax/SyntaxArena.swift

Lines changed: 17 additions & 116 deletions
Original file line numberDiff line numberDiff line change
@@ -10,69 +10,11 @@
1010
//
1111
//===----------------------------------------------------------------------===//
1212

13-
#if canImport(Darwin)
14-
import Darwin
15-
16-
struct ScopeGuard {
17-
private let lock: os_unfair_lock_t
18-
init(allocator: BumpPtrAllocator) {
19-
let storage = allocator.allocate(os_unfair_lock.self, count: 1).baseAddress!
20-
storage.initialize(to: os_unfair_lock())
21-
self.lock = os_unfair_lock_t(storage)
22-
}
23-
24-
func deinitialize() {}
25-
26-
func withGuard<T>(body: () throws -> T) rethrows -> T {
27-
os_unfair_lock_lock(lock)
28-
defer { os_unfair_lock_unlock(lock)}
29-
return try body()
30-
}
31-
}
32-
33-
#elseif canImport(Glibc)
34-
import Glibc
35-
36-
struct ScopeGuard {
37-
private let lock: UnsafeMutablePointer<pthread_mutex_t>
38-
init(allocator: BumpPtrAllocator) {
39-
let storage = allocator.allocate(pthread_mutex_t.self, count: 1).baseAddress!
40-
storage.initialize(to: pthread_mutex_t())
41-
pthread_mutex_init(storage, nil)
42-
self.lock = storage
43-
}
44-
func deinitialize() {
45-
pthread_mutex_destroy(self.lock)
46-
}
47-
func withGuard<T>(body: () throws -> T) rethrows -> T {
48-
pthread_mutex_lock(self.lock)
49-
defer { pthread_mutex_unlock(self.lock) }
50-
return try body()
51-
}
52-
}
53-
54-
#else
55-
// FIXME: Support other platforms.
56-
57-
/// Dummy mutex that doesn't actually guard at all.
58-
class ScopeGuard {
59-
init() {}
60-
func deinitialize() {}
61-
func withGuard<T>(body: () throws -> T) rethrows -> T {
62-
return try body()
63-
}
64-
}
65-
#endif
66-
6713
public class SyntaxArena {
6814

6915
@_spi(RawSyntax)
7016
public typealias ParseTriviaFunction = (_ source: SyntaxText, _ position: TriviaPosition) -> [RawTriviaPiece]
7117

72-
/// Thread safe guard.
73-
private let lock: ScopeGuard
74-
private var singleThreadMode: Bool
75-
7618
/// Bump-pointer allocator for all "intern" methods.
7719
private let allocator: BumpPtrAllocator
7820
/// Source file buffer the Syntax tree represents.
@@ -88,53 +30,26 @@ public class SyntaxArena {
8830

8931
@_spi(RawSyntax)
9032
public init(parseTriviaFunction: @escaping ParseTriviaFunction) {
91-
let allocator = BumpPtrAllocator()
92-
self.lock = ScopeGuard(allocator: allocator)
93-
self.singleThreadMode = false
94-
self.allocator = allocator
33+
allocator = BumpPtrAllocator()
9534
children = []
9635
sourceBuffer = .init(start: nil, count: 0)
9736
hasParent = false
9837
self.parseTriviaFunction = parseTriviaFunction
9938
}
10039

101-
deinit {
102-
// NOTE: We don't make `ScopeGuard` a class and `deinit` in it to
103-
// deinitialize it because the actual lock value is in `allocator`, and we
104-
// want to make sure to deinitialize the lock before destroying the allocator.
105-
lock.deinitialize()
106-
}
107-
10840
public convenience init() {
10941
self.init(parseTriviaFunction: _defaultParseTriviaFunction(_:_:))
11042
}
11143

112-
private func withGuard<R>(_ body: () throws -> R) rethrows -> R {
113-
if self.singleThreadMode {
114-
return try body()
115-
} else {
116-
return try self.lock.withGuard(body: body)
117-
}
118-
}
119-
120-
public func assumingSingleThread<R>(body: () throws -> R) rethrows -> R {
121-
let oldValue = self.singleThreadMode
122-
defer { self.singleThreadMode = oldValue }
123-
self.singleThreadMode = true
124-
return try body()
125-
}
126-
12744
/// Copies a source buffer in to the memory this arena manages, and returns
12845
/// the interned buffer.
12946
///
13047
/// The interned buffer is guaranteed to be null-terminated.
13148
/// `contains(address _:)` is faster if the address is inside the memory
13249
/// range this function returned.
13350
public func internSourceBuffer(_ buffer: UnsafeBufferPointer<UInt8>) -> UnsafeBufferPointer<UInt8> {
134-
let allocated = self.withGuard {
135-
allocator.allocate(UInt8.self, count: buffer.count + /* for NULL */1)
136-
}
13751
precondition(sourceBuffer.baseAddress == nil, "SourceBuffer should only be set once.")
52+
let allocated = allocator.allocate(UInt8.self, count: buffer.count + /* for NULL */1)
13853
_ = allocated.initialize(from: buffer)
13954

14055
// NULL terminate.
@@ -154,27 +69,20 @@ public class SyntaxArena {
15469
/// Allocates a buffer of `RawSyntax?` with the given count, then returns the
15570
/// uninitlialized memory range as a `UnsafeMutableBufferPointer<RawSyntax?>`.
15671
func allocateRawSyntaxBuffer(count: Int) -> UnsafeMutableBufferPointer<RawSyntax?> {
157-
return self.withGuard {
158-
allocator.allocate(RawSyntax?.self, count: count)
159-
}
72+
return allocator.allocate(RawSyntax?.self, count: count)
16073
}
16174

16275
/// Allcates a buffer of `RawTriviaPiece` with the given count, then returns
16376
/// the uninitialized memory range as a `UnsafeMutableBufferPointer<RawTriviaPiece>`.
16477
func allocateRawTriviaPieceBuffer(
165-
count: Int
166-
) -> UnsafeMutableBufferPointer<RawTriviaPiece> {
167-
return self.withGuard {
168-
allocator.allocate(RawTriviaPiece.self, count: count)
78+
count: Int) -> UnsafeMutableBufferPointer<RawTriviaPiece> {
79+
return allocator.allocate(RawTriviaPiece.self, count: count)
16980
}
170-
}
17181

17282
/// Allcates a buffer of `UInt8` with the given count, then returns the
17383
/// uninitialized memory range as a `UnsafeMutableBufferPointer<UInt8>`.
17484
func allocateTextBuffer(count: Int) -> UnsafeMutableBufferPointer<UInt8> {
175-
return self.withGuard {
176-
allocator.allocate(UInt8.self, count: count)
177-
}
85+
return allocator.allocate(UInt8.self, count: count)
17886
}
17987

18088
/// Copies the contents of a `SyntaxText` to the memory this arena manages,
@@ -206,9 +114,7 @@ public class SyntaxArena {
206114
/// Copies a `RawSyntaxData` to the memory this arena manages, and retuns the
207115
/// pointer to the destination.
208116
func intern(_ value: RawSyntaxData) -> UnsafePointer<RawSyntaxData> {
209-
let allocated = self.withGuard {
210-
allocator.allocate(RawSyntaxData.self, count: 1).baseAddress!
211-
}
117+
let allocated = allocator.allocate(RawSyntaxData.self, count: 1).baseAddress!
212118
allocated.initialize(to: value)
213119
return UnsafePointer(allocated)
214120
}
@@ -222,26 +128,21 @@ public class SyntaxArena {
222128
/// See also `RawSyntax.layout()`.
223129
func addChild(_ arenaRef: SyntaxArenaRef) {
224130
if SyntaxArenaRef(self) == arenaRef { return }
225-
let other = arenaRef.value
226131

227-
other.withGuard {
228-
self.withGuard {
229-
precondition(
230-
!self.hasParent,
231-
"an arena can't have a new child once it's owned by other arenas")
132+
let other = arenaRef.value
232133

233-
other.hasParent = true
234-
children.insert(other)
235-
}
236-
}
134+
precondition(
135+
!self.hasParent,
136+
"an arena can't have a new child once it's owned by other arenas")
137+
138+
other.hasParent = true
139+
children.insert(other)
237140
}
238141

239142
/// Recursively checks if this arena contains given `arena` as a descendant.
240143
func contains(arena: SyntaxArena) -> Bool {
241-
self.withGuard {
242-
children.contains { child in
243-
child === arena || child.contains(arena: arena)
244-
}
144+
return children.contains { child in
145+
child === arena || child.contains(arena: arena)
245146
}
246147
}
247148

@@ -253,7 +154,7 @@ public class SyntaxArena {
253154
public func contains(text: SyntaxText) -> Bool {
254155
return (text.isEmpty ||
255156
sourceBufferContains(text.baseAddress!) ||
256-
self.withGuard({allocator.contains(address: text.baseAddress!)}))
157+
allocator.contains(address: text.baseAddress!))
257158
}
258159

259160
@_spi(RawSyntax)

Tests/SwiftSyntaxTest/MultithreadingTests.swift

Lines changed: 1 addition & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import XCTest
2-
@_spi(RawSyntax) import SwiftSyntax
3-
2+
import SwiftSyntax
43

54
public class MultithreadingTests: XCTestCase {
65

@@ -16,29 +15,6 @@ public class MultithreadingTests: XCTestCase {
1615
}
1716
}
1817

19-
public func testConcurrentArena() {
20-
let arena = SyntaxArena()
21-
22-
DispatchQueue.concurrentPerform(iterations: 100) { i in
23-
var identStr = " ident\(i) "
24-
let tokenRaw = identStr.withSyntaxText { text in
25-
RawTokenSyntax(
26-
kind: .identifier,
27-
wholeText: arena.intern(text),
28-
textRange: 1..<(text.count-1),
29-
presence: .present,
30-
arena: arena)
31-
}
32-
let identifierExprRaw = RawIdentifierExprSyntax(
33-
identifier: tokenRaw,
34-
declNameArguments: nil,
35-
arena: arena)
36-
37-
let expr = Syntax(raw: RawSyntax(identifierExprRaw)).as(IdentifierExprSyntax.self)!
38-
XCTAssertEqual(expr.identifier.text, "ident\(i)")
39-
}
40-
}
41-
4218
public func testTwoAccesses() {
4319
let tuple = TupleTypeSyntax(
4420
leftParen: .leftParenToken(),

0 commit comments

Comments
 (0)