1
- package dotty .tools .dotc
1
+ package dotty .tools
2
+ package dotc
2
3
package core
3
4
4
5
import scala .io .Codec
@@ -151,11 +152,13 @@ object Names {
151
152
override def seq = toCollection(this )
152
153
}
153
154
154
- class TermName (val start : Int , val length : Int , private [Names ] var next : TermName ) extends Name {
155
+ class TermName (val start : Int , val length : Int , @ sharable private [Names ] var next : TermName ) extends Name {
156
+ // `next` is @sharable because it is only modified in the synchronized block of termName.
155
157
type ThisName = TermName
156
158
def isTypeName = false
157
159
def isTermName = true
158
160
161
+ @ sharable // because it is only modified in the synchronized block of toTypeName.
159
162
@ volatile private [this ] var _typeName : TypeName = null
160
163
161
164
def toTypeName : TypeName = {
@@ -200,44 +203,21 @@ object Names {
200
203
private final val fillFactor = 0.7
201
204
202
205
/** Memory to store all names sequentially. */
206
+ @ sharable // because it's only mutated in synchronized block of termName
203
207
private [dotty] var chrs : Array [Char ] = new Array [Char ](InitialNameSize )
204
208
205
209
/** The number of characters filled. */
210
+ @ sharable // because it's only mutated in synchronized block of termName
206
211
private var nc = 0
207
212
208
213
/** Hashtable for finding term names quickly. */
214
+ @ sharable // because it's only mutated in synchronized block of termName
209
215
private var table = new Array [TermName ](InitialHashSize )
210
216
211
217
/** The number of defined names. */
218
+ @ sharable // because it's only mutated in synchronized block of termName
212
219
private var size = 1
213
220
214
- /** Make sure the capacity of the character array is at least `n` */
215
- private def ensureCapacity (n : Int ) =
216
- if (n > chrs.length) {
217
- val newchrs = new Array [Char ](chrs.length * 2 )
218
- chrs.copyToArray(newchrs)
219
- chrs = newchrs
220
- }
221
-
222
- /** Make sure the hash table is large enough for the given load factor */
223
- private def incTableSize () = {
224
- size += 1
225
- if (size.toDouble / table.size > fillFactor) {
226
- val oldTable = table
227
- table = new Array [TermName ](table.size * 2 )
228
- for (i <- 0 until oldTable.size) rehash(oldTable(i))
229
- }
230
- }
231
-
232
- /** Rehash chain of names */
233
- private def rehash (name : TermName ): Unit =
234
- if (name != null ) {
235
- rehash(name.next)
236
- val h = hashValue(chrs, name.start, name.length) & (table.size - 1 )
237
- name.next = table(h)
238
- table(h) = name
239
- }
240
-
241
221
/** The hash of a name made of from characters cs[offset..offset+len-1]. */
242
222
private def hashValue (cs : Array [Char ], offset : Int , len : Int ): Int =
243
223
if (len > 0 )
@@ -257,24 +237,53 @@ object Names {
257
237
i == len
258
238
}
259
239
260
- /** Enter characters into chrs array. */
261
- private def enterChars (cs : Array [Char ], offset : Int , len : Int ): Unit = {
262
- ensureCapacity(nc + len)
263
- var i = 0
264
- while (i < len) {
265
- chrs(nc + i) = cs(offset + i)
266
- i += 1
267
- }
268
- nc += len
269
- }
270
-
271
240
/** Create a term name from the characters in cs[offset..offset+len-1].
272
241
* Assume they are already encoded.
273
242
*/
274
243
def termName (cs : Array [Char ], offset : Int , len : Int ): TermName = {
275
244
util.Stats .record(" termName" )
276
245
val h = hashValue(cs, offset, len) & (table.size - 1 )
246
+
277
247
synchronized {
248
+
249
+ /** Make sure the capacity of the character array is at least `n` */
250
+ def ensureCapacity (n : Int ) =
251
+ if (n > chrs.length) {
252
+ val newchrs = new Array [Char ](chrs.length * 2 )
253
+ chrs.copyToArray(newchrs)
254
+ chrs = newchrs
255
+ }
256
+
257
+ /** Enter characters into chrs array. */
258
+ def enterChars (): Unit = {
259
+ ensureCapacity(nc + len)
260
+ var i = 0
261
+ while (i < len) {
262
+ chrs(nc + i) = cs(offset + i)
263
+ i += 1
264
+ }
265
+ nc += len
266
+ }
267
+
268
+ /** Rehash chain of names */
269
+ def rehash (name : TermName ): Unit =
270
+ if (name != null ) {
271
+ rehash(name.next)
272
+ val h = hashValue(chrs, name.start, name.length) & (table.size - 1 )
273
+ name.next = table(h)
274
+ table(h) = name
275
+ }
276
+
277
+ /** Make sure the hash table is large enough for the given load factor */
278
+ def incTableSize () = {
279
+ size += 1
280
+ if (size.toDouble / table.size > fillFactor) {
281
+ val oldTable = table
282
+ table = new Array [TermName ](table.size * 2 )
283
+ for (i <- 0 until oldTable.size) rehash(oldTable(i))
284
+ }
285
+ }
286
+
278
287
val next = table(h)
279
288
var name = next
280
289
while (name ne null ) {
@@ -283,7 +292,7 @@ object Names {
283
292
name = name.next
284
293
}
285
294
name = new TermName (nc, len, next)
286
- enterChars(cs, offset, len )
295
+ enterChars()
287
296
table(h) = name
288
297
incTableSize()
289
298
name
0 commit comments