diff --git a/src/compiler/scala/tools/nsc/Global.scala b/src/compiler/scala/tools/nsc/Global.scala index 45d2b752c2ca..da77f2bda8bc 100644 --- a/src/compiler/scala/tools/nsc/Global.scala +++ b/src/compiler/scala/tools/nsc/Global.scala @@ -1655,7 +1655,7 @@ class Global(var currentSettings: Settings, reporter0: LegacyReporter) } private val hotCounters = - List(statistics.retainedCount, statistics.retainedByType, statistics.nodeByType) + List(statistics.retainedCount, statistics.retainedByType) private val parserStats = { import statistics.treeNodeCount if (settings.YhotStatisticsEnabled) treeNodeCount :: hotCounters diff --git a/src/compiler/scala/tools/nsc/backend/jvm/BCodeHelpers.scala b/src/compiler/scala/tools/nsc/backend/jvm/BCodeHelpers.scala index c9f340745d19..2dffdeb41bd1 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/BCodeHelpers.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/BCodeHelpers.scala @@ -645,7 +645,7 @@ abstract class BCodeHelpers extends BCodeIdiomatic { // without it. This is particularly bad because the availability of // generic information could disappear as a consequence of a seemingly // unrelated change. - settings.Ynogenericsig + settings.Ynogenericsig.value || sym.isArtifact || sym.isLiftedMethod || sym.isBridge diff --git a/src/compiler/scala/tools/nsc/typechecker/Infer.scala b/src/compiler/scala/tools/nsc/typechecker/Infer.scala index 0d84ecebb76a..6d6c0898c2c8 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Infer.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Infer.scala @@ -50,11 +50,23 @@ trait Infer extends Checkable { && isVarArgTypes(formals1) ) def lastType = formals1.last.dealiasWiden.typeArgs.head - def expanded(n: Int) = (1 to n).toList map (_ => lastType) - if (expandLast) - formals1.init ::: expanded(numArgs - numFormals + 1) - else + if (expandLast) { + // Optimized version of: formals1.init ::: expanded(numArgs - numFormals + 1) + val result = mutable.ListBuffer[Type]() + var fs = formals + while ((fs ne Nil) && (fs.tail ne Nil)) { + result.addOne(fs.head) + fs = fs.tail + } + var i = 0 + val n = numArgs - numFormals + 1 + while (i < n) { + result += lastType + i += 1 + } + result.toList + } else formals1 } diff --git a/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala b/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala index 80de9c229c53..87190461197f 100644 --- a/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala +++ b/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala @@ -480,7 +480,7 @@ trait TypeDiagnostics { } def apply(context: Context, tree: Tree): Tree = { - if (settings.warnDeadCode && context.unit.exists && treeOK(tree) && !context.contextMode.inAny(ContextMode.SuppressDeadArgWarning)) + if (settings.warnDeadCode.value && context.unit.exists && treeOK(tree) && !context.contextMode.inAny(ContextMode.SuppressDeadArgWarning)) context.warning(tree.pos, "dead code following this construct") tree } diff --git a/src/reflect/scala/reflect/internal/Definitions.scala b/src/reflect/scala/reflect/internal/Definitions.scala index 4bfed9156a0e..7cb0b3a0890a 100644 --- a/src/reflect/scala/reflect/internal/Definitions.scala +++ b/src/reflect/scala/reflect/internal/Definitions.scala @@ -661,6 +661,9 @@ trait Definitions extends api.StandardDefinitions { // add initialization from its generic class constructor val genericName = nme.unspecializedName(sym.name) val member = sym.owner.info.decl(genericName.toTypeName) + if (member.isOverloaded) + abort("Unexpected overloader: " + member.alternatives.map(_.debugLocationString)) + member } else sym diff --git a/src/reflect/scala/reflect/internal/Scopes.scala b/src/reflect/scala/reflect/internal/Scopes.scala index a893db74f2c3..b24702da475b 100644 --- a/src/reflect/scala/reflect/internal/Scopes.scala +++ b/src/reflect/scala/reflect/internal/Scopes.scala @@ -309,26 +309,39 @@ trait Scopes extends api.Scopes { self: SymbolTable => null } + private def hasName(sym: Symbol, name: Name, phaseFlatClasses: Boolean) = { + if (phaseFlatClasses) + sym.name eq name + else + sym.rawname eq name // opt: avoid calls to Symbol.needsFlatClasses inside the loops below + } + private def hasSameName(sym1: Symbol, sym2: Symbol, phaseFlatClasses: Boolean) = { + if (phaseFlatClasses) + sym1.name eq sym2.name + else + sym1.rawname eq sym2.rawname // opt: avoid calls to Symbol.needsFlatClasses inside the loops below + } + /** lookup a symbol entry matching given name. * @note from Martin: I believe this is a hotspot or will be one * in future versions of the type system. I have reverted the previous * change to use iterators as too costly. */ def lookupEntry(name: Name): ScopeEntry = { - val startTime = if (StatisticsStatics.areSomeColdStatsEnabled) statistics.startTimer(statistics.scopeLookupTime) else null var e: ScopeEntry = null + val phaseFlatClasses = phase.flatClasses + if (hashtable ne null) { e = hashtable(name.start & HASHMASK) - while ((e ne null) && (e.sym.name ne name)) { + while ((e ne null) && !hasName(e.sym, name, phaseFlatClasses)) { e = e.tail } } else { e = elems - while ((e ne null) && (e.sym.name ne name)) { + while ((e ne null) && !hasName(e.sym, name, phaseFlatClasses)) { e = e.next } } - if (StatisticsStatics.areSomeColdStatsEnabled) statistics.stopTimer(statistics.scopeLookupTime, startTime) e } @@ -339,10 +352,12 @@ trait Scopes extends api.Scopes { self: SymbolTable => */ def lookupNextEntry(entry: ScopeEntry): ScopeEntry = { var e = entry + val phaseFlatClasses = phase.flatClasses + if (hashtable ne null) - do { e = e.tail } while ((e ne null) && e.sym.name != entry.sym.name) + do { e = e.tail } while ((e ne null) && !hasSameName(e.sym, entry.sym, phaseFlatClasses)) else - do { e = e.next } while ((e ne null) && e.sym.name != entry.sym.name) + do { e = e.next } while ((e ne null) && !hasSameName(e.sym, entry.sym, phaseFlatClasses)) e } @@ -523,5 +538,4 @@ trait ScopeStats { self: Statistics => val scopeCountView = newView("#created scopes")(symbolTable.scopeCount) val scopePopulationTime = newTimer("time spent in scope population") - val scopeLookupTime = newTimer("time spent in scope lookup") } diff --git a/src/reflect/scala/reflect/internal/Symbols.scala b/src/reflect/scala/reflect/internal/Symbols.scala index 760199ec3560..81d6c598c1bf 100644 --- a/src/reflect/scala/reflect/internal/Symbols.scala +++ b/src/reflect/scala/reflect/internal/Symbols.scala @@ -689,6 +689,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => def isRootSymbol = false // RootPackage and RootClass. TODO: also NoSymbol. def isEmptyPackage = false def isEmptyPackageClass = false + final def isNoSymbol: Boolean = this.isInstanceOf[NoSymbol] /** Is this symbol an effective root for fullname string? */ @@ -841,7 +842,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => final def isDelambdafyFunction = isSynthetic && (name containsName tpnme.DELAMBDAFY_LAMBDA_CLASS_NAME) final def isDelambdafyTarget = isArtifact && isMethod && hasAttachment[DelambdafyTarget.type] final def isDefinedInPackage = effectiveOwner.isPackageClass - final def needsFlatClasses = phase.flatClasses && (rawowner ne NoSymbol) && !rawowner.isPackageClass && !isMethod + final def needsFlatClasses = phase.flatClasses && !rawowner.isNoSymbol && !rawowner.isPackageClass && !isMethod // TODO introduce a flag for these? final def isPatternTypeVariable: Boolean = @@ -2879,8 +2880,8 @@ trait Symbols extends api.Symbols { self: SymbolTable => override def isLocalDummy = nme.isLocalDummyName(name) - override def isClassConstructor = name == nme.CONSTRUCTOR - override def isMixinConstructor = name == nme.MIXIN_CONSTRUCTOR + override def isClassConstructor = rawname == nme.CONSTRUCTOR + override def isMixinConstructor = rawname == nme.MIXIN_CONSTRUCTOR override def isConstructor = isClassConstructor || isMixinConstructor override def isPackageObject = isModule && (name == nme.PACKAGE) diff --git a/src/reflect/scala/reflect/internal/Trees.scala b/src/reflect/scala/reflect/internal/Trees.scala index 3b8628488003..cb2ddf005980 100644 --- a/src/reflect/scala/reflect/internal/Trees.scala +++ b/src/reflect/scala/reflect/internal/Trees.scala @@ -47,9 +47,6 @@ trait Trees extends api.Trees { val id = nodeCount // TODO: add to attachment? nodeCount += 1 - if (StatisticsStatics.areSomeHotStatsEnabled()) - statistics.incCounter(statistics.nodeByType, getClass) - final override def pos: Position = rawatt.pos private[this] var rawtpe: Type = _ @@ -1108,14 +1105,15 @@ trait Trees extends api.Trees { class LazyTreeCopier extends InternalTreeCopierOps { val treeCopy: TreeCopier = newStrictTreeCopier + private def same[T <: AnyRef](as: List[T], bs: List[T]) = sameElementsEquals(as, bs) def ClassDef(tree: Tree, mods: Modifiers, name: Name, tparams: List[TypeDef], impl: Template) = tree match { case t @ ClassDef(mods0, name0, tparams0, impl0) - if (mods0 == mods) && (name0 == name) && (tparams0 == tparams) && (impl0 == impl) => t + if (mods0 == mods) && (name0 == name) && (same(tparams0, tparams)) && (impl0 == impl) => t case _ => treeCopy.ClassDef(tree, mods, name, tparams, impl) } def PackageDef(tree: Tree, pid: RefTree, stats: List[Tree]) = tree match { case t @ PackageDef(pid0, stats0) - if (pid0 == pid) && (stats0 == stats) => t + if (pid0 == pid) && same(stats0, stats) => t case _ => treeCopy.PackageDef(tree, pid, stats) } def ModuleDef(tree: Tree, mods: Modifiers, name: Name, impl: Template) = tree match { @@ -1130,33 +1128,33 @@ trait Trees extends api.Trees { } def DefDef(tree: Tree, mods: Modifiers, name: Name, tparams: List[TypeDef], vparamss: List[List[ValDef]], tpt: Tree, rhs: Tree) = tree match { case t @ DefDef(mods0, name0, tparams0, vparamss0, tpt0, rhs0) - if (mods0 == mods) && (name0 == name) && (tparams0 == tparams) && - (vparamss0 == vparamss) && (tpt0 == tpt) && (rhs == rhs0) => t + if (mods0 == mods) && (name0 == name) && same(tparams0, tparams) && + same(vparamss0, vparamss) && (tpt0 == tpt) && (rhs == rhs0) => t case _ => treeCopy.DefDef(tree, mods, name, tparams, vparamss, tpt, rhs) } def TypeDef(tree: Tree, mods: Modifiers, name: Name, tparams: List[TypeDef], rhs: Tree) = tree match { case t @ TypeDef(mods0, name0, tparams0, rhs0) - if (mods0 == mods) && (name0 == name) && (tparams0 == tparams) && (rhs0 == rhs) => t + if (mods0 == mods) && (name0 == name) && same(tparams0, tparams) && (rhs0 == rhs) => t case _ => treeCopy.TypeDef(tree, mods, name, tparams, rhs) } def LabelDef(tree: Tree, name: Name, params: List[Ident], rhs: Tree) = tree match { case t @ LabelDef(name0, params0, rhs0) - if (name0 == name) && (params0 == params) && (rhs0 == rhs) => t + if (name0 == name) && same(params0, params) && (rhs0 == rhs) => t case _ => treeCopy.LabelDef(tree, name, params, rhs) } def Import(tree: Tree, expr: Tree, selectors: List[ImportSelector]) = tree match { case t @ Import(expr0, selectors0) - if (expr0 == expr) && (selectors0 == selectors) => t + if (expr0 == expr) && same(selectors0, selectors) => t case _ => treeCopy.Import(tree, expr, selectors) } def Template(tree: Tree, parents: List[Tree], self: ValDef, body: List[Tree]) = tree match { case t @ Template(parents0, self0, body0) - if (parents0 == parents) && (self0 == self) && (body0 == body) => t + if (parents0 == parents) && (self0 == self) && same(body0, body) => t case _ => treeCopy.Template(tree, parents, self, body) } def Block(tree: Tree, stats: List[Tree], expr: Tree) = tree match { case t @ Block(stats0, expr0) - if ((stats0 == stats) && (expr0 == expr)) => t + if (same(stats0, stats) && (expr0 == expr)) => t case _ => treeCopy.Block(tree, stats, expr) } def CaseDef(tree: Tree, pat: Tree, guard: Tree, body: Tree) = tree match { @@ -1166,7 +1164,7 @@ trait Trees extends api.Trees { } def Alternative(tree: Tree, trees: List[Tree]) = tree match { case t @ Alternative(trees0) - if trees0 == trees => t + if same(trees0, trees) => t case _ => treeCopy.Alternative(tree, trees) } def Star(tree: Tree, elem: Tree) = tree match { @@ -1181,17 +1179,17 @@ trait Trees extends api.Trees { } def UnApply(tree: Tree, fun: Tree, args: List[Tree]) = tree match { case t @ UnApply(fun0, args0) - if (fun0 == fun) && (args0 == args) => t + if (fun0 == fun) && same(args0, args) => t case _ => treeCopy.UnApply(tree, fun, args) } def ArrayValue(tree: Tree, elemtpt: Tree, trees: List[Tree]) = tree match { case t @ ArrayValue(elemtpt0, trees0) - if (elemtpt0 == elemtpt) && (trees0 == trees) => t + if (elemtpt0 == elemtpt) && same(trees0, trees) => t case _ => treeCopy.ArrayValue(tree, elemtpt, trees) } def Function(tree: Tree, vparams: List[ValDef], body: Tree) = tree match { case t @ Function(vparams0, body0) - if (vparams0 == vparams) && (body0 == body) => t + if same(vparams0, vparams) && (body0 == body) => t case _ => treeCopy.Function(tree, vparams, body) } def Assign(tree: Tree, lhs: Tree, rhs: Tree) = tree match { @@ -1211,7 +1209,7 @@ trait Trees extends api.Trees { } def Match(tree: Tree, selector: Tree, cases: List[CaseDef]) = tree match { case t @ Match(selector0, cases0) - if (selector0 == selector) && (cases0 == cases) => t + if (selector0 == selector) && same(cases0, cases) => t case _ => treeCopy.Match(tree, selector, cases) } def Return(tree: Tree, expr: Tree) = tree match { @@ -1221,7 +1219,7 @@ trait Trees extends api.Trees { } def Try(tree: Tree, block: Tree, catches: List[CaseDef], finalizer: Tree) = tree match { case t @ Try(block0, catches0, finalizer0) - if (block0 == block) && (catches0 == catches) && (finalizer0 == finalizer) => t + if (block0 == block) && same(catches0, catches) && (finalizer0 == finalizer) => t case _ => treeCopy.Try(tree, block, catches, finalizer) } def Throw(tree: Tree, expr: Tree) = tree match { @@ -1241,17 +1239,17 @@ trait Trees extends api.Trees { } def TypeApply(tree: Tree, fun: Tree, args: List[Tree]) = tree match { case t @ TypeApply(fun0, args0) - if (fun0 == fun) && (args0 == args) => t + if (fun0 == fun) && same(args0, args) => t case _ => treeCopy.TypeApply(tree, fun, args) } def Apply(tree: Tree, fun: Tree, args: List[Tree]) = tree match { case t @ Apply(fun0, args0) - if (fun0 == fun) && (args0 == args) => t + if (fun0 == fun) && same(args0, args) => t case _ => treeCopy.Apply(tree, fun, args) } def ApplyDynamic(tree: Tree, qual: Tree, args: List[Tree]) = tree match { case t @ ApplyDynamic(qual0, args0) - if (qual0 == qual) && (args0 == args) => t + if (qual0 == qual) && same(args0, args) => t case _ => treeCopy.ApplyDynamic(tree, qual, args) } def Super(tree: Tree, qual: Tree, mix: TypeName) = tree match { @@ -1315,7 +1313,7 @@ trait Trees extends api.Trees { } def AppliedTypeTree(tree: Tree, tpt: Tree, args: List[Tree]) = tree match { case t @ AppliedTypeTree(tpt0, args0) - if (tpt0 == tpt) && (args0 == args) => t + if (tpt0 == tpt) && same(args0, args) => t case _ => treeCopy.AppliedTypeTree(tree, tpt, args) } def TypeBoundsTree(tree: Tree, lo: Tree, hi: Tree) = tree match { @@ -1325,7 +1323,7 @@ trait Trees extends api.Trees { } def ExistentialTypeTree(tree: Tree, tpt: Tree, whereClauses: List[MemberDef]) = tree match { case t @ ExistentialTypeTree(tpt0, whereClauses0) - if (tpt0 == tpt) && (whereClauses0 == whereClauses) => t + if (tpt0 == tpt) && same(whereClauses0, whereClauses) => t case _ => treeCopy.ExistentialTypeTree(tree, tpt, whereClauses) } } @@ -2053,7 +2051,6 @@ trait TreesStats { self: Statistics => val symbolTable: SymbolTable val treeNodeCount = newView("#created tree nodes")(symbolTable.nodeCount) - val nodeByType = newByClass("#created tree nodes by type")(newCounter("")) val retainedCount = newCounter("#retained tree nodes") val retainedByType = newByClass("#retained tree nodes by type")(newCounter("")) } diff --git a/src/reflect/scala/reflect/internal/Types.scala b/src/reflect/scala/reflect/internal/Types.scala index f5cd258e51e8..57a1bee7efa4 100644 --- a/src/reflect/scala/reflect/internal/Types.scala +++ b/src/reflect/scala/reflect/internal/Types.scala @@ -4024,7 +4024,7 @@ trait Types // Optimization to avoid creating unnecessary new typerefs. def copyTypeRef(tp: Type, pre: Type, sym: Symbol, args: List[Type]): Type = tp match { - case TypeRef(pre0, sym0, _) if pre == pre0 && sym0.name == sym.name => + case TypeRef(pre0, sym0, _) if pre == pre0 && sym0.rawname == sym.rawname => if (sym.isAliasType && sameLength(sym.info.typeParams, args) && !sym.lockOK) throw new RecoverableCyclicReference(sym)