summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2012-08-17 15:41:40 +0200
committerGrzegorz Kossakowski <grzegorz.kossakowski@gmail.com>2012-08-20 08:11:08 +0100
commitc2aae3faa5bdb0bb8797ebcf951857e911e5c3f3 (patch)
tree3ef65e69e92fd407b6de27081a7b29828d949e4e
parent3b7c730212fa4653c12ff2681cb67369101ce2c2 (diff)
downloadscala-c2aae3faa5bdb0bb8797ebcf951857e911e5c3f3.tar.gz
scala-c2aae3faa5bdb0bb8797ebcf951857e911e5c3f3.tar.bz2
scala-c2aae3faa5bdb0bb8797ebcf951857e911e5c3f3.zip
Optimizations to SymTree and transform
Two optimizations: (1) Make SymTree a class rather than a trait to allow faster access to symbol (2) Split itransform into several smaller methods and order cases according to expected frequency.
-rw-r--r--src/compiler/scala/tools/nsc/ast/Trees.scala2
-rw-r--r--src/reflect/scala/reflect/internal/Trees.scala180
2 files changed, 97 insertions, 85 deletions
diff --git a/src/compiler/scala/tools/nsc/ast/Trees.scala b/src/compiler/scala/tools/nsc/ast/Trees.scala
index b703a90ebf..085ce82025 100644
--- a/src/compiler/scala/tools/nsc/ast/Trees.scala
+++ b/src/compiler/scala/tools/nsc/ast/Trees.scala
@@ -50,7 +50,7 @@ trait Trees extends reflect.internal.Trees { self: Global =>
/** Array selection <qualifier> . <name> only used during erasure */
case class SelectFromArray(qualifier: Tree, name: Name, erasure: Type)
- extends TermTree with RefTree
+ extends RefTree with TermTree
/** Derived value class injection (equivalent to: new C(arg) after easure); only used during erasure
* The class C is stored as the symbol of the tree node.
diff --git a/src/reflect/scala/reflect/internal/Trees.scala b/src/reflect/scala/reflect/internal/Trees.scala
index 8f4c0de001..6d80867d02 100644
--- a/src/reflect/scala/reflect/internal/Trees.scala
+++ b/src/reflect/scala/reflect/internal/Trees.scala
@@ -210,7 +210,7 @@ trait Trees extends api.Trees { self: SymbolTable =>
trait TypTree extends Tree with TypTreeApi
- trait SymTree extends Tree with SymTreeContextApi {
+ abstract class SymTree extends Tree with SymTreeContextApi {
override def hasSymbol = true
override var symbol: Symbol = NoSymbol
}
@@ -333,7 +333,7 @@ trait Trees extends api.Trees { self: SymbolTable =>
object ArrayValue extends ArrayValueExtractor
case class Function(vparams: List[ValDef], body: Tree)
- extends TermTree with SymTree with FunctionApi
+ extends SymTree with TermTree with FunctionApi
object Function extends FunctionExtractor
case class Assign(lhs: Tree, rhs: Tree)
@@ -353,7 +353,7 @@ trait Trees extends api.Trees { self: SymbolTable =>
object Match extends MatchExtractor
case class Return(expr: Tree)
- extends TermTree with SymTree with ReturnApi
+ extends SymTree with TermTree with ReturnApi
object Return extends ReturnExtractor
case class Try(block: Tree, catches: List[CaseDef], finalizer: Tree)
@@ -401,7 +401,7 @@ trait Trees extends api.Trees { self: SymbolTable =>
def ApplyConstructor(tpt: Tree, args: List[Tree]) = Apply(Select(New(tpt), nme.CONSTRUCTOR), args)
case class ApplyDynamic(qual: Tree, args: List[Tree])
- extends TermTree with SymTree with ApplyDynamicApi
+ extends SymTree with TermTree with ApplyDynamicApi
object ApplyDynamic extends ApplyDynamicExtractor
case class Super(qual: Tree, mix: TypeName) extends TermTree with SuperApi {
@@ -411,7 +411,7 @@ trait Trees extends api.Trees { self: SymbolTable =>
object Super extends SuperExtractor
case class This(qual: TypeName)
- extends TermTree with SymTree with ThisApi
+ extends SymTree with TermTree with ThisApi
object This extends ThisExtractor
case class Select(qualifier: Tree, name: Name)
@@ -447,7 +447,7 @@ trait Trees extends api.Trees { self: SymbolTable =>
object SingletonTypeTree extends SingletonTypeTreeExtractor
case class SelectFromTypeTree(qualifier: Tree, name: TypeName)
- extends TypTree with RefTree with SelectFromTypeTreeApi
+ extends RefTree with TypTree with SelectFromTypeTreeApi
object SelectFromTypeTree extends SelectFromTypeTreeExtractor
case class CompoundTypeTree(templ: Template)
@@ -1145,19 +1145,36 @@ trait Trees extends api.Trees { self: SymbolTable =>
}
}
+ //OPT split in two and ordered according to frequency to speed it up.
override protected def itransform(transformer: Transformer, tree: Tree): Tree = {
import transformer._
val treeCopy = transformer.treeCopy
- tree match {
+
+ def itransform1(transformer: Transformer, tree: Tree): Tree = tree match {
+ case Match(selector, cases) =>
+ treeCopy.Match(tree, transform(selector), transformCaseDefs(cases))
+ case New(tpt) =>
+ treeCopy.New(tree, transform(tpt))
+ case Assign(lhs, rhs) =>
+ treeCopy.Assign(tree, transform(lhs), transform(rhs))
+ case AssignOrNamedArg(lhs, rhs) =>
+ treeCopy.AssignOrNamedArg(tree, transform(lhs), transform(rhs))
+ case Try(block, catches, finalizer) =>
+ treeCopy.Try(tree, transform(block), transformCaseDefs(catches), transform(finalizer))
case EmptyTree =>
tree
- case PackageDef(pid, stats) =>
- treeCopy.PackageDef(
- tree, transform(pid).asInstanceOf[RefTree],
- atOwner(mclass(tree.symbol)) {
- transformStats(stats, currentOwner)
- }
- )
+ case Throw(expr) =>
+ treeCopy.Throw(tree, transform(expr))
+ case Super(qual, mix) =>
+ treeCopy.Super(tree, transform(qual), mix)
+ case TypeBoundsTree(lo, hi) =>
+ treeCopy.TypeBoundsTree(tree, transform(lo), transform(hi))
+ case Typed(expr, tpt) =>
+ treeCopy.Typed(tree, transform(expr), transform(tpt))
+ case Import(expr, selectors) =>
+ treeCopy.Import(tree, transform(expr), selectors)
+ case Template(parents, self, body) =>
+ treeCopy.Template(tree, transformTrees(parents), transformValDef(self), transformStats(body, tree.symbol))
case ClassDef(mods, name, tparams, impl) =>
atOwner(tree.symbol) {
treeCopy.ClassDef(tree, transformModifiers(mods), name,
@@ -1168,100 +1185,95 @@ trait Trees extends api.Trees { self: SymbolTable =>
treeCopy.ModuleDef(tree, transformModifiers(mods),
name, transformTemplate(impl))
}
- case ValDef(mods, name, tpt, rhs) =>
- atOwner(tree.symbol) {
- treeCopy.ValDef(tree, transformModifiers(mods),
- name, transform(tpt), transform(rhs))
- }
- case DefDef(mods, name, tparams, vparamss, tpt, rhs) =>
- atOwner(tree.symbol) {
- treeCopy.DefDef(tree, transformModifiers(mods), name,
- transformTypeDefs(tparams), transformValDefss(vparamss),
- transform(tpt), transform(rhs))
- }
case TypeDef(mods, name, tparams, rhs) =>
atOwner(tree.symbol) {
treeCopy.TypeDef(tree, transformModifiers(mods), name,
transformTypeDefs(tparams), transform(rhs))
}
+ case _ => itransform2(transformer, tree)
+ }
+
+ def itransform2(transformer: Transformer, tree: Tree): Tree = tree match {
case LabelDef(name, params, rhs) =>
treeCopy.LabelDef(tree, name, transformIdents(params), transform(rhs)) //bq: Martin, once, atOwner(...) works, also change `LamdaLifter.proxy'
- case Import(expr, selectors) =>
- treeCopy.Import(tree, transform(expr), selectors)
- case Template(parents, self, body) =>
- treeCopy.Template(tree, transformTrees(parents), transformValDef(self), transformStats(body, tree.symbol))
- case Block(stats, expr) =>
- treeCopy.Block(tree, transformStats(stats, currentOwner), transform(expr))
- case CaseDef(pat, guard, body) =>
- treeCopy.CaseDef(tree, transform(pat), transform(guard), transform(body))
+ case PackageDef(pid, stats) =>
+ treeCopy.PackageDef(
+ tree, transform(pid).asInstanceOf[RefTree],
+ atOwner(mclass(tree.symbol)) {
+ transformStats(stats, currentOwner)
+ }
+ )
+ case Annotated(annot, arg) =>
+ treeCopy.Annotated(tree, transform(annot), transform(arg))
+ case SingletonTypeTree(ref) =>
+ treeCopy.SingletonTypeTree(tree, transform(ref))
+ case SelectFromTypeTree(qualifier, selector) =>
+ treeCopy.SelectFromTypeTree(tree, transform(qualifier), selector)
+ case CompoundTypeTree(templ) =>
+ treeCopy.CompoundTypeTree(tree, transformTemplate(templ))
+ case ExistentialTypeTree(tpt, whereClauses) =>
+ treeCopy.ExistentialTypeTree(tree, transform(tpt), transformTrees(whereClauses))
+ case Return(expr) =>
+ treeCopy.Return(tree, transform(expr))
case Alternative(trees) =>
treeCopy.Alternative(tree, transformTrees(trees))
case Star(elem) =>
treeCopy.Star(tree, transform(elem))
- case Bind(name, body) =>
- treeCopy.Bind(tree, name, transform(body))
case UnApply(fun, args) =>
treeCopy.UnApply(tree, fun, transformTrees(args)) // bq: see test/.../unapplyContexts2.scala
case ArrayValue(elemtpt, trees) =>
treeCopy.ArrayValue(tree, transform(elemtpt), transformTrees(trees))
- case Function(vparams, body) =>
- atOwner(tree.symbol) {
- treeCopy.Function(tree, transformValDefs(vparams), transform(body))
- }
- case Assign(lhs, rhs) =>
- treeCopy.Assign(tree, transform(lhs), transform(rhs))
- case AssignOrNamedArg(lhs, rhs) =>
- treeCopy.AssignOrNamedArg(tree, transform(lhs), transform(rhs))
- case If(cond, thenp, elsep) =>
- treeCopy.If(tree, transform(cond), transform(thenp), transform(elsep))
- case Match(selector, cases) =>
- treeCopy.Match(tree, transform(selector), transformCaseDefs(cases))
- case Return(expr) =>
- treeCopy.Return(tree, transform(expr))
- case Try(block, catches, finalizer) =>
- treeCopy.Try(tree, transform(block), transformCaseDefs(catches), transform(finalizer))
- case Throw(expr) =>
- treeCopy.Throw(tree, transform(expr))
- case New(tpt) =>
- treeCopy.New(tree, transform(tpt))
- case Typed(expr, tpt) =>
- treeCopy.Typed(tree, transform(expr), transform(tpt))
- case TypeApply(fun, args) =>
- treeCopy.TypeApply(tree, transform(fun), transformTrees(args))
- case Apply(fun, args) =>
- treeCopy.Apply(tree, transform(fun), transformTrees(args))
case ApplyDynamic(qual, args) =>
treeCopy.ApplyDynamic(tree, transform(qual), transformTrees(args))
- case Super(qual, mix) =>
- treeCopy.Super(tree, transform(qual), mix)
- case This(qual) =>
- treeCopy.This(tree, qual)
- case Select(qualifier, selector) =>
- treeCopy.Select(tree, transform(qualifier), selector)
- case Ident(name) =>
- treeCopy.Ident(tree, name)
case ReferenceToBoxed(idt) =>
treeCopy.ReferenceToBoxed(tree, transform(idt) match { case idt1: Ident => idt1 })
- case Literal(value) =>
- treeCopy.Literal(tree, value)
+ case _ =>
+ xtransform(transformer, tree)
+ }
+
+ // begin itransform
+ tree match {
+ case Ident(name) =>
+ treeCopy.Ident(tree, name)
+ case Select(qualifier, selector) =>
+ treeCopy.Select(tree, transform(qualifier), selector)
+ case Apply(fun, args) =>
+ treeCopy.Apply(tree, transform(fun), transformTrees(args))
case TypeTree() =>
treeCopy.TypeTree(tree)
- case Annotated(annot, arg) =>
- treeCopy.Annotated(tree, transform(annot), transform(arg))
- case SingletonTypeTree(ref) =>
- treeCopy.SingletonTypeTree(tree, transform(ref))
- case SelectFromTypeTree(qualifier, selector) =>
- treeCopy.SelectFromTypeTree(tree, transform(qualifier), selector)
- case CompoundTypeTree(templ) =>
- treeCopy.CompoundTypeTree(tree, transformTemplate(templ))
+ case Literal(value) =>
+ treeCopy.Literal(tree, value)
+ case This(qual) =>
+ treeCopy.This(tree, qual)
+ case ValDef(mods, name, tpt, rhs) =>
+ atOwner(tree.symbol) {
+ treeCopy.ValDef(tree, transformModifiers(mods),
+ name, transform(tpt), transform(rhs))
+ }
+ case DefDef(mods, name, tparams, vparamss, tpt, rhs) =>
+ atOwner(tree.symbol) {
+ treeCopy.DefDef(tree, transformModifiers(mods), name,
+ transformTypeDefs(tparams), transformValDefss(vparamss),
+ transform(tpt), transform(rhs))
+ }
+ case Block(stats, expr) =>
+ treeCopy.Block(tree, transformStats(stats, currentOwner), transform(expr))
+ case If(cond, thenp, elsep) =>
+ treeCopy.If(tree, transform(cond), transform(thenp), transform(elsep))
+ case CaseDef(pat, guard, body) =>
+ treeCopy.CaseDef(tree, transform(pat), transform(guard), transform(body))
+ case TypeApply(fun, args) =>
+ treeCopy.TypeApply(tree, transform(fun), transformTrees(args))
case AppliedTypeTree(tpt, args) =>
treeCopy.AppliedTypeTree(tree, transform(tpt), transformTrees(args))
- case TypeBoundsTree(lo, hi) =>
- treeCopy.TypeBoundsTree(tree, transform(lo), transform(hi))
- case ExistentialTypeTree(tpt, whereClauses) =>
- treeCopy.ExistentialTypeTree(tree, transform(tpt), transformTrees(whereClauses))
+ case Bind(name, body) =>
+ treeCopy.Bind(tree, name, transform(body))
+ case Function(vparams, body) =>
+ atOwner(tree.symbol) {
+ treeCopy.Function(tree, transformValDefs(vparams), transform(body))
+ }
case _ =>
- xtransform(transformer, tree)
+ itransform1(transformer, tree)
}
}