diff options
author | Martin Odersky <odersky@gmail.com> | 2011-09-15 17:31:31 +0000 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2011-09-15 17:31:31 +0000 |
commit | 09b1a31309c9cbf1394c317b87d2073d39a8cd56 (patch) | |
tree | 38a72ae94778e32fb2889a9fc2eb04424d6c41ee /src | |
parent | 17c04628617809b9542f7d3c9bcb8d3c6d23a2ec (diff) | |
download | scala-09b1a31309c9cbf1394c317b87d2073d39a8cd56.tar.gz scala-09b1a31309c9cbf1394c317b87d2073d39a8cd56.tar.bz2 scala-09b1a31309c9cbf1394c317b87d2073d39a8cd56.zip |
Fixed stackoverflow problem when initializing l...
Fixed stackoverflow problem when initializing large scopes.
Diffstat (limited to 'src')
-rw-r--r-- | src/compiler/scala/reflect/internal/Scopes.scala | 40 |
1 files changed, 27 insertions, 13 deletions
diff --git a/src/compiler/scala/reflect/internal/Scopes.scala b/src/compiler/scala/reflect/internal/Scopes.scala index a73b0f4b4f..7893e0eb3a 100644 --- a/src/compiler/scala/reflect/internal/Scopes.scala +++ b/src/compiler/scala/reflect/internal/Scopes.scala @@ -94,15 +94,18 @@ trait Scopes extends api.Scopes { self: SymbolTable => * * @param e ... */ - def enter(e: ScopeEntry) { + protected def enter(e: ScopeEntry) { elemsCache = null - if (hashtable ne null) { - val i = e.sym.name.start & HASHMASK - elems.tail = hashtable(i) - hashtable(i) = elems - } else if (size >= MIN_HASH) { + if (hashtable ne null) + enterInHash(e) + else if (size >= MIN_HASH) createHash() - } + } + + private def enterInHash(e: ScopeEntry): Unit = { + val i = e.sym.name.start & HASHMASK + e.tail = hashtable(i) + hashtable(i) = e } /** enter a symbol @@ -122,15 +125,23 @@ trait Scopes extends api.Scopes { self: SymbolTable => private def createHash() { hashtable = new Array[ScopeEntry](HASHSIZE) - enterInHash(elems) + enterAllInHash(elems) } - private def enterInHash(e: ScopeEntry) { + private def enterAllInHash(e: ScopeEntry, n: Int = 0) { if (e ne null) { - enterInHash(e.next) - val i = e.sym.name.start & HASHMASK - e.tail = hashtable(i) - hashtable(i) = e + if (n < maxRecursions) { + enterAllInHash(e.next, n + 1) + enterInHash(e) + } else { + var entries: List[ScopeEntry] = List() + var ee = e + while (ee ne null) { + entries = ee :: entries + ee = ee.next + } + entries foreach enterInHash + } } } @@ -334,5 +345,8 @@ trait Scopes extends api.Scopes { self: SymbolTable => /** The error scope. */ class ErrorScope(owner: Symbol) extends Scope(null: ScopeEntry) + + private final val maxRecursions = 1000 + } |