Skip to content

Commit

Permalink
Merge pull request scala#3216 from dotty-staging/more-opts
Browse files Browse the repository at this point in the history
Some more small optimizations
  • Loading branch information
allanrenucci authored Oct 3, 2017
2 parents 96b0ae4 + 128afcc commit 0dd8688
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 15 deletions.
25 changes: 13 additions & 12 deletions compiler/src/dotty/tools/dotc/transform/Memoize.scala
Original file line number Diff line number Diff line change
Expand Up @@ -101,19 +101,8 @@ import Decorators._
cpy.installAfter(thisTransform)
}

lazy val field = sym.field.orElse(newField).asTerm

def adaptToField(tree: Tree): Tree =
if (tree.isEmpty) tree else tree.ensureConforms(field.info.widen)

val NoFieldNeeded = Lazy | Deferred | JavaDefined | (if (ctx.settings.YnoInline.value) EmptyFlags else Inline)

def isErasableBottomField(cls: Symbol): Boolean = {
// TODO: For Scala.js, return false if this field is in a js.Object unless it is an ErasedPhantomClass.
!field.isVolatile &&
((cls eq defn.NothingClass) || (cls eq defn.NullClass) || (cls eq defn.BoxedUnitClass) || (cls eq defn.ErasedPhantomClass))
}

def erasedBottomTree(sym: Symbol) = {
if (sym eq defn.NothingClass) Throw(Literal(Constant(null)))
else if (sym eq defn.NullClass) Literal(Constant(null))
Expand All @@ -125,7 +114,18 @@ import Decorators._
}
}

if (sym.is(Accessor, butNot = NoFieldNeeded))
if (sym.is(Accessor, butNot = NoFieldNeeded)) {
val field = sym.field.orElse(newField).asTerm

def adaptToField(tree: Tree): Tree =
if (tree.isEmpty) tree else tree.ensureConforms(field.info.widen)

def isErasableBottomField(cls: Symbol): Boolean = {
// TODO: For Scala.js, return false if this field is in a js.Object unless it is an ErasedPhantomClass.
!field.isVolatile &&
((cls eq defn.NothingClass) || (cls eq defn.NullClass) || (cls eq defn.BoxedUnitClass) || (cls eq defn.ErasedPhantomClass))
}

if (sym.isGetter) {
var rhs = tree.rhs.changeOwnerAfter(sym, field, thisTransform)
if (isWildcardArg(rhs)) rhs = EmptyTree
Expand All @@ -151,6 +151,7 @@ import Decorators._
}
else tree // curiously, some accessors from Scala2 have ' ' suffixes. They count as
// neither getters nor setters
}
else tree
}
}
22 changes: 19 additions & 3 deletions compiler/src/dotty/tools/dotc/transform/TreeTransform.scala
Original file line number Diff line number Diff line change
Expand Up @@ -196,10 +196,12 @@ object TreeTransforms {
}
}

@sharable val NoTransform = new TreeTransform {
private class NoTreeTransform extends TreeTransform {
def phase = unsupported("phase")
}

@sharable val NoTransform: TreeTransform = new NoTreeTransform

type Mutator[T] = (TreeTransform, T, Context) => TreeTransform

class TransformerInfo(val transformers: Array[TreeTransform], val nx: NXTransformations, val group: TreeTransformer)
Expand All @@ -209,15 +211,29 @@ object TreeTransforms {
* @see NXTransformations.index for format of plan
*/
class NXTransformations {
private val clsMethodsCache = new java.util.IdentityHashMap[Class[_], Array[java.lang.reflect.Method]]

// TODO: We spend too much time here. See if we can call it less or make it faster,
// e.g. by checking `cls.getMethod(name, ...).getDeclaringClass != classOf[TreeTransform]` instead.
private def hasRedefinedMethod(cls: Class[_], name: String): Boolean = {
val clsMethods = cls.getDeclaredMethods
if (cls.eq(classOf[TreeTransform]) || cls.eq(classOf[NoTreeTransform]) ||
cls.eq(classOf[MiniPhaseTransform]))
return false

// Class#getDeclaredMethods is slow, so we cache its output
var clsMethods = clsMethodsCache.get(cls)
if (clsMethods eq null) {
clsMethods = cls.getDeclaredMethods
clsMethodsCache.put(cls, clsMethods)
}

var i = clsMethods.length - 1
while (i >= 0) {
if (clsMethods(i).getName == name)
return cls != classOf[TreeTransform]
return true
i -= 1
}

hasRedefinedMethod(cls.getSuperclass, name)
}

Expand Down

0 comments on commit 0dd8688

Please sign in to comment.