@@ -14,20 +14,25 @@ private[reflect] trait SynchronizedOps extends internal.SymbolTable
14
14
// BaseTypeSeqs
15
15
16
16
override protected def newBaseTypeSeq (parents : List [Type ], elems : Array [Type ]) =
17
- new BaseTypeSeq (parents, elems) with SynchronizedBaseTypeSeq
17
+ // only need to synchronize BaseTypeSeqs if they contain refined types
18
+ if (elems.filter(_.isInstanceOf [RefinedType ]).nonEmpty) new BaseTypeSeq (parents, elems) with SynchronizedBaseTypeSeq
19
+ else new BaseTypeSeq (parents, elems)
18
20
19
21
trait SynchronizedBaseTypeSeq extends BaseTypeSeq {
20
- override def apply (i : Int ): Type = synchronized { super .apply(i) }
21
- override def rawElem (i : Int ) = synchronized { super .rawElem(i) }
22
- override def typeSymbol (i : Int ): Symbol = synchronized { super .typeSymbol(i) }
23
- override def toList : List [Type ] = synchronized { super .toList }
24
- override def copy (head : Type , offset : Int ): BaseTypeSeq = synchronized { super .copy(head, offset) }
25
- override def map (f : Type => Type ): BaseTypeSeq = synchronized { super .map(f) }
26
- override def exists (p : Type => Boolean ): Boolean = synchronized { super .exists(p) }
27
- override lazy val maxDepth = synchronized { maxDepthOfElems }
28
- override def toString = synchronized { super .toString }
29
-
30
- override def lateMap (f : Type => Type ): BaseTypeSeq = new MappedBaseTypeSeq (this , f) with SynchronizedBaseTypeSeq
22
+ override def apply (i : Int ): Type = gilSynchronized { super .apply(i) }
23
+ override def rawElem (i : Int ) = gilSynchronized { super .rawElem(i) }
24
+ override def typeSymbol (i : Int ): Symbol = gilSynchronized { super .typeSymbol(i) }
25
+ override def toList : List [Type ] = gilSynchronized { super .toList }
26
+ override def copy (head : Type , offset : Int ): BaseTypeSeq = gilSynchronized { super .copy(head, offset) }
27
+ override def map (f : Type => Type ): BaseTypeSeq = gilSynchronized { super .map(f) }
28
+ override def exists (p : Type => Boolean ): Boolean = gilSynchronized { super .exists(p) }
29
+ override lazy val maxDepth = gilSynchronized { maxDepthOfElems }
30
+ override def toString = gilSynchronized { super .toString }
31
+
32
+ override def lateMap (f : Type => Type ): BaseTypeSeq =
33
+ // only need to synchronize BaseTypeSeqs if they contain refined types
34
+ if (map(f).toList.filter(_.isInstanceOf [RefinedType ]).nonEmpty) new MappedBaseTypeSeq (this , f) with SynchronizedBaseTypeSeq
35
+ else new MappedBaseTypeSeq (this , f)
31
36
}
32
37
33
38
// Scopes
@@ -36,15 +41,19 @@ private[reflect] trait SynchronizedOps extends internal.SymbolTable
36
41
override def newNestedScope (outer : Scope ): Scope = new Scope (outer) with SynchronizedScope
37
42
38
43
trait SynchronizedScope extends Scope {
39
- override def isEmpty : Boolean = synchronized { super .isEmpty }
40
- override def size : Int = synchronized { super .size }
41
- override def enter [T <: Symbol ](sym : T ): T = synchronized { super .enter(sym) }
42
- override def rehash (sym : Symbol , newname : Name ) = synchronized { super .rehash(sym, newname) }
43
- override def unlink (e : ScopeEntry ) = synchronized { super .unlink(e) }
44
- override def unlink (sym : Symbol ) = synchronized { super .unlink(sym) }
45
- override def lookupAll (name : Name ) = synchronized { super .lookupAll(name) }
46
- override def lookupEntry (name : Name ) = synchronized { super .lookupEntry(name) }
47
- override def lookupNextEntry (entry : ScopeEntry ) = synchronized { super .lookupNextEntry(entry) }
48
- override def toList : List [Symbol ] = synchronized { super .toList }
44
+ // we can keep this lock fine-grained, because methods of Scope don't do anything extraordinary, which makes deadlocks impossible
45
+ // fancy subclasses of internal.Scopes#Scope should do synchronization themselves (e.g. see PackageScope for an example)
46
+ private lazy val syncLock = new Object
47
+ def syncLockSynchronized [T ](body : => T ): T = syncLock.synchronized { body }
48
+ override def isEmpty : Boolean = syncLockSynchronized { super .isEmpty }
49
+ override def size : Int = syncLockSynchronized { super .size }
50
+ override def enter [T <: Symbol ](sym : T ): T = syncLockSynchronized { super .enter(sym) }
51
+ override def rehash (sym : Symbol , newname : Name ) = syncLockSynchronized { super .rehash(sym, newname) }
52
+ override def unlink (e : ScopeEntry ) = syncLockSynchronized { super .unlink(e) }
53
+ override def unlink (sym : Symbol ) = syncLockSynchronized { super .unlink(sym) }
54
+ override def lookupAll (name : Name ) = syncLockSynchronized { super .lookupAll(name) }
55
+ override def lookupEntry (name : Name ) = syncLockSynchronized { super .lookupEntry(name) }
56
+ override def lookupNextEntry (entry : ScopeEntry ) = syncLockSynchronized { super .lookupNextEntry(entry) }
57
+ override def toList : List [Symbol ] = syncLockSynchronized { super .toList }
49
58
}
50
59
}
0 commit comments