From 1a6a9b4c75c5a8835ab1ed42a9e0269cf4bc2fe7 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Tue, 14 Aug 2012 20:17:09 +0200 Subject: More method hoisting. Also avoided systematically to map (_.tpe) on parameters in favor of lazy val paramTypes. --- .../scala/reflect/internal/Definitions.scala | 4 +- src/reflect/scala/reflect/internal/Symbols.scala | 23 ++++++- src/reflect/scala/reflect/internal/Trees.scala | 6 ++ src/reflect/scala/reflect/internal/Types.scala | 79 +++++++++++----------- .../reflect/internal/pickling/UnPickler.scala | 2 +- .../scala/reflect/internal/transform/Erasure.scala | 4 +- 6 files changed, 72 insertions(+), 46 deletions(-) (limited to 'src/reflect') diff --git a/src/reflect/scala/reflect/internal/Definitions.scala b/src/reflect/scala/reflect/internal/Definitions.scala index 98d42b724c..14547123b0 100644 --- a/src/reflect/scala/reflect/internal/Definitions.scala +++ b/src/reflect/scala/reflect/internal/Definitions.scala @@ -759,7 +759,7 @@ trait Definitions extends api.StandardDefinitions { // java.lang.Object. Java also special cases the return type. lazy val Any_getClass = enterNewMethod(AnyClass, nme.getClass_, Nil, getMemberMethod(ObjectClass, nme.getClass_).tpe.resultType, DEFERRED) lazy val Any_isInstanceOf = newT1NullaryMethod(AnyClass, nme.isInstanceOf_, FINAL)(_ => booltype) - lazy val Any_asInstanceOf = newT1NullaryMethod(AnyClass, nme.asInstanceOf_, FINAL)(_.typeConstructor) + lazy val Any_asInstanceOf = newT1NullaryMethod(AnyClass, nme.asInstanceOf_, FINAL)(typeConstructorOfSymbol) // A type function from T => Class[U], used to determine the return // type of getClass calls. The returned type is: @@ -851,7 +851,7 @@ trait Definitions extends api.StandardDefinitions { lazy val Object_eq = enterNewMethod(ObjectClass, nme.eq, anyrefparam, booltype, FINAL) lazy val Object_ne = enterNewMethod(ObjectClass, nme.ne, anyrefparam, booltype, FINAL) lazy val Object_isInstanceOf = newT1NoParamsMethod(ObjectClass, nme.isInstanceOf_Ob, FINAL | SYNTHETIC)(_ => booltype) - lazy val Object_asInstanceOf = newT1NoParamsMethod(ObjectClass, nme.asInstanceOf_Ob, FINAL | SYNTHETIC)(_.typeConstructor) + lazy val Object_asInstanceOf = newT1NoParamsMethod(ObjectClass, nme.asInstanceOf_Ob, FINAL | SYNTHETIC)(typeConstructorOfSymbol) lazy val Object_synchronized = newPolyMethod(1, ObjectClass, nme.synchronized_, FINAL)(tps => (Some(List(tps.head.typeConstructor)), tps.head.typeConstructor) ) diff --git a/src/reflect/scala/reflect/internal/Symbols.scala b/src/reflect/scala/reflect/internal/Symbols.scala index 17f4669c29..15ca276b1a 100644 --- a/src/reflect/scala/reflect/internal/Symbols.scala +++ b/src/reflect/scala/reflect/internal/Symbols.scala @@ -11,6 +11,7 @@ import scala.collection.mutable.ListBuffer import util.Statistics import Flags._ import base.Attachments +import scala.annotation.tailrec trait Symbols extends api.Symbols { self: SymbolTable => import definitions._ @@ -1378,7 +1379,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => /** The value parameter sections of this symbol. */ def paramss: List[List[Symbol]] = info.paramss - + /** The least proper supertype of a class; includes all parent types * and refinement where needed. You need to compute that in a situation like this: * { @@ -2624,7 +2625,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => tpeCache = NoType val targs = if (phase.erasedTypes && this != ArrayClass) List() - else unsafeTypeParams map (_.typeConstructor) + else unsafeTypeParams map typeConstructorOfSymbol //@M! use typeConstructor to generate dummy type arguments, // sym.tpe should not be called on a symbol that's supposed to be a higher-kinded type // memberType should be used instead, that's why it uses tpeHK and not tpe @@ -3206,7 +3207,25 @@ trait Symbols extends api.Symbols { self: SymbolTable => def toList: List[TypeHistory] = this :: ( if (prev eq null) Nil else prev.toList ) } +// ----- Hoisted closures and convenience methods, for compile time reductions ------- + + private[scala] final val symbolIsPossibleInRefinement = (sym: Symbol) => sym.isPossibleInRefinement + private[scala] final val symbolIsNonVariant = (sym: Symbol) => sym.variance == 0 + private[scala] final val typeConstructorOfSymbol = (sym: Symbol) => sym.typeConstructor + private[scala] final val tpeOfSymbol = (sym: Symbol) => sym.tpe + private[scala] final val tpeHKOfSymbol = (sym: Symbol) => sym.tpeHK + + @tailrec private[scala] final + def allSymbolsHaveOwner(syms: List[Symbol], owner: Symbol): Boolean = syms match { + case sym :: rest => sym.owner == owner && allSymbolsHaveOwner(rest, owner) + case _ => true + } + + +// -------------- Statistics -------------------------------------------------------- + Statistics.newView("#symbols")(ids) + } object SymbolsStats { diff --git a/src/reflect/scala/reflect/internal/Trees.scala b/src/reflect/scala/reflect/internal/Trees.scala index b21a28eea8..8baed325fd 100644 --- a/src/reflect/scala/reflect/internal/Trees.scala +++ b/src/reflect/scala/reflect/internal/Trees.scala @@ -1540,6 +1540,12 @@ trait Trees extends api.Trees { self: SymbolTable => sys.error("Not a LabelDef: " + t + "/" + t.getClass) } +// ----- Hoisted closures and convenience methods, for compile time reductions ------- + + private[scala] final val tpeOfTree = (tree: Tree) => tree.tpe + +// -------------- Classtags -------------------------------------------------------- + implicit val TreeTag = ClassTag[Tree](classOf[Tree]) implicit val TermTreeTag = ClassTag[TermTree](classOf[TermTree]) implicit val TypTreeTag = ClassTag[TypTree](classOf[TypTree]) diff --git a/src/reflect/scala/reflect/internal/Types.scala b/src/reflect/scala/reflect/internal/Types.scala index dd47ee2181..e031498684 100644 --- a/src/reflect/scala/reflect/internal/Types.scala +++ b/src/reflect/scala/reflect/internal/Types.scala @@ -363,7 +363,7 @@ trait Types extends api.Types { self: SymbolTable => * and all type parameters (if any) are invariant. */ def isFinalType = - typeSymbol.isFinal && (typeSymbol.typeParams forall (_.variance == 0)) + typeSymbol.isFinal && (typeSymbol.typeParams forall symbolIsNonVariant) /** Is this type completed (i.e. not a lazy type)? */ def isComplete: Boolean = true @@ -484,7 +484,7 @@ trait Types extends api.Types { self: SymbolTable => /** A list of placeholder types derived from the type parameters. * Used by RefinedType and TypeRef. */ - protected def dummyArgs: List[Type] = typeParams map (_.typeConstructor) + protected def dummyArgs: List[Type] = typeParams map typeConstructorOfSymbol /** For a (nullary) method or poly type, its direct result type, * the type itself for all other types. */ @@ -835,7 +835,7 @@ trait Types extends api.Types { self: SymbolTable => case (TypeRef(_, ArrayClass, List(arg1)), TypeRef(_, ArrayClass, List(arg2))) if arg2.typeSymbol.typeParams.nonEmpty => arg1 matchesPattern arg2 case (_, TypeRef(_, _, args)) => - val newtp = existentialAbstraction(args map (_.typeSymbol), that) + val newtp = existentialAbstraction(args map typeSymbolOfType, that) !(that =:= newtp) && (this <:< newtp) case _ => false @@ -1495,8 +1495,8 @@ trait Types extends api.Types { self: SymbolTable => } private def lowerString = if (emptyLowerBound) "" else " >: " + lo private def upperString = if (emptyUpperBound) "" else " <: " + hi - private def emptyLowerBound = lo.typeSymbolDirect eq NothingClass - private def emptyUpperBound = hi.typeSymbolDirect eq AnyClass + private def emptyLowerBound = typeIsNothing(lo) + private def emptyUpperBound = typeIsAny(hi) def isEmptyBounds = emptyLowerBound && emptyUpperBound // override def isNullable: Boolean = NullClass.tpe <:< lo; @@ -1706,7 +1706,7 @@ trait Types extends api.Types { self: SymbolTable => override def isHigherKinded = ( parents.nonEmpty && - (parents forall (_.isHigherKinded)) && + (parents forall typeIsHigherKinded) && !phase.erasedTypes ) @@ -1716,7 +1716,7 @@ trait Types extends api.Types { self: SymbolTable => //@M may result in an invalid type (references to higher-order args become dangling ) override def typeConstructor = - copyRefinedType(this, parents map (_.typeConstructor), decls) + copyRefinedType(this, parents map typeConstructorOfType, decls) final override def normalize: Type = if (phase.erasedTypes) normalizeImpl @@ -2540,7 +2540,7 @@ trait Types extends api.Types { self: SymbolTable => override def paramss: List[List[Symbol]] = params :: resultType.paramss - override def paramTypes = params map (_.tpe) + override def paramTypes = params map tpeOfSymbol override def boundSyms = resultType.boundSyms ++ params @@ -3240,7 +3240,7 @@ trait Types extends api.Types { self: SymbolTable => if (constr.instValid) constr.inst // get here when checking higher-order subtyping of the typevar by itself // TODO: check whether this ever happens? - else if (isHigherKinded) typeFun(params, applyArgs(params map (_.typeConstructor))) + else if (isHigherKinded) typeFun(params, applyArgs(params map typeConstructorOfSymbol)) else super.normalize ) override def typeSymbol = origin.typeSymbol @@ -3625,7 +3625,7 @@ trait Types extends api.Types { self: SymbolTable => val bounds = args map (TypeBounds upper _) foreach2(eparams, bounds)(_ setInfo _) - newExistentialType(eparams, typeRef(pre, sym, eparams map (_.tpe))) + newExistentialType(eparams, typeRef(pre, sym, eparams map tpeOfSymbol)) case _ => appliedType(tycon, args) } @@ -3862,8 +3862,8 @@ trait Types extends api.Types { self: SymbolTable => * guarding addLoBound/addHiBound somehow broke raw types so it * only guards against being created with them.] */ - private var lobounds = lo0 filterNot (_.typeSymbolDirect eq NothingClass) - private var hibounds = hi0 filterNot (_.typeSymbolDirect eq AnyClass) + private var lobounds = lo0 filterNot typeIsNothing + private var hibounds = hi0 filterNot typeIsAny private var numlo = numlo0 private var numhi = numhi0 private var avoidWidening = avoidWidening0 @@ -3919,8 +3919,8 @@ trait Types extends api.Types { self: SymbolTable => override def toString = { val boundsStr = { - val lo = loBounds filterNot (_.typeSymbolDirect eq NothingClass) - val hi = hiBounds filterNot (_.typeSymbolDirect eq AnyClass) + val lo = loBounds filterNot typeIsNothing + val hi = hiBounds filterNot typeIsAny val lostr = if (lo.isEmpty) Nil else List(lo.mkString(" >: (", ", ", ")")) val histr = if (hi.isEmpty) Nil else List(hi.mkString(" <: (", ", ", ")")) @@ -4281,7 +4281,7 @@ trait Types extends api.Types { self: SymbolTable => else try { expanded += sym val eparams = mapOver(typeParamsToExistentials(sym)) - existentialAbstraction(eparams, typeRef(apply(pre), sym, eparams map (_.tpe))) + existentialAbstraction(eparams, typeRef(apply(pre), sym, eparams map tpeOfSymbol)) } finally { expanded -= sym } @@ -6225,8 +6225,8 @@ trait Types extends api.Types { self: SymbolTable => */ private def lubList(ts: List[Type], depth: Int): List[Type] = { // Matching the type params of one of the initial types means dummies. - val initialTypeParams = ts map (_.typeParams) - def isHotForTs(xs: List[Type]) = initialTypeParams contains xs.map(_.typeSymbol) + val initialTypeParams = ts map typeParamsOfType + def isHotForTs(xs: List[Type]) = initialTypeParams contains (xs map typeSymbolOfType) def elimHigherOrderTypeParam(tp: Type) = tp match { case TypeRef(pre, sym, args) if args.nonEmpty && isHotForTs(args) => tp.typeConstructor @@ -6459,8 +6459,8 @@ trait Types extends api.Types { self: SymbolTable => val tparams1 = map2(tparams, matchingBounds(ts, tparams).transpose)((tparam, bounds) => tparam.cloneSymbol.setInfo(glb(bounds, depth))) PolyType(tparams1, lub0(matchingInstTypes(ts, tparams1))) - case ts @ MethodType(params, _) :: rest => - MethodType(params, lub0(matchingRestypes(ts, params map (_.tpe)))) + case ts @ (mt @ MethodType(params, _)) :: rest => + MethodType(params, lub0(matchingRestypes(ts, mt.paramTypes))) case ts @ NullaryMethodType(_) :: rest => NullaryMethodType(lub0(matchingRestypes(ts, Nil))) case ts @ TypeBounds(_, _) :: rest => @@ -6614,8 +6614,8 @@ trait Types extends api.Types { self: SymbolTable => val tparams1 = map2(tparams, matchingBounds(ts, tparams).transpose)((tparam, bounds) => tparam.cloneSymbol.setInfo(lub(bounds, depth))) PolyType(tparams1, glbNorm(matchingInstTypes(ts, tparams1), depth)) - case ts @ MethodType(params, _) :: rest => - MethodType(params, glbNorm(matchingRestypes(ts, params map (_.tpe)), depth)) + case ts @ (mt @ MethodType(params, _)) :: rest => + MethodType(params, glbNorm(matchingRestypes(ts, mt.paramTypes), depth)) case ts @ NullaryMethodType(_) :: rest => NullaryMethodType(glbNorm(matchingRestypes(ts, Nil), depth)) case ts @ TypeBounds(_, _) :: rest => @@ -6878,7 +6878,7 @@ trait Types extends api.Types { self: SymbolTable => */ private def matchingRestypes(tps: List[Type], pts: List[Type]): List[Type] = tps map { - case MethodType(params1, res) if (isSameTypes(params1 map (_.tpe), pts)) => + case mt @ MethodType(params1, res) if isSameTypes(mt.paramTypes, pts) => res case NullaryMethodType(res) if pts.isEmpty => res @@ -6992,29 +6992,30 @@ trait Types extends api.Types { self: SymbolTable => // ----- Hoisted closures and convenience methods, for compile time reductions ------- - private val typeIsNotNull = (tp: Type) => tp.isNotNull - private val symbolIsPossibleInRefinement = (sym: Symbol) => sym.isPossibleInRefinement - private val isTypeVar = (tp: Type) => tp.isInstanceOf[TypeVar] - private val typeContainsTypeVar = (tp: Type) => tp exists isTypeVar - private val typeIsNonClassType = (tp: Type) => tp.typeSymbolDirect.isNonClassType - private val typeIsExistentiallyBound = (tp: Type) => tp.typeSymbol.isExistentiallyBound - private val typeSymbolOfType = (tp: Type) => tp.typeSymbol - private val typeIsErroneous = (tp: Type) => tp.isErroneous - private val typeHasAnnotations = (tp: Type) => tp.annotations.nonEmpty - private val boundsContainType = (bounds: TypeBounds, tp: Type) => bounds containsType tp - private val typeListIsEmpty = (ts: List[Type]) => ts.isEmpty - private val typeIsSubTypeOfSerializable = (tp: Type) => tp <:< SerializableClass.tpe + private[scala] val typeIsNotNull = (tp: Type) => tp.isNotNull + private[scala] val isTypeVar = (tp: Type) => tp.isInstanceOf[TypeVar] + private[scala] val typeContainsTypeVar = (tp: Type) => tp exists isTypeVar + private[scala] val typeIsNonClassType = (tp: Type) => tp.typeSymbolDirect.isNonClassType + private[scala] val typeIsExistentiallyBound = (tp: Type) => tp.typeSymbol.isExistentiallyBound + private[scala] val typeIsErroneous = (tp: Type) => tp.isErroneous + private[scala] val typeIsError = (tp: Type) => tp.isError + private[scala] val typeHasAnnotations = (tp: Type) => tp.annotations.nonEmpty + private[scala] val boundsContainType = (bounds: TypeBounds, tp: Type) => bounds containsType tp + private[scala] val typeListIsEmpty = (ts: List[Type]) => ts.isEmpty + private[scala] val typeIsSubTypeOfSerializable = (tp: Type) => tp <:< SerializableClass.tpe + private[scala] val typeIsNothing = (tp: Type) => tp.typeSymbolDirect eq NothingClass + private[scala] val typeIsAny = (tp: Type) => tp.typeSymbolDirect eq AnyClass + private[scala] val typeIsHigherKinded = (tp: Type) => tp.isHigherKinded + + private[scala] val typeSymbolOfType = (tp: Type) => tp.typeSymbol + private[scala] val typeParamsOfType = (tp: Type) => tp.typeParams + private[scala] val typeConstructorOfType = (tp: Type) => tp.typeConstructor @tailrec private def typesContain(tps: List[Type], sym: Symbol): Boolean = tps match { case tp :: rest => (tp contains sym) || typesContain(rest, sym) case _ => false } - @tailrec private def allSymbolsHaveOwner(syms: List[Symbol], owner: Symbol): Boolean = syms match { - case sym :: rest => sym.owner == owner && allSymbolsHaveOwner(rest, owner) - case _ => true - } - // -------------- Classtags -------------------------------------------------------- implicit val AnnotatedTypeTag = ClassTag[AnnotatedType](classOf[AnnotatedType]) diff --git a/src/reflect/scala/reflect/internal/pickling/UnPickler.scala b/src/reflect/scala/reflect/internal/pickling/UnPickler.scala index 9234ccca7b..dd515b2201 100644 --- a/src/reflect/scala/reflect/internal/pickling/UnPickler.scala +++ b/src/reflect/scala/reflect/internal/pickling/UnPickler.scala @@ -677,7 +677,7 @@ abstract class UnPickler /*extends reflect.generic.UnPickler*/ { val args = until(end, readTreeRef) if (fun.symbol.isOverloaded) { fun.setType(fun.symbol.info) - inferMethodAlternative(fun, args map (_.tpe), tpe) + inferMethodAlternative(fun, args map tpeOfTree, tpe) } Apply(fun, args) diff --git a/src/reflect/scala/reflect/internal/transform/Erasure.scala b/src/reflect/scala/reflect/internal/transform/Erasure.scala index 368d55a59c..cc5b5bb406 100644 --- a/src/reflect/scala/reflect/internal/transform/Erasure.scala +++ b/src/reflect/scala/reflect/internal/transform/Erasure.scala @@ -141,7 +141,7 @@ trait Erasure { if (restpe.typeSymbol == UnitClass) erasedTypeRef(UnitClass) // this replaces each typeref that refers to an argument // by the type `p.tpe` of the actual argument p (p in params) - else apply(mt.resultType(params map (_.tpe)))) + else apply(mt.resultType(mt.paramTypes))) case RefinedType(parents, decls) => apply(mergeParents(parents)) case AnnotatedType(_, atp, _) => @@ -220,7 +220,7 @@ trait Erasure { MethodType( cloneSymbolsAndModify(params, specialErasureAvoiding(clazz, _)), if (restpe.typeSymbol == UnitClass) erasedTypeRef(UnitClass) - else specialErasureAvoiding(clazz, (mt.resultType(params map (_.tpe))))) + else specialErasureAvoiding(clazz, (mt.resultType(mt.paramTypes)))) case TypeRef(pre, `clazz`, args) => typeRef(pre, clazz, List()) case _ => -- cgit v1.2.3