summaryrefslogtreecommitdiff
path: root/src/compiler
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2012-04-18 12:22:59 +0100
committerPaul Phillips <paulp@improving.org>2012-04-18 14:59:22 +0100
commit016bc3db52d6f1ffa3ef2285d5801f82f5f49167 (patch)
tree0915586ab8fe0f4019245e655f5f31e9d83649c3 /src/compiler
parent8a285258fdb37af9f4ba8ced0a5c8fb6fefbf62c (diff)
downloadscala-016bc3db52d6f1ffa3ef2285d5801f82f5f49167.tar.gz
scala-016bc3db52d6f1ffa3ef2285d5801f82f5f49167.tar.bz2
scala-016bc3db52d6f1ffa3ef2285d5801f82f5f49167.zip
Minor optimizations with nested list operations.
I also tried transforming a comment into an assertion and to my shock and happy surprise everything still worked. Let's express those preconditions in code when we can, mmm?
Diffstat (limited to 'src/compiler')
-rw-r--r--src/compiler/scala/reflect/internal/Definitions.scala2
-rw-r--r--src/compiler/scala/reflect/internal/Importers.scala2
-rw-r--r--src/compiler/scala/reflect/internal/Symbols.scala17
-rw-r--r--src/compiler/scala/reflect/internal/util/Collections.scala15
-rw-r--r--src/compiler/scala/tools/nsc/ast/Trees.scala22
-rw-r--r--src/compiler/scala/tools/nsc/interpreter/MemberHandlers.scala2
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Duplicators.scala2
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Macros.scala6
8 files changed, 42 insertions, 26 deletions
diff --git a/src/compiler/scala/reflect/internal/Definitions.scala b/src/compiler/scala/reflect/internal/Definitions.scala
index 3150b674af..7353e69ab6 100644
--- a/src/compiler/scala/reflect/internal/Definitions.scala
+++ b/src/compiler/scala/reflect/internal/Definitions.scala
@@ -120,7 +120,7 @@ trait Definitions extends reflect.api.StandardDefinitions {
numericWeight contains sym
def isGetClass(sym: Symbol) =
- (sym.name == nme.getClass_) && (sym.paramss.isEmpty || sym.paramss.head.isEmpty)
+ (sym.name == nme.getClass_) && flattensToEmpty(sym.paramss)
lazy val UnitClass = valueCache(tpnme.Unit)
lazy val ByteClass = valueCache(tpnme.Byte)
diff --git a/src/compiler/scala/reflect/internal/Importers.scala b/src/compiler/scala/reflect/internal/Importers.scala
index 596d400628..8404386e10 100644
--- a/src/compiler/scala/reflect/internal/Importers.scala
+++ b/src/compiler/scala/reflect/internal/Importers.scala
@@ -326,7 +326,7 @@ trait Importers { self: SymbolTable =>
case from.ValDef(mods, name, tpt, rhs) =>
new ValDef(importModifiers(mods), importName(name).toTermName, importTree(tpt), importTree(rhs))
case from.DefDef(mods, name, tparams, vparamss, tpt, rhs) =>
- new DefDef(importModifiers(mods), importName(name).toTermName, tparams map importTypeDef, vparamss map (_ map importValDef), importTree(tpt), importTree(rhs))
+ new DefDef(importModifiers(mods), importName(name).toTermName, tparams map importTypeDef, mmap(vparamss)(importValDef), importTree(tpt), importTree(rhs))
case from.TypeDef(mods, name, tparams, rhs) =>
new TypeDef(importModifiers(mods), importName(name).toTypeName, tparams map importTypeDef, importTree(rhs))
case from.LabelDef(name, params, rhs) =>
diff --git a/src/compiler/scala/reflect/internal/Symbols.scala b/src/compiler/scala/reflect/internal/Symbols.scala
index 74e924add4..c9ac929edf 100644
--- a/src/compiler/scala/reflect/internal/Symbols.scala
+++ b/src/compiler/scala/reflect/internal/Symbols.scala
@@ -718,13 +718,8 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
*/
final def isMonomorphicType =
isType && {
- var is = infos
- (is eq null) || {
- while (is.prev ne null) { is = is.prev }
- is.info.isComplete && !is.info.isHigherKinded // was: is.info.typeParams.isEmpty.
- // YourKit listed the call to PolyType.typeParams as a hot spot but it is likely an artefact.
- // The change to isHigherKinded did not reduce the total running time.
- }
+ val info = originalInfo
+ info.isComplete && !info.isHigherKinded
}
def isStrictFP = hasAnnotation(ScalaStrictFPAttr) || (enclClass hasAnnotation ScalaStrictFPAttr)
@@ -1126,6 +1121,14 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
// ------ info and type -------------------------------------------------------------------
private[Symbols] var infos: TypeHistory = null
+ def originalInfo = {
+ if (infos eq null) null
+ else {
+ var is = infos
+ while (is.prev ne null) { is = is.prev }
+ is.info
+ }
+ }
/** Get type. The type of a symbol is:
* for a type symbol, the type corresponding to the symbol itself,
diff --git a/src/compiler/scala/reflect/internal/util/Collections.scala b/src/compiler/scala/reflect/internal/util/Collections.scala
index 9dbf1adeef..9e4ae1ca00 100644
--- a/src/compiler/scala/reflect/internal/util/Collections.scala
+++ b/src/compiler/scala/reflect/internal/util/Collections.scala
@@ -24,18 +24,21 @@ trait Collections {
)
/** All these mm methods are "deep map" style methods for
- * mapping etc. on a list of lists.
+ * mapping etc. on a list of lists while avoiding unnecessary
+ * intermediate structures like those created via flatten.
*/
final def mexists[A](xss: List[List[A]])(p: A => Boolean) =
xss exists (_ exists p)
+ final def mforall[A](xss: List[List[A]])(p: A => Boolean) =
+ xss forall (_ forall p)
final def mmap[A, B](xss: List[List[A]])(f: A => B) =
xss map (_ map f)
final def mforeach[A](xss: List[List[A]])(f: A => Unit) =
xss foreach (_ foreach f)
final def mfind[A](xss: List[List[A]])(p: A => Boolean): Option[A] = {
- for (xs <- xss; x <- xs)
- if (p(x)) return Some(x)
- None
+ var res: Option[A] = null
+ mforeach(xss)(x => if ((res eq null) && p(x)) res = Some(x))
+ if (res eq null) None else res
}
final def mfilter[A](xss: List[List[A]])(p: A => Boolean) =
for (xs <- xss; x <- xs; if p(x)) yield x
@@ -66,6 +69,10 @@ trait Collections {
}
lb.toList
}
+
+ @tailrec final def flattensToEmpty(xss: Seq[Seq[_]]): Boolean = {
+ xss.isEmpty || xss.head.isEmpty && flattensToEmpty(xss.tail)
+ }
final def foreachWithIndex[A, B](xs: List[A])(f: (A, Int) => Unit) {
var index = 0
diff --git a/src/compiler/scala/tools/nsc/ast/Trees.scala b/src/compiler/scala/tools/nsc/ast/Trees.scala
index 04452c68e5..2bd1ba3fea 100644
--- a/src/compiler/scala/tools/nsc/ast/Trees.scala
+++ b/src/compiler/scala/tools/nsc/ast/Trees.scala
@@ -86,13 +86,12 @@ trait Trees extends reflect.internal.Trees { self: Global =>
/* Add constructor to template */
// create parameters for <init> as synthetic trees.
- var vparamss1 =
- vparamss map (vps => vps.map { vd =>
- atPos(vd.pos.focus) {
- ValDef(
- Modifiers(vd.mods.flags & (IMPLICIT | DEFAULTPARAM | BYNAMEPARAM) | PARAM | PARAMACCESSOR) withAnnotations vd.mods.annotations,
- vd.name, vd.tpt.duplicate, vd.rhs.duplicate)
- }})
+ var vparamss1 = mmap(vparamss) { vd =>
+ atPos(vd.pos.focus) {
+ val mods = Modifiers(vd.mods.flags & (IMPLICIT | DEFAULTPARAM | BYNAMEPARAM) | PARAM | PARAMACCESSOR)
+ ValDef(mods withAnnotations vd.mods.annotations, vd.name, vd.tpt.duplicate, vd.rhs.duplicate)
+ }
+ }
val (edefs, rest) = body span treeInfo.isEarlyDef
val (evdefs, etdefs) = edefs partition treeInfo.isEarlyValDef
val gvdefs = evdefs map {
@@ -143,11 +142,18 @@ trait Trees extends reflect.internal.Trees { self: Global =>
* @param body the template statements without primary constructor
* and value parameter fields.
*/
- def ClassDef(sym: Symbol, constrMods: Modifiers, vparamss: List[List[ValDef]], argss: List[List[Tree]], body: List[Tree], superPos: Position): ClassDef =
+ def ClassDef(sym: Symbol, constrMods: Modifiers, vparamss: List[List[ValDef]], argss: List[List[Tree]], body: List[Tree], superPos: Position): ClassDef = {
+ // "if they have symbols they should be owned by `sym`"
+ assert(
+ mforall(vparamss)(p => (p.symbol eq NoSymbol) || (p.symbol.owner == sym)),
+ ((mmap(vparamss)(_.symbol), sym))
+ )
+
ClassDef(sym,
Template(sym.info.parents map TypeTree,
if (sym.thisSym == sym || phase.erasedTypes) emptyValDef else ValDef(sym.thisSym),
constrMods, vparamss, argss, body, superPos))
+ }
// --- subcomponents --------------------------------------------------
diff --git a/src/compiler/scala/tools/nsc/interpreter/MemberHandlers.scala b/src/compiler/scala/tools/nsc/interpreter/MemberHandlers.scala
index fcede04aaf..a29eb3ac6d 100644
--- a/src/compiler/scala/tools/nsc/interpreter/MemberHandlers.scala
+++ b/src/compiler/scala/tools/nsc/interpreter/MemberHandlers.scala
@@ -124,7 +124,7 @@ trait MemberHandlers {
private def vparamss = member.vparamss
private def isMacro = member.mods.hasFlag(scala.reflect.internal.Flags.MACRO)
// true if not a macro and 0-arity
- override def definesValue = !isMacro && (vparamss.isEmpty || vparamss.head.isEmpty && vparamss.tail.isEmpty)
+ override def definesValue = !isMacro && flattensToEmpty(vparamss)
override def resultExtractionCode(req: Request) =
if (mods.isPublic) codegenln(name, ": ", req.typeOf(name)) else ""
}
diff --git a/src/compiler/scala/tools/nsc/typechecker/Duplicators.scala b/src/compiler/scala/tools/nsc/typechecker/Duplicators.scala
index f6d1e42c32..2574a1d241 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Duplicators.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Duplicators.scala
@@ -186,7 +186,7 @@ abstract class Duplicators extends Analyzer {
oldClassOwner = oldThis
newClassOwner = newThis
invalidate(ddef.tparams)
- for (vdef <- ddef.vparamss.flatten) {
+ mforeach(ddef.vparamss) { vdef =>
invalidate(vdef)
vdef.tpe = null
}
diff --git a/src/compiler/scala/tools/nsc/typechecker/Macros.scala b/src/compiler/scala/tools/nsc/typechecker/Macros.scala
index 539ddfb19c..da32e638d3 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Macros.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Macros.scala
@@ -76,7 +76,7 @@ trait Macros { self: Analyzer =>
case ThisType(sym) if sym == macroDef.owner =>
SingleType(SingleType(SingleType(NoPrefix, paramsCtx(0)), MacroContextPrefix), ExprValue)
case SingleType(NoPrefix, sym) =>
- vparamss.flatten.find(_.symbol == sym) match {
+ mfind(vparamss)(_.symbol == sym) match {
case Some(macroDefParam) =>
SingleType(SingleType(NoPrefix, param(macroDefParam)), ExprValue)
case _ =>
@@ -121,7 +121,7 @@ trait Macros { self: Analyzer =>
val paramsCtx = List(ctxParam)
val paramsThis = List(makeParam(nme.macroThis, macroDef.pos, implType(false, ownerTpe), SYNTHETIC))
val paramsTparams = tparams map param
- val paramssParams = vparamss map (_ map param)
+ val paramssParams = mmap(vparamss)(param)
var paramsss = List[List[List[Symbol]]]()
// tparams are no longer part of a signature, they get into macro implementations via context bounds
@@ -544,7 +544,7 @@ trait Macros { self: Analyzer =>
def unsigma(tpe: Type): Type = {
// unfortunately, we cannot dereference ``paramss'', because we're in the middle of inferring a type for ``macroDef''
// val defParamss = macroDef.paramss
- val defParamss = macroDdef.vparamss map (_ map (_.symbol))
+ val defParamss = mmap(macroDdef.vparamss)(_.symbol)
var implParamss = macroImpl.paramss
implParamss = transformTypeTagEvidenceParams(implParamss, (param, tparam) => None)