Skip to content

Commit 8cf7f0e

Browse files
committed
More @sharable annotations
Also, some code movements in Names to make it more obvious that mutating operations are only called from synchronized blocks.
1 parent 1ee827d commit 8cf7f0e

File tree

5 files changed

+57
-47
lines changed

5 files changed

+57
-47
lines changed

src/dotty/tools/dotc/config/ScalaVersion.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ case class SpecificScalaVersion(major: Int, minor: Int, rev: Int, build: ScalaBu
5353
/**
5454
* A Scala version that sorts lower than all actual versions
5555
*/
56-
case object AnyScalaVersion extends ScalaVersion {
56+
@sharable case object AnyScalaVersion extends ScalaVersion {
5757
def unparse = "any"
5858

5959
def compare(that: ScalaVersion): Int = that match {
@@ -65,7 +65,7 @@ case object AnyScalaVersion extends ScalaVersion {
6565
/**
6666
* Methods for parsing ScalaVersions
6767
*/
68-
object ScalaVersion {
68+
@sharable object ScalaVersion {
6969
private val dot = "\\."
7070
private val dash = "\\-"
7171
private def not(s:String) = s"[^${s}]"

src/dotty/tools/dotc/core/Names.scala

Lines changed: 50 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
package dotty.tools.dotc
1+
package dotty.tools
2+
package dotc
23
package core
34

45
import scala.io.Codec
@@ -151,11 +152,13 @@ object Names {
151152
override def seq = toCollection(this)
152153
}
153154

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.
155157
type ThisName = TermName
156158
def isTypeName = false
157159
def isTermName = true
158160

161+
@sharable // because it is only modified in the synchronized block of toTypeName.
159162
@volatile private[this] var _typeName: TypeName = null
160163

161164
def toTypeName: TypeName = {
@@ -200,44 +203,21 @@ object Names {
200203
private final val fillFactor = 0.7
201204

202205
/** Memory to store all names sequentially. */
206+
@sharable // because it's only mutated in synchronized block of termName
203207
private[dotty] var chrs: Array[Char] = new Array[Char](InitialNameSize)
204208

205209
/** The number of characters filled. */
210+
@sharable // because it's only mutated in synchronized block of termName
206211
private var nc = 0
207212

208213
/** Hashtable for finding term names quickly. */
214+
@sharable // because it's only mutated in synchronized block of termName
209215
private var table = new Array[TermName](InitialHashSize)
210216

211217
/** The number of defined names. */
218+
@sharable // because it's only mutated in synchronized block of termName
212219
private var size = 1
213220

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-
241221
/** The hash of a name made of from characters cs[offset..offset+len-1]. */
242222
private def hashValue(cs: Array[Char], offset: Int, len: Int): Int =
243223
if (len > 0)
@@ -257,24 +237,53 @@ object Names {
257237
i == len
258238
}
259239

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-
271240
/** Create a term name from the characters in cs[offset..offset+len-1].
272241
* Assume they are already encoded.
273242
*/
274243
def termName(cs: Array[Char], offset: Int, len: Int): TermName = {
275244
util.Stats.record("termName")
276245
val h = hashValue(cs, offset, len) & (table.size - 1)
246+
277247
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+
278287
val next = table(h)
279288
var name = next
280289
while (name ne null) {
@@ -283,7 +292,7 @@ object Names {
283292
name = name.next
284293
}
285294
name = new TermName(nc, len, next)
286-
enterChars(cs, offset, len)
295+
enterChars()
287296
table(h) = name
288297
incTableSize()
289298
name

src/dotty/tools/dotc/typer/ProtoTypes.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -423,7 +423,7 @@ object ProtoTypes {
423423
def apply(tp: Type) = wildApprox(tp, this)
424424
}
425425

426-
private lazy val dummyTree = untpd.Literal(Constant(null))
426+
@sharable private lazy val dummyTree = untpd.Literal(Constant(null))
427427

428428
/** Dummy tree to be used as an argument of a FunProto or ViewProto type */
429429
object dummyTreeOfType {

src/dotty/tools/dotc/util/SourceFile.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import ScriptSourceFile._
1212
import Positions._
1313

1414
object ScriptSourceFile {
15-
private val headerPattern = Pattern.compile("""^(::)?!#.*(\r|\n|\r\n)""", Pattern.MULTILINE)
15+
@sharable private val headerPattern = Pattern.compile("""^(::)?!#.*(\r|\n|\r\n)""", Pattern.MULTILINE)
1616
private val headerStarts = List("#!", "::#!")
1717

1818
def apply(file: AbstractFile, content: Array[Char]) = {

src/dotty/tools/dotc/util/SourcePosition.scala

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
package dotty.tools.dotc.util
1+
package dotty.tools
2+
package dotc.util
23

34
import Positions.{Position, NoPosition}
45

@@ -19,7 +20,7 @@ case class SourcePosition(source: SourceFile, pos: Position) {
1920
}
2021

2122
/** A sentinel for a non-existing source position */
22-
object NoSourcePosition extends SourcePosition(NoSource, NoPosition) {
23+
@sharable object NoSourcePosition extends SourcePosition(NoSource, NoPosition) {
2324
override def toString = "?"
2425
}
2526

0 commit comments

Comments
 (0)