Skip to content

Commit

Permalink
Merge pull request #6209 from retronym/faster/december
Browse files Browse the repository at this point in the history
Assorted compiler optimizations
  • Loading branch information
retronym committed Mar 21, 2018
2 parents 5fb9420 + b175218 commit 0170e73
Show file tree
Hide file tree
Showing 9 changed files with 38 additions and 16 deletions.
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 @@ -1121,10 +1121,10 @@ class Global(var currentSettings: Settings, reporter0: 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 @@ -328,8 +328,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 @@ -771,6 +774,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 @@ -814,7 +826,7 @@ object BackendUtils {
accept(';')

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

case '[' =>
Expand All @@ -825,7 +837,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 @@ -592,7 +592,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 @@ -833,7 +833,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
* and should not be used otherwise. TODO: can it be replaced with a tree attachment?
*/
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
}
}

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
2 changes: 1 addition & 1 deletion 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
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 @@ -409,7 +409,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 @@ -4054,7 +4054,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

0 comments on commit 0170e73

Please sign in to comment.