10
10
//
11
11
//===----------------------------------------------------------------------===//
12
12
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
-
67
13
public class SyntaxArena {
68
14
69
15
@_spi ( RawSyntax)
70
16
public typealias ParseTriviaFunction = ( _ source: SyntaxText , _ position: TriviaPosition ) -> [ RawTriviaPiece ]
71
17
72
- /// Thread safe guard.
73
- private let lock : ScopeGuard
74
- private var singleThreadMode : Bool
75
-
76
18
/// Bump-pointer allocator for all "intern" methods.
77
19
private let allocator : BumpPtrAllocator
78
20
/// Source file buffer the Syntax tree represents.
@@ -88,53 +30,26 @@ public class SyntaxArena {
88
30
89
31
@_spi ( RawSyntax)
90
32
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 ( )
95
34
children = [ ]
96
35
sourceBuffer = . init( start: nil , count: 0 )
97
36
hasParent = false
98
37
self . parseTriviaFunction = parseTriviaFunction
99
38
}
100
39
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
-
108
40
public convenience init ( ) {
109
41
self . init ( parseTriviaFunction: _defaultParseTriviaFunction ( _: _: ) )
110
42
}
111
43
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
-
127
44
/// Copies a source buffer in to the memory this arena manages, and returns
128
45
/// the interned buffer.
129
46
///
130
47
/// The interned buffer is guaranteed to be null-terminated.
131
48
/// `contains(address _:)` is faster if the address is inside the memory
132
49
/// range this function returned.
133
50
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
- }
137
51
precondition ( sourceBuffer. baseAddress == nil , " SourceBuffer should only be set once. " )
52
+ let allocated = allocator. allocate ( UInt8 . self, count: buffer. count + /* for NULL */1 )
138
53
_ = allocated. initialize ( from: buffer)
139
54
140
55
// NULL terminate.
@@ -154,27 +69,20 @@ public class SyntaxArena {
154
69
/// Allocates a buffer of `RawSyntax?` with the given count, then returns the
155
70
/// uninitlialized memory range as a `UnsafeMutableBufferPointer<RawSyntax?>`.
156
71
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)
160
73
}
161
74
162
75
/// Allcates a buffer of `RawTriviaPiece` with the given count, then returns
163
76
/// the uninitialized memory range as a `UnsafeMutableBufferPointer<RawTriviaPiece>`.
164
77
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)
169
80
}
170
- }
171
81
172
82
/// Allcates a buffer of `UInt8` with the given count, then returns the
173
83
/// uninitialized memory range as a `UnsafeMutableBufferPointer<UInt8>`.
174
84
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)
178
86
}
179
87
180
88
/// Copies the contents of a `SyntaxText` to the memory this arena manages,
@@ -206,9 +114,7 @@ public class SyntaxArena {
206
114
/// Copies a `RawSyntaxData` to the memory this arena manages, and retuns the
207
115
/// pointer to the destination.
208
116
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!
212
118
allocated. initialize ( to: value)
213
119
return UnsafePointer ( allocated)
214
120
}
@@ -222,26 +128,21 @@ public class SyntaxArena {
222
128
/// See also `RawSyntax.layout()`.
223
129
func addChild( _ arenaRef: SyntaxArenaRef ) {
224
130
if SyntaxArenaRef ( self ) == arenaRef { return }
225
- let other = arenaRef. value
226
131
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
232
133
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)
237
140
}
238
141
239
142
/// Recursively checks if this arena contains given `arena` as a descendant.
240
143
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)
245
146
}
246
147
}
247
148
@@ -253,7 +154,7 @@ public class SyntaxArena {
253
154
public func contains( text: SyntaxText ) -> Bool {
254
155
return ( text. isEmpty ||
255
156
sourceBufferContains ( text. baseAddress!) ||
256
- self . withGuard ( { allocator. contains ( address: text. baseAddress!) } ) )
157
+ allocator. contains ( address: text. baseAddress!) )
257
158
}
258
159
259
160
@_spi ( RawSyntax)
0 commit comments