Skip to content

Commit 0598535

Browse files
committed
Merge pull request scala#3445 from retronym/topic/opt7
Grab bag of compiler optimizations
2 parents ca85886 + bf24780 commit 0598535

File tree

9 files changed

+81
-26
lines changed

9 files changed

+81
-26
lines changed

src/compiler/scala/tools/nsc/transform/Erasure.scala

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -522,6 +522,8 @@ abstract class Erasure extends AddInterfaces
522522
class Eraser(_context: Context) extends Typer(_context) with TypeAdapter {
523523
val typer = this.asInstanceOf[analyzer.Typer]
524524

525+
override protected def stabilize(tree: Tree, pre: Type, mode: Mode, pt: Type): Tree = tree
526+
525527
/** Replace member references as follows:
526528
*
527529
* - `x == y` for == in class Any becomes `x equals y` with equals in class Object.

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -788,7 +788,7 @@ trait Implicits {
788788
final class LocalShadower extends Shadower {
789789
val shadowed = util.HashSet[Name](512)
790790
def addInfos(infos: Infos) {
791-
shadowed addEntries infos.map(_.name)
791+
infos.foreach(i => shadowed.addEntry(i.name))
792792
}
793793
def isShadowed(name: Name) = shadowed(name)
794794
}
@@ -805,7 +805,6 @@ trait Implicits {
805805
private def isIneligible(info: ImplicitInfo) = (
806806
info.isCyclicOrErroneous
807807
|| isView && (info.sym eq Predef_conforms)
808-
|| shadower.isShadowed(info.name)
809808
|| (!context.macrosEnabled && info.sym.isTermMacro)
810809
)
811810

@@ -814,6 +813,7 @@ trait Implicits {
814813
def survives(info: ImplicitInfo) = (
815814
!isIneligible(info) // cyclic, erroneous, shadowed, or specially excluded
816815
&& isPlausiblyCompatible(info.tpe, wildPt) // optimization to avoid matchesPt
816+
&& !shadower.isShadowed(info.name) // OPT rare, only check for plausible candidates
817817
&& matchesPt(info) // stable and matches expected type
818818
)
819819
/** The implicits that are not valid because they come later in the source and

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1069,8 +1069,9 @@ trait Namers extends MethodSynthesis {
10691069
}
10701070

10711071
def overriddenSymbol(resTp: Type) = {
1072+
lazy val schema: Type = methodTypeSchema(resTp) // OPT create once. Must be lazy to avoid cycles in neg/t5093.scala
10721073
intersectionType(methOwner.info.parents).nonPrivateMember(meth.name).filter { sym =>
1073-
sym != NoSymbol && (site.memberType(sym) matches methodTypeSchema(resTp))
1074+
sym != NoSymbol && (site.memberType(sym) matches schema)
10741075
}
10751076
}
10761077
// TODO: see whether this or something similar would work instead:

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ trait StdAttachments {
4646
* The parameter is of type `Any`, because macros can expand both into trees and into annotations.
4747
*/
4848
def hasMacroExpansionAttachment(any: Any): Boolean = any match {
49-
case tree: Tree => tree.attachments.get[MacroExpansionAttachment].isDefined
49+
case tree: Tree => tree.hasAttachment[MacroExpansionAttachment]
5050
case _ => false
5151
}
5252

@@ -96,7 +96,7 @@ trait StdAttachments {
9696
*/
9797
def isMacroExpansionSuppressed(tree: Tree): Boolean =
9898
( settings.Ymacroexpand.value == settings.MacroExpand.None // SI-6812
99-
|| tree.attachments.get[SuppressMacroExpansionAttachment.type].isDefined
99+
|| tree.hasAttachment[SuppressMacroExpansionAttachment.type]
100100
|| (tree match {
101101
// we have to account for the fact that during typechecking an expandee might become wrapped,
102102
// i.e. surrounded by an inferred implicit argument application or by an inferred type argument application.
@@ -150,7 +150,7 @@ trait StdAttachments {
150150
/** Determines whether a tree should or should not be adapted,
151151
* because someone has put MacroImplRefAttachment on it.
152152
*/
153-
def isMacroImplRef(tree: Tree): Boolean = tree.attachments.get[MacroImplRefAttachment.type].isDefined
153+
def isMacroImplRef(tree: Tree): Boolean = tree.hasAttachment[MacroImplRefAttachment.type]
154154

155155
/** Since mkInvoke, the applyDynamic/selectDynamic/etc desugarer, is disconnected
156156
* from typedNamedApply, the applyDynamicNamed argument rewriter, the latter

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

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -579,7 +579,8 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
579579
* 3. Turn tree type into stable type if possible and required by context.
580580
* 4. Give getClass calls a more precise type based on the type of the target of the call.
581581
*/
582-
private def stabilize(tree: Tree, pre: Type, mode: Mode, pt: Type): Tree = {
582+
protected def stabilize(tree: Tree, pre: Type, mode: Mode, pt: Type): Tree = {
583+
583584
// Side effect time! Don't be an idiot like me and think you
584585
// can move "val sym = tree.symbol" before this line, because
585586
// inferExprAlternative side-effects the tree's symbol.
@@ -992,7 +993,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
992993
def adaptMismatchedSkolems() = {
993994
def canIgnoreMismatch = (
994995
!context.reportErrors && isPastTyper
995-
|| tree.attachments.get[MacroExpansionAttachment].isDefined
996+
|| tree.hasAttachment[MacroExpansionAttachment]
996997
)
997998
def bound = pt match {
998999
case ExistentialType(qs, _) => qs
@@ -2232,14 +2233,14 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
22322233
DeprecatedParamNameError(p, n)
22332234
}
22342235
}
2235-
}
2236-
if (meth.isStructuralRefinementMember)
2237-
checkMethodStructuralCompatible(ddef)
2236+
if (meth.isStructuralRefinementMember)
2237+
checkMethodStructuralCompatible(ddef)
22382238

2239-
if (meth.isImplicit && !meth.isSynthetic) meth.info.paramss match {
2240-
case List(param) :: _ if !param.isImplicit =>
2241-
checkFeature(ddef.pos, ImplicitConversionsFeature, meth.toString)
2242-
case _ =>
2239+
if (meth.isImplicit && !meth.isSynthetic) meth.info.paramss match {
2240+
case List(param) :: _ if !param.isImplicit =>
2241+
checkFeature(ddef.pos, ImplicitConversionsFeature, meth.toString)
2242+
case _ =>
2243+
}
22432244
}
22442245

22452246
treeCopy.DefDef(ddef, typedMods, ddef.name, tparams1, vparamss1, tpt1, rhs1) setType NoType

src/library/scala/collection/immutable/Set.scala

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,16 @@ object Set extends ImmutableSetFactory[Set] {
8282
override def foreach[U](f: A => U): Unit = {
8383
f(elem1)
8484
}
85+
override def exists(f: A => Boolean): Boolean = {
86+
f(elem1)
87+
}
88+
override def forall(f: A => Boolean): Boolean = {
89+
f(elem1)
90+
}
91+
override def find(f: A => Boolean): Option[A] = {
92+
if (f(elem1)) Some(elem1)
93+
else None
94+
}
8595
}
8696

8797
/** An optimized representation for immutable sets of size 2 */
@@ -102,6 +112,17 @@ object Set extends ImmutableSetFactory[Set] {
102112
override def foreach[U](f: A => U): Unit = {
103113
f(elem1); f(elem2)
104114
}
115+
override def exists(f: A => Boolean): Boolean = {
116+
f(elem1) || f(elem2)
117+
}
118+
override def forall(f: A => Boolean): Boolean = {
119+
f(elem1) && f(elem2)
120+
}
121+
override def find(f: A => Boolean): Option[A] = {
122+
if (f(elem1)) Some(elem1)
123+
else if (f(elem2)) Some(elem2)
124+
else None
125+
}
105126
}
106127

107128
/** An optimized representation for immutable sets of size 3 */
@@ -123,6 +144,18 @@ object Set extends ImmutableSetFactory[Set] {
123144
override def foreach[U](f: A => U): Unit = {
124145
f(elem1); f(elem2); f(elem3)
125146
}
147+
override def exists(f: A => Boolean): Boolean = {
148+
f(elem1) || f(elem2) || f(elem3)
149+
}
150+
override def forall(f: A => Boolean): Boolean = {
151+
f(elem1) && f(elem2) && f(elem3)
152+
}
153+
override def find(f: A => Boolean): Option[A] = {
154+
if (f(elem1)) Some(elem1)
155+
else if (f(elem2)) Some(elem2)
156+
else if (f(elem3)) Some(elem3)
157+
else None
158+
}
126159
}
127160

128161
/** An optimized representation for immutable sets of size 4 */
@@ -145,6 +178,19 @@ object Set extends ImmutableSetFactory[Set] {
145178
override def foreach[U](f: A => U): Unit = {
146179
f(elem1); f(elem2); f(elem3); f(elem4)
147180
}
181+
override def exists(f: A => Boolean): Boolean = {
182+
f(elem1) || f(elem2) || f(elem3) || f(elem4)
183+
}
184+
override def forall(f: A => Boolean): Boolean = {
185+
f(elem1) && f(elem2) && f(elem3) && f(elem4)
186+
}
187+
override def find(f: A => Boolean): Option[A] = {
188+
if (f(elem1)) Some(elem1)
189+
else if (f(elem2)) Some(elem2)
190+
else if (f(elem3)) Some(elem3)
191+
else if (f(elem4)) Some(elem4)
192+
else None
193+
}
148194
}
149195
}
150196

src/reflect/scala/reflect/internal/TreeInfo.scala

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -284,17 +284,17 @@ abstract class TreeInfo {
284284
/** Is tree a self constructor call this(...)? I.e. a call to a constructor of the
285285
* same object?
286286
*/
287-
def isSelfConstrCall(tree: Tree): Boolean = tree match {
288-
case Applied(Ident(nme.CONSTRUCTOR), _, _) => true
289-
case Applied(Select(This(_), nme.CONSTRUCTOR), _, _) => true
290-
case _ => false
287+
def isSelfConstrCall(tree: Tree): Boolean = dissectApplied(tree).core match {
288+
case Ident(nme.CONSTRUCTOR) => true
289+
case Select(This(_), nme.CONSTRUCTOR) => true
290+
case _ => false
291291
}
292292

293293
/** Is tree a super constructor call?
294294
*/
295-
def isSuperConstrCall(tree: Tree): Boolean = tree match {
296-
case Applied(Select(Super(_, _), nme.CONSTRUCTOR), _, _) => true
297-
case _ => false
295+
def isSuperConstrCall(tree: Tree): Boolean = dissectApplied(tree).core match {
296+
case Select(Super(_, _), nme.CONSTRUCTOR) => true
297+
case _ => false
298298
}
299299

300300
/**
@@ -848,8 +848,10 @@ abstract class TreeInfo {
848848
case _ => false
849849
})
850850

851-
def isMacroApplication(tree: Tree): Boolean =
852-
!tree.isDef && tree.symbol != null && tree.symbol.isTermMacro && !tree.symbol.isErroneous
851+
def isMacroApplication(tree: Tree): Boolean = !tree.isDef && {
852+
val sym = tree.symbol
853+
sym != null && sym.isTermMacro && !sym.isErroneous
854+
}
853855

854856
def isMacroApplicationOrBlock(tree: Tree): Boolean = tree match {
855857
case Block(_, expr) => isMacroApplicationOrBlock(expr)

src/reflect/scala/reflect/internal/tpe/TypeMaps.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -861,7 +861,7 @@ private[internal] trait TypeMaps {
861861
class InstantiateDependentMap(params: List[Symbol], actuals0: List[Type]) extends TypeMap with KeepOnlyTypeConstraints {
862862
private val actuals = actuals0.toIndexedSeq
863863
private val existentials = new Array[Symbol](actuals.size)
864-
def existentialsNeeded: List[Symbol] = existentials.filter(_ ne null).toList
864+
def existentialsNeeded: List[Symbol] = existentials.iterator.filter(_ ne null).toList
865865

866866
private object StableArg {
867867
def unapply(param: Symbol) = Arg unapply param map actuals filter (tp =>

src/reflect/scala/reflect/macros/Attachments.scala

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ abstract class Attachments { self =>
4343

4444
/** Check underlying payload contains an instance of type `T`. */
4545
def contains[T: ClassTag]: Boolean =
46-
all exists matchesTag[T]
46+
!isEmpty && (all exists matchesTag[T])
4747

4848
/** Creates a copy of this attachment with the payload slot of T added/updated with the provided value.
4949
* Replaces an existing payload of the same type, if exists.
@@ -57,11 +57,14 @@ abstract class Attachments { self =>
5757
if (newAll.isEmpty) pos.asInstanceOf[Attachments { type Pos = self.Pos }]
5858
else new NonemptyAttachments[Pos](this.pos, newAll)
5959
}
60+
61+
def isEmpty: Boolean = true
6062
}
6163

6264
// SI-7018: This used to be an inner class of `Attachments`, but that led to a memory leak in the
6365
// IDE via $outer pointers.
6466
private final class NonemptyAttachments[P >: Null](override val pos: P, override val all: Set[Any]) extends Attachments {
6567
type Pos = P
6668
def withPos(newPos: Pos) = new NonemptyAttachments(newPos, all)
69+
override def isEmpty: Boolean = false
6770
}

0 commit comments

Comments
 (0)