Skip to content

Faster/2019 march todo 2 #42

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 8 commits into
base: 2.13.x
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/compiler/scala/tools/nsc/Global.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
20 changes: 16 additions & 4 deletions src/compiler/scala/tools/nsc/typechecker/Infer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Expand Down
3 changes: 3 additions & 0 deletions src/reflect/scala/reflect/internal/Definitions.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
28 changes: 21 additions & 7 deletions src/reflect/scala/reflect/internal/Scopes.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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
}

Expand All @@ -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
}

Expand Down Expand Up @@ -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")
}
7 changes: 4 additions & 3 deletions src/reflect/scala/reflect/internal/Symbols.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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?
*/
Expand Down Expand Up @@ -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 =
Expand Down Expand Up @@ -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)
Expand Down
45 changes: 21 additions & 24 deletions src/reflect/scala/reflect/internal/Trees.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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 = _
Expand Down Expand Up @@ -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 {
Expand All @@ -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 {
Expand All @@ -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 {
Expand All @@ -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 {
Expand All @@ -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 {
Expand All @@ -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 {
Expand All @@ -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 {
Expand Down Expand Up @@ -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 {
Expand All @@ -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)
}
}
Expand Down Expand Up @@ -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(""))
}
2 changes: 1 addition & 1 deletion src/reflect/scala/reflect/internal/Types.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand Down