From a15d1d617a9a9b6e262eaf6a7f6dd4e3a9dc8c37 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Fri, 2 Jun 2006 18:04:28 +0000 Subject: space leaks are plugged --- .../scala/tools/nsc/CompilationUnits.scala | 2 - .../scala/tools/nsc/symtab/SymbolTable.scala | 25 ++++---- src/compiler/scala/tools/nsc/symtab/Symbols.scala | 66 ++++++++++++---------- src/compiler/scala/tools/nsc/symtab/Types.scala | 11 +++- .../scala/tools/nsc/typechecker/Namers.scala | 2 +- 5 files changed, 56 insertions(+), 50 deletions(-) (limited to 'src/compiler') diff --git a/src/compiler/scala/tools/nsc/CompilationUnits.scala b/src/compiler/scala/tools/nsc/CompilationUnits.scala index 46e95dbb29..24f0b66b8e 100644 --- a/src/compiler/scala/tools/nsc/CompilationUnits.scala +++ b/src/compiler/scala/tools/nsc/CompilationUnits.scala @@ -13,8 +13,6 @@ import scala.collection.mutable.HashSet; trait CompilationUnits requires Global { - private var unitCount = 0; - class CompilationUnit(val source: SourceFile) { /** the fresh name creator */ diff --git a/src/compiler/scala/tools/nsc/symtab/SymbolTable.scala b/src/compiler/scala/tools/nsc/symtab/SymbolTable.scala index 74642f0eb7..eb9fb486e5 100644 --- a/src/compiler/scala/tools/nsc/symtab/SymbolTable.scala +++ b/src/compiler/scala/tools/nsc/symtab/SymbolTable.scala @@ -23,8 +23,19 @@ abstract class SymbolTable extends Names /** Are we compiling for the J2ME CLDC platform? */ def forCLDC: Boolean + /** A period is an ordinal number for a phase in a run. + * Phases in later runs have higher periods than phases in earlier runs. + * Later phases have higher periods than earlier phases in the same run. + */ + type Period = int + final val NoPeriod = 0 + + /** An ordinal number for compiler runs. First run has number 1. */ + type RunId = int + final val NoRunId = 0 + private var ph: Phase = NoPhase - private var period = 0 + private var period = NoPeriod def phase: Phase = ph @@ -35,21 +46,9 @@ abstract class SymbolTable extends Names period = (currentRunId << 8) + p.id } - /** An ordinal number for compiler runs. First run has number 1. */ - type RunId = int - - val NoRunId = 0 - /** The current compiler run identifier. */ def currentRunId: RunId - /** A period is an ordinal number for a phase in a run. - * Phases in later runs have higher periods than phases in earlier runs. - * Later phases have higher periods than earlier phases in the same run. - */ - type Period = int - val NoPeriod = -1 - /** The run identifier of the given period */ def runId(period: Period): RunId = period >> 8 diff --git a/src/compiler/scala/tools/nsc/symtab/Symbols.scala b/src/compiler/scala/tools/nsc/symtab/Symbols.scala index 4db6d26e83..65606e591d 100644 --- a/src/compiler/scala/tools/nsc/symtab/Symbols.scala +++ b/src/compiler/scala/tools/nsc/symtab/Symbols.scala @@ -33,7 +33,7 @@ trait Symbols requires SymbolTable { private var rawpos = initPos val id = { ids = ids + 1; ids } - var validForRunId: RunId = NoRunId + var validTo: Period = NoPeriod def pos = rawpos def setPos(pos: int): this.type = { this.rawpos = pos; this } @@ -276,7 +276,7 @@ trait Symbols requires SymbolTable { this != NoSymbol && (!owner.isPackageClass || { rawInfo.load(this); rawInfo != NoType }) final def isInitialized: boolean = - validForRunId == currentRunId + runId(validTo) == currentRunId final def isCovariant: boolean = isType && hasFlag(COVARIANT) @@ -314,7 +314,6 @@ trait Symbols requires SymbolTable { // Info and Type ------------------------------------------------------------------- private var infos: TypeHistory = null - private var limit: Phase#Id = 0 /** Get type. The type of a symbol is: * for a type symbol, the type corresponding to the symbol itself @@ -327,7 +326,7 @@ trait Symbols requires SymbolTable { */ final def info: Type = { var cnt = 0 - while (validForRunId != currentRunId) { + while (runId(validTo) != currentRunId) { //if (settings.debug.value) System.out.println("completing " + this);//DEBUG var ifs = infos assert(ifs != null, this.name) @@ -345,7 +344,7 @@ trait Symbols requires SymbolTable { try { phase = phaseWithId(ifs.start) tp.complete(this) - // if (settings.debug.value && validForRunId == currentRunId) System.out.println("completed " + this/* + ":" + info*/);//DEBUG + // if (settings.debug.value && runId(validTo) == currentRunId) System.out.println("completed " + this/* + ":" + info*/);//DEBUG rawflags = rawflags & ~LOCKED } finally { phase = current @@ -361,20 +360,19 @@ trait Symbols requires SymbolTable { /** Set initial info. */ def setInfo(info: Type): this.type = { assert(info != null) - var pid = phase.id - if (pid == 0) { + var period = currentPeriod + if (phaseId(period) == 0) { // can happen when we initialize NoSymbol before running the compiler assert(name == nme.NOSYMBOL) - pid = 1 + period = period + 1 } - infos = new TypeHistory(pid, info, null) - limit = pid + infos = new TypeHistory(phaseId(period), info, null) if (info.isComplete) { rawflags = rawflags & ~LOCKED - validForRunId = currentRunId + validTo = currentPeriod } else { rawflags = rawflags & ~LOCKED - validForRunId = NoRunId + validTo = NoPeriod } this } @@ -388,26 +386,31 @@ trait Symbols requires SymbolTable { } /** Return info without checking for initialization or completing */ - final def rawInfo: Type = { - if (limit < phase.id) { - if (validForRunId == currentRunId) { - val current = phase - var itr = infoTransformers.nextFrom(limit) - infoTransformers = itr; // caching optimization - while (itr.pid != NoPhase.id && itr.pid < current.id) { - phase = phaseWithId(itr.pid) - val info1 = itr.transform(this, infos.info) - limit = phase.id + 1 - if (info1 ne infos.info) { - infos = new TypeHistory(limit, info1, infos) + final def rawInfo: Type = + if (validTo == currentPeriod) { + infos.info + } else { + var limit = phaseId(validTo) + if (limit < phase.id) { + if (runId(validTo) == currentRunId) { + val current = phase + var itr = infoTransformers.nextFrom(limit) + infoTransformers = itr; // caching optimization + while (itr.pid != NoPhase.id && itr.pid < current.id) { + limit = itr.pid + phase = phaseWithId(limit) + val info1 = itr.transform(this, infos.info) + validTo = currentPeriod + 1 + if (info1 ne infos.info) { + infos = new TypeHistory(limit + 1, info1, infos) + } + itr = itr.nextFrom(limit + 1) } - itr = itr.nextFrom(limit) + phase = current + validTo = currentPeriod } - phase = current - limit = current.id - } - assert(infos != null, name) - infos.info + assert(infos != null, name) + infos.info } else { var infos = this.infos while (phase.id < infos.start && infos.prev != null) infos = infos.prev @@ -450,7 +453,8 @@ trait Symbols requires SymbolTable { def reset(completer: Type): unit = { resetFlags infos = null - limit = NoPhase.id + validTo = NoPeriod + //limit = NoPhase.id setInfo(completer) } diff --git a/src/compiler/scala/tools/nsc/symtab/Types.scala b/src/compiler/scala/tools/nsc/symtab/Types.scala index f5f6fdc8f3..bd36f74ccb 100644 --- a/src/compiler/scala/tools/nsc/symtab/Types.scala +++ b/src/compiler/scala/tools/nsc/symtab/Types.scala @@ -335,10 +335,10 @@ trait Types requires SymbolTable { /** If this is a lazy type, assign a new type to `sym'. */ def complete(sym: Symbol): unit = { - if (sym == NoSymbol || sym.isPackageClass) sym.validForRunId = currentRunId + if (sym == NoSymbol || sym.isPackageClass) sym.validTo = currentPeriod else { val this1 = adaptToNewRunMap(this) - if (this1 eq this) sym.validForRunId = currentRunId + if (this1 eq this) sym.validTo = currentPeriod else { //System.out.println("new type of " + sym + "=" + this1);//DEBUG sym.setInfo(this1) @@ -1122,11 +1122,16 @@ trait Types requires SymbolTable { // Hash consing -------------------------------------------------------------- - private val uniques = new HashSet[AnyRef](20000) + private var uniques: HashSet[AnyRef] = _ + private var uniqueRunId = NoRunId def uniqueTypeCount = uniques.size // for statistics private def unique[T <: AnyRef](tp: T): T = { + if (uniqueRunId != currentRunId) { + uniques = new HashSet(20000) + uniqueRunId = currentRunId + } val tp1 = uniques.findEntry(tp); if (tp1 == null) { uniques.addEntry(tp); tp diff --git a/src/compiler/scala/tools/nsc/typechecker/Namers.scala b/src/compiler/scala/tools/nsc/typechecker/Namers.scala index f09d971042..0dab8927f5 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Namers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Namers.scala @@ -58,7 +58,7 @@ trait Namers requires Analyzer { updatePosFlags(sym.moduleClass, pos, (flags & ModuleToClassFlags) | MODULE | FINAL); if (sym.owner.isPackageClass && (sym.linkedSym.rawInfo.isInstanceOf[loaders.SymbolLoader] || - sym.linkedSym.rawInfo.isComplete && sym.validForRunId != currentRunId)) + sym.linkedSym.rawInfo.isComplete && runId(sym.validTo) != currentRunId)) // pre-set linked symbol to NoType, in case it is not loaded together with this symbol. sym.linkedSym.setInfo(NoType); sym -- cgit v1.2.3