From 09b1a31309c9cbf1394c317b87d2073d39a8cd56 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Thu, 15 Sep 2011 17:31:31 +0000 Subject: Fixed stackoverflow problem when initializing l... Fixed stackoverflow problem when initializing large scopes. --- src/compiler/scala/reflect/internal/Scopes.scala | 40 ++++++++++++++++-------- 1 file changed, 27 insertions(+), 13 deletions(-) (limited to 'src/compiler') 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 + } -- cgit v1.2.3