Skip to content

Commit 016bc3d

Browse files
committed
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?
1 parent 8a28525 commit 016bc3d

File tree

8 files changed

+42
-26
lines changed

8 files changed

+42
-26
lines changed

src/compiler/scala/reflect/internal/Definitions.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ trait Definitions extends reflect.api.StandardDefinitions {
120120
numericWeight contains sym
121121

122122
def isGetClass(sym: Symbol) =
123-
(sym.name == nme.getClass_) && (sym.paramss.isEmpty || sym.paramss.head.isEmpty)
123+
(sym.name == nme.getClass_) && flattensToEmpty(sym.paramss)
124124

125125
lazy val UnitClass = valueCache(tpnme.Unit)
126126
lazy val ByteClass = valueCache(tpnme.Byte)

src/compiler/scala/reflect/internal/Importers.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -326,7 +326,7 @@ trait Importers { self: SymbolTable =>
326326
case from.ValDef(mods, name, tpt, rhs) =>
327327
new ValDef(importModifiers(mods), importName(name).toTermName, importTree(tpt), importTree(rhs))
328328
case from.DefDef(mods, name, tparams, vparamss, tpt, rhs) =>
329-
new DefDef(importModifiers(mods), importName(name).toTermName, tparams map importTypeDef, vparamss map (_ map importValDef), importTree(tpt), importTree(rhs))
329+
new DefDef(importModifiers(mods), importName(name).toTermName, tparams map importTypeDef, mmap(vparamss)(importValDef), importTree(tpt), importTree(rhs))
330330
case from.TypeDef(mods, name, tparams, rhs) =>
331331
new TypeDef(importModifiers(mods), importName(name).toTypeName, tparams map importTypeDef, importTree(rhs))
332332
case from.LabelDef(name, params, rhs) =>

src/compiler/scala/reflect/internal/Symbols.scala

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -718,13 +718,8 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
718718
*/
719719
final def isMonomorphicType =
720720
isType && {
721-
var is = infos
722-
(is eq null) || {
723-
while (is.prev ne null) { is = is.prev }
724-
is.info.isComplete && !is.info.isHigherKinded // was: is.info.typeParams.isEmpty.
725-
// YourKit listed the call to PolyType.typeParams as a hot spot but it is likely an artefact.
726-
// The change to isHigherKinded did not reduce the total running time.
727-
}
721+
val info = originalInfo
722+
info.isComplete && !info.isHigherKinded
728723
}
729724

730725
def isStrictFP = hasAnnotation(ScalaStrictFPAttr) || (enclClass hasAnnotation ScalaStrictFPAttr)
@@ -1126,6 +1121,14 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
11261121
// ------ info and type -------------------------------------------------------------------
11271122

11281123
private[Symbols] var infos: TypeHistory = null
1124+
def originalInfo = {
1125+
if (infos eq null) null
1126+
else {
1127+
var is = infos
1128+
while (is.prev ne null) { is = is.prev }
1129+
is.info
1130+
}
1131+
}
11291132

11301133
/** Get type. The type of a symbol is:
11311134
* for a type symbol, the type corresponding to the symbol itself,

src/compiler/scala/reflect/internal/util/Collections.scala

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,18 +24,21 @@ trait Collections {
2424
)
2525

2626
/** All these mm methods are "deep map" style methods for
27-
* mapping etc. on a list of lists.
27+
* mapping etc. on a list of lists while avoiding unnecessary
28+
* intermediate structures like those created via flatten.
2829
*/
2930
final def mexists[A](xss: List[List[A]])(p: A => Boolean) =
3031
xss exists (_ exists p)
32+
final def mforall[A](xss: List[List[A]])(p: A => Boolean) =
33+
xss forall (_ forall p)
3134
final def mmap[A, B](xss: List[List[A]])(f: A => B) =
3235
xss map (_ map f)
3336
final def mforeach[A](xss: List[List[A]])(f: A => Unit) =
3437
xss foreach (_ foreach f)
3538
final def mfind[A](xss: List[List[A]])(p: A => Boolean): Option[A] = {
36-
for (xs <- xss; x <- xs)
37-
if (p(x)) return Some(x)
38-
None
39+
var res: Option[A] = null
40+
mforeach(xss)(x => if ((res eq null) && p(x)) res = Some(x))
41+
if (res eq null) None else res
3942
}
4043
final def mfilter[A](xss: List[List[A]])(p: A => Boolean) =
4144
for (xs <- xss; x <- xs; if p(x)) yield x
@@ -66,6 +69,10 @@ trait Collections {
6669
}
6770
lb.toList
6871
}
72+
73+
@tailrec final def flattensToEmpty(xss: Seq[Seq[_]]): Boolean = {
74+
xss.isEmpty || xss.head.isEmpty && flattensToEmpty(xss.tail)
75+
}
6976

7077
final def foreachWithIndex[A, B](xs: List[A])(f: (A, Int) => Unit) {
7178
var index = 0

src/compiler/scala/tools/nsc/ast/Trees.scala

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -86,13 +86,12 @@ trait Trees extends reflect.internal.Trees { self: Global =>
8686
/* Add constructor to template */
8787

8888
// create parameters for <init> as synthetic trees.
89-
var vparamss1 =
90-
vparamss map (vps => vps.map { vd =>
91-
atPos(vd.pos.focus) {
92-
ValDef(
93-
Modifiers(vd.mods.flags & (IMPLICIT | DEFAULTPARAM | BYNAMEPARAM) | PARAM | PARAMACCESSOR) withAnnotations vd.mods.annotations,
94-
vd.name, vd.tpt.duplicate, vd.rhs.duplicate)
95-
}})
89+
var vparamss1 = mmap(vparamss) { vd =>
90+
atPos(vd.pos.focus) {
91+
val mods = Modifiers(vd.mods.flags & (IMPLICIT | DEFAULTPARAM | BYNAMEPARAM) | PARAM | PARAMACCESSOR)
92+
ValDef(mods withAnnotations vd.mods.annotations, vd.name, vd.tpt.duplicate, vd.rhs.duplicate)
93+
}
94+
}
9695
val (edefs, rest) = body span treeInfo.isEarlyDef
9796
val (evdefs, etdefs) = edefs partition treeInfo.isEarlyValDef
9897
val gvdefs = evdefs map {
@@ -143,11 +142,18 @@ trait Trees extends reflect.internal.Trees { self: Global =>
143142
* @param body the template statements without primary constructor
144143
* and value parameter fields.
145144
*/
146-
def ClassDef(sym: Symbol, constrMods: Modifiers, vparamss: List[List[ValDef]], argss: List[List[Tree]], body: List[Tree], superPos: Position): ClassDef =
145+
def ClassDef(sym: Symbol, constrMods: Modifiers, vparamss: List[List[ValDef]], argss: List[List[Tree]], body: List[Tree], superPos: Position): ClassDef = {
146+
// "if they have symbols they should be owned by `sym`"
147+
assert(
148+
mforall(vparamss)(p => (p.symbol eq NoSymbol) || (p.symbol.owner == sym)),
149+
((mmap(vparamss)(_.symbol), sym))
150+
)
151+
147152
ClassDef(sym,
148153
Template(sym.info.parents map TypeTree,
149154
if (sym.thisSym == sym || phase.erasedTypes) emptyValDef else ValDef(sym.thisSym),
150155
constrMods, vparamss, argss, body, superPos))
156+
}
151157

152158
// --- subcomponents --------------------------------------------------
153159

src/compiler/scala/tools/nsc/interpreter/MemberHandlers.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ trait MemberHandlers {
124124
private def vparamss = member.vparamss
125125
private def isMacro = member.mods.hasFlag(scala.reflect.internal.Flags.MACRO)
126126
// true if not a macro and 0-arity
127-
override def definesValue = !isMacro && (vparamss.isEmpty || vparamss.head.isEmpty && vparamss.tail.isEmpty)
127+
override def definesValue = !isMacro && flattensToEmpty(vparamss)
128128
override def resultExtractionCode(req: Request) =
129129
if (mods.isPublic) codegenln(name, ": ", req.typeOf(name)) else ""
130130
}

src/compiler/scala/tools/nsc/typechecker/Duplicators.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,7 @@ abstract class Duplicators extends Analyzer {
186186
oldClassOwner = oldThis
187187
newClassOwner = newThis
188188
invalidate(ddef.tparams)
189-
for (vdef <- ddef.vparamss.flatten) {
189+
mforeach(ddef.vparamss) { vdef =>
190190
invalidate(vdef)
191191
vdef.tpe = null
192192
}

src/compiler/scala/tools/nsc/typechecker/Macros.scala

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ trait Macros { self: Analyzer =>
7676
case ThisType(sym) if sym == macroDef.owner =>
7777
SingleType(SingleType(SingleType(NoPrefix, paramsCtx(0)), MacroContextPrefix), ExprValue)
7878
case SingleType(NoPrefix, sym) =>
79-
vparamss.flatten.find(_.symbol == sym) match {
79+
mfind(vparamss)(_.symbol == sym) match {
8080
case Some(macroDefParam) =>
8181
SingleType(SingleType(NoPrefix, param(macroDefParam)), ExprValue)
8282
case _ =>
@@ -121,7 +121,7 @@ trait Macros { self: Analyzer =>
121121
val paramsCtx = List(ctxParam)
122122
val paramsThis = List(makeParam(nme.macroThis, macroDef.pos, implType(false, ownerTpe), SYNTHETIC))
123123
val paramsTparams = tparams map param
124-
val paramssParams = vparamss map (_ map param)
124+
val paramssParams = mmap(vparamss)(param)
125125

126126
var paramsss = List[List[List[Symbol]]]()
127127
// tparams are no longer part of a signature, they get into macro implementations via context bounds
@@ -544,7 +544,7 @@ trait Macros { self: Analyzer =>
544544
def unsigma(tpe: Type): Type = {
545545
// unfortunately, we cannot dereference ``paramss'', because we're in the middle of inferring a type for ``macroDef''
546546
// val defParamss = macroDef.paramss
547-
val defParamss = macroDdef.vparamss map (_ map (_.symbol))
547+
val defParamss = mmap(macroDdef.vparamss)(_.symbol)
548548
var implParamss = macroImpl.paramss
549549
implParamss = transformTypeTagEvidenceParams(implParamss, (param, tparam) => None)
550550

0 commit comments

Comments
 (0)