summaryrefslogtreecommitdiff
path: root/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2012-04-08 23:20:59 -0700
committerPaul Phillips <paulp@improving.org>2012-04-09 06:33:08 -0700
commit7bddd73f6e18bde931026abf5fe2526b747727ad (patch)
treec356907fc8a2232bda914cd4d7c9f445d3bcc9bb /src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala
parent174a75f78df9436884100768eff7ec938315280d (diff)
downloadscala-7bddd73f6e18bde931026abf5fe2526b747727ad.tar.gz
scala-7bddd73f6e18bde931026abf5fe2526b747727ad.tar.bz2
scala-7bddd73f6e18bde931026abf5fe2526b747727ad.zip
Make specialize check cheaper and consistent.
Profiler said checking hasAnnotation thousands of times is expensive. I always wondered why some things used the SPECIALIZED flag and others looked for the annotation. No reason emerges which is apparent from the tests. So: - mark an annotated symbol specialized at a convenient time - always look for the flag - create Symbol#isSpecialized to be consistent with all others
Diffstat (limited to 'src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala')
-rw-r--r--src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala40
1 files changed, 19 insertions, 21 deletions
diff --git a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala
index 51da933312..30decd4854 100644
--- a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala
+++ b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala
@@ -99,9 +99,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
/** Concrete methods that use a specialized type, or override such methods. */
private val concreteSpecMethods = perRunCaches.newWeakSet[Symbol]()
- private def isSpecialized(sym: Symbol) = sym hasAnnotation SpecializedClass
- private def hasSpecializedFlag(sym: Symbol) = sym hasFlag SPECIALIZED
- private def specializedTypes(tps: List[Symbol]) = tps filter isSpecialized
+ private def specializedTypes(tps: List[Symbol]) = tps filter (_.isSpecialized)
private def specializedOn(sym: Symbol): List[Symbol] = {
sym getAnnotation SpecializedClass match {
case Some(AnnotationInfo(_, Nil, _)) => specializableTypes.map(_.typeSymbol)
@@ -141,7 +139,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
def fromSpecialization(sym: Symbol, args: List[Type]): TypeEnv = {
ifDebug(assert(sym.info.typeParams.length == args.length, sym + " args: " + args))
- emptyEnv ++ collectMap2(sym.info.typeParams, args)((k, v) => isSpecialized(k))
+ emptyEnv ++ collectMap2(sym.info.typeParams, args)((k, v) => k.isSpecialized)
}
/** Does typeenv `t1` include `t2`? All type variables in `t1`
@@ -166,7 +164,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
*/
def isValid(env: TypeEnv, sym: Symbol): Boolean = {
env forall { case (tvar, tpe) =>
- isSpecialized(tvar) && (concreteTypes(tvar) contains tpe) && {
+ tvar.isSpecialized && (concreteTypes(tvar) contains tpe) && {
(sym.typeParams contains tvar) ||
(sym.owner != RootClass && (sym.owner.typeParams contains tvar))
}
@@ -178,7 +176,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
* 'sClass' itself if sClass is not a specialized subclass.
*/
def genericClass(sClass: Symbol): Symbol =
- if (hasSpecializedFlag(sClass)) sClass.superClass
+ if (sClass.isSpecialized) sClass.superClass
else sClass
case class Overload(sym: Symbol, env: TypeEnv) {
@@ -243,7 +241,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
/** Type bounds of a @specialized type var are now in the environment. */
override def typeBoundsIn(env: TypeEnv): Boolean = {
target.info.typeParams exists { tvar =>
- isSpecialized(tvar) && (specializedTypeVars(tvar.info.bounds) exists env.isDefinedAt)
+ tvar.isSpecialized && (specializedTypeVars(tvar.info.bounds) exists env.isDefinedAt)
}
}
@@ -259,21 +257,21 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
/** Has `clazz` any type parameters that need be specialized? */
def hasSpecializedParams(clazz: Symbol) =
- clazz.info.typeParams exists isSpecialized
+ clazz.info.typeParams exists (_.isSpecialized)
/** Return specialized type parameters. */
def specializedParams(sym: Symbol): List[Symbol] =
- sym.info.typeParams filter isSpecialized
+ sym.info.typeParams filter (_.isSpecialized)
def splitParams(tps: List[Symbol]) =
- tps partition isSpecialized
+ tps partition (_.isSpecialized)
/** Given an original class symbol and a list of types its type parameters are instantiated at
* returns a list of type parameters that should remain in the TypeRef when instantiating a
* specialized type.
*/
def survivingArgs(sym: Symbol, args: List[Type]): List[Type] =
- for ((tvar, tpe) <- sym.info.typeParams.zip(args) if !isSpecialized(tvar) || !isScalaValueType(tpe))
+ for ((tvar, tpe) <- sym.info.typeParams.zip(args) if !tvar.isSpecialized || !isScalaValueType(tpe))
yield tpe
val specializedType = new TypeMap {
@@ -347,7 +345,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
* These are in a meaningful order for stability purposes.
*/
def concreteTypes(sym: Symbol): List[Type] = {
- val types = if (!isSpecialized(sym))
+ val types = if (!sym.isSpecialized)
Nil // no @specialized Annotation
else
specializedOn(sym) map (s => specializesClass(s).tpe) sorted
@@ -363,7 +361,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
*/
private def specializations(tps: List[Symbol]): List[TypeEnv] = {
// the keys in each TypeEnv
- val keys: List[Symbol] = tps filter isSpecialized
+ val keys: List[Symbol] = tps filter (_.isSpecialized)
// creating each permutation of concrete types
def loop(ctypes: List[List[Type]]): List[List[Type]] = ctypes match {
case Nil => Nil
@@ -384,11 +382,11 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
*/
private def needsSpecialization(env: TypeEnv, sym: Symbol): Boolean = {
specializedTypeVars(sym).intersect(env.keySet).diff(wasSpecializedForTypeVars(sym)).nonEmpty ||
- (sym.isClassConstructor && (sym.enclClass.typeParams exists isSpecialized)) ||
+ (sym.isClassConstructor && (sym.enclClass.typeParams exists (_.isSpecialized))) ||
(isNormalizedMember(sym) && info(sym).typeBoundsIn(env))
}
- def isNormalizedMember(m: Symbol) = hasSpecializedFlag(m) && (info get m exists {
+ def isNormalizedMember(m: Symbol) = m.isSpecialized && (info get m exists {
case NormalizedMember(_) => true
case _ => false
})
@@ -409,14 +407,14 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
case TypeRef(pre, sym, args) =>
if (sym.isAliasType)
specializedTypeVars(tpe.normalize)
- else if (sym.isTypeParameter && isSpecialized(sym) || (sym.isTypeSkolem && isSpecialized(sym.deSkolemize)))
+ else if (sym.isTypeParameter && sym.isSpecialized || (sym.isTypeSkolem && sym.deSkolemize.isSpecialized))
Set(sym)
else if (sym == ArrayClass)
specializedTypeVars(args)
else if (args.isEmpty)
Set()
else
- specializedTypeVars(sym.typeParams zip args collect { case (tp, arg) if isSpecialized(tp) => arg })
+ specializedTypeVars(sym.typeParams zip args collect { case (tp, arg) if tp.isSpecialized => arg })
case PolyType(tparams, resTpe) => specializedTypeVars(resTpe :: tparams.map(_.info))
// since this method may be run at phase typer (before uncurry, where NMTs are eliminated)
@@ -450,7 +448,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
/** Type parameters that survive when specializing in the specified environment. */
def survivingParams(params: List[Symbol], env: TypeEnv) =
- params.filter(p => !isSpecialized(p) || !isScalaValueType(env(p)))
+ params.filter(p => !p.isSpecialized || !isScalaValueType(env(p)))
/** Produces the symbols from type parameters `syms` of the original owner,
* in the given type environment `env`. The new owner is `nowner`.
@@ -994,7 +992,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
* If `strict` is true, a UnifyError is thrown if unification is impossible.
*/
private def unify(tp1: Type, tp2: Type, env: TypeEnv, strict: Boolean): TypeEnv = (tp1, tp2) match {
- case (TypeRef(_, sym1, _), _) if isSpecialized(sym1) =>
+ case (TypeRef(_, sym1, _), _) if sym1.isSpecialized =>
debuglog("Unify " + tp1 + ", " + tp2)
if (isPrimitiveValueClass(tp2.typeSymbol) || isSpecializedAnyRefSubtype(tp2, sym1))
env + ((sym1, tp2))
@@ -1235,13 +1233,13 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
/** Return the generic class corresponding to this specialized class. */
def originalClass(clazz: Symbol): Symbol =
- if (hasSpecializedFlag(clazz)) {
+ if (clazz.isSpecialized) {
val (originalName, _, _) = nme.splitSpecializedName(clazz.name)
clazz.owner.info.decl(originalName).suchThat(_.isClass)
} else NoSymbol
def illegalSpecializedInheritance(clazz: Symbol): Boolean = (
- hasSpecializedFlag(clazz)
+ clazz.isSpecialized
&& originalClass(clazz).parentSymbols.exists(p => hasSpecializedParams(p) && !p.isTrait)
)