Skip to content
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

Assorted compiler optimizations #6209

Merged
merged 6 commits into from
Mar 21, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/compiler/scala/tools/nsc/CompilationUnits.scala
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ trait CompilationUnits { global: Global =>
/** Synthetic definitions generated by namer, eliminated by typer.
*/
object synthetics {
private val map = mutable.HashMap[Symbol, Tree]()
private val map = mutable.AnyRefMap[Symbol, Tree]()
def update(sym: Symbol, tree: Tree) {
debuglog(s"adding synthetic ($sym, $tree) to $self")
map.update(sym, tree)
Expand Down
4 changes: 2 additions & 2 deletions src/compiler/scala/tools/nsc/Global.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1127,10 +1127,10 @@ class Global(var currentSettings: Settings, var reporter: Reporter)
val compiledFiles = new mutable.HashSet[String]

/** A map from compiled top-level symbols to their source files */
val symSource = new mutable.HashMap[Symbol, AbstractFile]
val symSource = new mutable.AnyRefMap[Symbol, AbstractFile]

/** A map from compiled top-level symbols to their picklers */
val symData = new mutable.HashMap[Symbol, PickleBuffer]
val symData = new mutable.AnyRefMap[Symbol, PickleBuffer]

private var phasec: Int = 0 // phases completed
private var unitc: Int = 0 // units completed this phase
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -324,8 +324,11 @@ abstract class BackendUtils extends PerRunInit {
bTypesFromClassfile.classBTypeFromParsedClassfile(internalName).info.get.nestedClasses.force

def getClassIfNested(internalName: InternalName): Option[ClassBType] = {
val c = bTypesFromClassfile.classBTypeFromParsedClassfile(internalName)
if (c.isNestedClass.get) Some(c) else None
if (internalName.indexOf('$') < 0) None
else {
val c = bTypesFromClassfile.classBTypeFromParsedClassfile(internalName)
if (c.isNestedClass.get) Some(c) else None
}
}

def raiseError(msg: String, sig: String, e: Option[Throwable]): Unit = {
Expand Down Expand Up @@ -758,6 +761,15 @@ object BackendUtils {
private def skipUntil(isDelimiter: CharBooleanFunction): Unit = {
while (!isDelimiter(current)) { index += 1 }
}
private def skipUntilDelimiter(delimiter: Char): Unit = {
sig.indexOf(delimiter, index) match {
case -1 =>
raiseError(s"Out of bounds", sig)
abort() // Don't continue, even if `notifyInvalidSignature` returns
case i =>
index = i
}
}

private def appendUntil(builder: java.lang.StringBuilder, isDelimiter: CharBooleanFunction): Unit = {
val start = index
Expand Down Expand Up @@ -801,7 +813,7 @@ object BackendUtils {
accept(';')

case 'T' =>
skipUntil(_ == ';')
skipUntilDelimiter(';')
skip()

case '[' =>
Expand All @@ -812,7 +824,7 @@ object BackendUtils {
private def typeParameters(): Unit = if (current == '<') {
skip()
while (current != '>') {
skipUntil(_ == ':'); skip()
skipUntilDelimiter(':'); skip()
val c = current
// The ClassBound can be missing, but only if there's an InterfaceBound after.
// This is an assumption that's not in the spec, see https://stackoverflow.com/q/44284928
Expand Down
2 changes: 1 addition & 1 deletion src/compiler/scala/tools/nsc/typechecker/Implicits.scala
Original file line number Diff line number Diff line change
Expand Up @@ -575,7 +575,7 @@ trait Implicits {
var ps = params
var as = args
if (fast) {
while (ps.nonEmpty && as.nonEmpty) {
while (!(ps.isEmpty || as.isEmpty)) {
if (!isPlausiblySubType(as.head, ps.head.tpe))
return false
ps = ps.tail
Expand Down
2 changes: 1 addition & 1 deletion src/compiler/scala/tools/nsc/typechecker/Typers.scala
Original file line number Diff line number Diff line change
Expand Up @@ -828,7 +828,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
* If all this fails, error
*/
protected def adapt(tree: Tree, mode: Mode, pt: Type, original: Tree = EmptyTree): Tree = {
def hasUndets = context.undetparams.nonEmpty
def hasUndets = !context.undetparams.isEmpty
def hasUndetsInMonoMode = hasUndets && !mode.inPolyMode

def adaptToImplicitMethod(mt: MethodType): Tree = {
Expand Down
10 changes: 10 additions & 0 deletions src/library/scala/collection/IndexedSeqOptimized.scala
Original file line number Diff line number Diff line change
Expand Up @@ -276,5 +276,15 @@ trait IndexedSeqOptimized[+A, +Repr] extends Any with IndexedSeqLike[A, Repr] {
case _ =>
super.endsWith(that)
}

override def toList: List[A] = {
var i = length - 1
var result: List[A] = Nil
while (i >= 0) {
result ::= apply(i)
i -= 1
}
result
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cc @szeiger - does that need to be ported to collection-strawman? i couldn't find WrappedArray there.

To avoid the reversed iteration order, we could use a version that mutates ::.tl

  override def toList: List[A] = {
    if (length == 0) Nil
    else {
      val res = immutable.::(apply(0), Nil)
      var cur = res
      var i = 1
      while (i < length) {
        val next = immutable.::(apply(i), Nil)
        cur.tl = next
        cur = next
        i += 1
      }
      res
    }
  }

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

probably local val length as well

}

8 changes: 4 additions & 4 deletions src/reflect/scala/reflect/internal/Definitions.scala
Original file line number Diff line number Diff line change
Expand Up @@ -394,10 +394,10 @@ trait Definitions extends api.StandardDefinitions {
def isCastSymbol(sym: Symbol) = sym == Any_asInstanceOf || sym == Object_asInstanceOf

def isJavaVarArgsMethod(m: Symbol) = m.isMethod && isJavaVarArgs(m.info.params)
def isJavaVarArgs(params: Seq[Symbol]) = params.nonEmpty && isJavaRepeatedParamType(params.last.tpe)
def isScalaVarArgs(params: Seq[Symbol]) = params.nonEmpty && isScalaRepeatedParamType(params.last.tpe)
def isVarArgsList(params: Seq[Symbol]) = params.nonEmpty && isRepeatedParamType(params.last.tpe)
def isVarArgTypes(formals: Seq[Type]) = formals.nonEmpty && isRepeatedParamType(formals.last)
def isJavaVarArgs(params: Seq[Symbol]) = !params.isEmpty && isJavaRepeatedParamType(params.last.tpe)
def isScalaVarArgs(params: Seq[Symbol]) = !params.isEmpty && isScalaRepeatedParamType(params.last.tpe)
def isVarArgsList(params: Seq[Symbol]) = !params.isEmpty && isRepeatedParamType(params.last.tpe)
def isVarArgTypes(formals: Seq[Type]) = !formals.isEmpty && isRepeatedParamType(formals.last)

def firstParamType(tpe: Type): Type = tpe.paramTypes match {
case p :: _ => p
Expand Down
3 changes: 0 additions & 3 deletions src/reflect/scala/reflect/internal/SymbolTable.scala
Original file line number Diff line number Diff line change
Expand Up @@ -188,8 +188,6 @@ abstract class SymbolTable extends macros.Universe

final def atPhaseStack: List[Phase] = List.tabulate(phStackIndex)(i => phStack(i))
final def phase: Phase = {
if (StatisticsStatics.areSomeColdStatsEnabled)
statistics.incCounter(statistics.phaseCounter)
ph
}

Expand Down Expand Up @@ -445,7 +443,6 @@ abstract class SymbolTable extends macros.Universe
trait SymbolTableStats {
self: TypesStats with Statistics =>

val phaseCounter = newCounter("#phase calls")
// Defined here because `SymbolLoaders` is defined in `scala.tools.nsc`
// and only has access to the `statistics` definition from `scala.reflect`.
val classReadNanos = newSubTimer("time classfilereading", typerNanos)
Expand Down
13 changes: 1 addition & 12 deletions src/reflect/scala/reflect/internal/Symbols.scala
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
* The original owner of a symbol is needed in some places in the backend. Ideally, owners should
* be versioned like the type history.
*/
private val originalOwnerMap = perRunCaches.newMap[Symbol, Symbol]()
private val originalOwnerMap = perRunCaches.newAnyRefMap[Symbol, Symbol]()

// TODO - don't allow the owner to be changed without checking invariants, at least
// when under some flag. Define per-phase invariants for owner/owned relationships,
Expand Down Expand Up @@ -767,7 +767,6 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
}

final def flags: Long = {
if (StatisticsStatics.areSomeColdStatsEnabled) statistics.incCounter(flagsCount)
val fs = _rawflags & phase.flagMask
(fs | ((fs & LateFlags) >>> LateShift)) & ~((fs & AntiFlags) >>> AntiShift)
}
Expand Down Expand Up @@ -1197,7 +1196,6 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
* `assertOwner` aborts compilation immediately if called on NoSymbol.
*/
def owner: Symbol = {
if (StatisticsStatics.areSomeColdStatsEnabled) statistics.incCounter(ownerCount)
rawowner
}
final def safeOwner: Symbol = if (this eq NoSymbol) NoSymbol else owner
Expand Down Expand Up @@ -2766,7 +2764,6 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
private[this] var _rawname: TermName = initName
def rawname = _rawname
def name = {
if (StatisticsStatics.areSomeColdStatsEnabled) statistics.incCounter(nameCount)
_rawname
}
override def name_=(name: Name) {
Expand Down Expand Up @@ -2900,13 +2897,11 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
override def moduleClass = referenced

override def owner = {
if (StatisticsStatics.areSomeColdStatsEnabled) statistics.incCounter(ownerCount)
// a non-static module symbol gets the METHOD flag in uncurry's info transform -- see isModuleNotMethod
if (!isMethod && needsFlatClasses) rawowner.owner
else rawowner
}
override def name: TermName = {
if (StatisticsStatics.areSomeColdStatsEnabled) statistics.incCounter(nameCount)
if (!isMethod && needsFlatClasses) {
if (flatname eq null)
flatname = nme.flattenedName(rawowner.name, rawname)
Expand Down Expand Up @@ -3038,7 +3033,6 @@ trait Symbols extends api.Symbols { self: SymbolTable =>

def rawname = _rawname
def name = {
if (StatisticsStatics.areSomeColdStatsEnabled) statistics.incCounter(nameCount)
_rawname
}
final def asNameType(n: Name) = n.toTypeName
Expand Down Expand Up @@ -3325,12 +3319,10 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
}

override def owner: Symbol = {
if (StatisticsStatics.areSomeColdStatsEnabled) statistics.incCounter(ownerCount)
if (needsFlatClasses) rawowner.owner else rawowner
}

override def name: TypeName = {
if (StatisticsStatics.areSomeColdStatsEnabled) statistics.incCounter(nameCount)
if (needsFlatClasses) {
if (flatname eq null)
flatname = tpnme.flattenedName(rawowner.name, rawname)
Expand Down Expand Up @@ -3744,7 +3736,4 @@ trait SymbolsStats {
val symbolsCount = newView("#symbols")(symbolTable.getCurrentSymbolIdCount)
val typeSymbolCount = newCounter("#type symbols")
val classSymbolCount = newCounter("#class symbols")
val flagsCount = newCounter("#flags ops")
val ownerCount = newCounter("#owner ops")
val nameCount = newCounter("#name ops")
}
4 changes: 2 additions & 2 deletions src/reflect/scala/reflect/internal/Types.scala
Original file line number Diff line number Diff line change
Expand Up @@ -410,7 +410,7 @@ trait Types
/** For a class with nonEmpty parents, the first parent.
* Otherwise some specific fixed top type.
*/
def firstParent = if (parents.nonEmpty) parents.head else ObjectTpe
def firstParent = if (!parents.isEmpty) parents.head else ObjectTpe

/** For a typeref or single-type, the prefix of the normalized type (@see normalize).
* NoType for all other types. */
Expand Down Expand Up @@ -4005,7 +4005,7 @@ trait Types
def typeParamsToExistentials(clazz: Symbol): List[Symbol] =
typeParamsToExistentials(clazz, clazz.typeParams)

def isRawIfWithoutArgs(sym: Symbol) = sym.isClass && sym.typeParams.nonEmpty && sym.isJavaDefined
def isRawIfWithoutArgs(sym: Symbol) = sym.isClass && !sym.typeParams.isEmpty && sym.isJavaDefined
/** Is type tp a ''raw type''? */
// note: it's important to write the two tests in this order,
// as only typeParams forces the classfile to be read. See #400
Expand Down