diff options
author | Paul Phillips <paulp@improving.org> | 2012-02-18 22:55:34 -0800 |
---|---|---|
committer | Paul Phillips <paulp@improving.org> | 2012-02-18 23:48:26 -0800 |
commit | ec160bae7e2935d98bf71cfb6dcba61f1979b854 (patch) | |
tree | 11ed857d21aaac691481e12eabfc53a4446065d4 /src/compiler | |
parent | 0d19fe04eb43d39bdceab570fb5400a3a4b072ea (diff) | |
download | scala-ec160bae7e2935d98bf71cfb6dcba61f1979b854.tar.gz scala-ec160bae7e2935d98bf71cfb6dcba61f1979b854.tar.bz2 scala-ec160bae7e2935d98bf71cfb6dcba61f1979b854.zip |
More on SI-5500.
A reimagining of erik's patch in 1df4fc6e59 . He did the hard
part, this is the batman reboot. I added more tests and tried
to make the anyref caching code less fragile.
Diffstat (limited to 'src/compiler')
4 files changed, 41 insertions, 34 deletions
diff --git a/src/compiler/scala/reflect/internal/NameManglers.scala b/src/compiler/scala/reflect/internal/NameManglers.scala index 97a74c2383..c4ee7254dc 100644 --- a/src/compiler/scala/reflect/internal/NameManglers.scala +++ b/src/compiler/scala/reflect/internal/NameManglers.scala @@ -76,12 +76,14 @@ trait NameManglers { val PROTECTED_PREFIX = "protected$" val PROTECTED_SET_PREFIX = PROTECTED_PREFIX + "set" val SINGLETON_SUFFIX = ".type" - val SPECIALIZED_SUFFIX_STRING = "$sp" val SUPER_PREFIX_STRING = "super$" val TRAIT_SETTER_SEPARATOR_STRING = "$_setter_$" + val SETTER_SUFFIX: TermName = encode("_=") - val SETTER_SUFFIX: TermName = encode("_=") - val SPECIALIZED_SUFFIX_NAME: TermName = SPECIALIZED_SUFFIX_STRING + @deprecated("2.10.0", "Use SPECIALIZED_SUFFIX") + def SPECIALIZED_SUFFIX_STRING = SPECIALIZED_SUFFIX.toString + @deprecated("2.10.0", "Use SPECIALIZED_SUFFIX") + def SPECIALIZED_SUFFIX_NAME: TermName = SPECIALIZED_SUFFIX.toTermName def isConstructorName(name: Name) = name == CONSTRUCTOR || name == MIXIN_CONSTRUCTOR def isExceptionResultName(name: Name) = name startsWith EXCEPTION_RESULT_PREFIX @@ -120,7 +122,7 @@ trait NameManglers { } def unspecializedName(name: Name): Name = ( - if (name endsWith SPECIALIZED_SUFFIX_NAME) + if (name endsWith SPECIALIZED_SUFFIX) name.subName(0, name.lastIndexOf('m') - 1) else name ) @@ -140,8 +142,8 @@ trait NameManglers { * and another one belonging to the enclosing class, on Double. */ def splitSpecializedName(name: Name): (Name, String, String) = - if (name endsWith SPECIALIZED_SUFFIX_NAME) { - val name1 = name dropRight SPECIALIZED_SUFFIX_NAME.length + if (name endsWith SPECIALIZED_SUFFIX) { + val name1 = name dropRight SPECIALIZED_SUFFIX.length val idxC = name1 lastIndexOf 'c' val idxM = name1 lastIndexOf 'm' diff --git a/src/compiler/scala/reflect/internal/StdNames.scala b/src/compiler/scala/reflect/internal/StdNames.scala index b4c404a80c..f61fe7a457 100644 --- a/src/compiler/scala/reflect/internal/StdNames.scala +++ b/src/compiler/scala/reflect/internal/StdNames.scala @@ -99,6 +99,7 @@ trait StdNames extends NameManglers { self: SymbolTable => val MODULE_VAR_SUFFIX: NameType = "$module" val ROOT: NameType = "<root>" val PACKAGE: NameType = "package" + val SPECIALIZED_SUFFIX: NameType = "$sp" // value types (and AnyRef) are all used as terms as well // as (at least) arguments to the @specialize annotation. diff --git a/src/compiler/scala/reflect/internal/Symbols.scala b/src/compiler/scala/reflect/internal/Symbols.scala index b3ff2c6329..8e9788e8b6 100644 --- a/src/compiler/scala/reflect/internal/Symbols.scala +++ b/src/compiler/scala/reflect/internal/Symbols.scala @@ -1383,15 +1383,25 @@ trait Symbols extends api.Symbols { self: SymbolTable => cloneSymbol(owner) /** A clone of this symbol, but with given owner. */ - final def cloneSymbol(owner: Symbol): Symbol = cloneSymbol(owner, this.rawflags) - final def cloneSymbol(owner: Symbol, newFlags: Long): Symbol = { - val newSym = cloneSymbolImpl(owner, newFlags) - ( newSym + final def cloneSymbol(newOwner: Symbol): Symbol = + cloneSymbol(newOwner, this.rawflags) + final def cloneSymbol(newOwner: Symbol, newFlags: Long): Symbol = + cloneSymbol(newOwner, newFlags, nme.NO_NAME) + final def cloneSymbol(newOwner: Symbol, newFlags: Long, newName: Name): Symbol = { + val clone = cloneSymbolImpl(newOwner, newFlags) + ( clone setPrivateWithin privateWithin - setInfo (info cloneInfo newSym) + setInfo (this.info cloneInfo clone) setAnnotations this.annotations ) + if (clone.thisSym != clone) + clone.typeOfThis = (clone.typeOfThis cloneInfo clone) + if (newName != nme.NO_NAME) + clone.name = newName + + clone } + /** Internal method to clone a symbol's implementation with the given flags and no info. */ def cloneSymbolImpl(owner: Symbol, newFlags: Long): Symbol def cloneSymbolImpl(owner: Symbol): Symbol = cloneSymbolImpl(owner, 0L) @@ -2327,7 +2337,7 @@ trait Symbols extends api.Symbols { self: SymbolTable => */ def existentialBound: Type = abort("unexpected type: "+this.getClass+ " "+debugLocationString) - override def name: TypeName = super.name.asInstanceOf[TypeName] + override def name: TypeName = super.name.toTypeName final override def isType = true override def isNonClassType = true override def isAbstractType = { diff --git a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala index 468518d938..3254844344 100644 --- a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala +++ b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala @@ -87,10 +87,9 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { /** Map class symbols to the type environments where they were created. */ private val typeEnv = mutable.HashMap[Symbol, TypeEnv]() withDefaultValue emptyEnv - // holds mappings from regular type parameter symbols and their class to - // symbols of specialized type parameters which are subtypes of AnyRef - // e.g. (sym, clazz) => specializedSym - private val anyrefSpecCache = perRunCaches.newMap[(Symbol, Symbol), Symbol]() + // Key: a specialized class or method + // Value: a map from tparams in the original class to tparams in the specialized class. + private val anyrefSpecCache = perRunCaches.newMap[Symbol, mutable.Map[Symbol, Symbol]]() // holds mappings from members to the type variables in the class // that they were already specialized for, so that they don't get @@ -432,29 +431,24 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { case _ => Set() } - /** Returns the type parameter in the specialized class `clazz` that corresponds to type parameter - * `sym` in the original class. It will create it if needed or use the one from the cache. + /** Returns the type parameter in the specialized class `sClass` that corresponds to type parameter + * `tparam` in the original class. It will create it if needed or use the one from the cache. */ - private def typeParamSubAnyRef(sym: Symbol, clazz: Symbol) = ( - anyrefSpecCache.getOrElseUpdate((sym, clazz), - clazz.newTypeParameter(sym.name append nme.SPECIALIZED_SUFFIX_NAME toTypeName, sym.pos) - setInfo TypeBounds(sym.info.bounds.lo, AnyRefClass.tpe) + private def typeParamSubAnyRef(tparam: Symbol, sClass: Symbol): Type = { + val sClassMap = anyrefSpecCache.getOrElseUpdate(sClass, mutable.Map[Symbol, Symbol]()) + + sClassMap.getOrElseUpdate(tparam, + tparam.cloneSymbol(sClass, tparam.flags, tparam.name append tpnme.SPECIALIZED_SUFFIX) + modifyInfo (info => TypeBounds(info.bounds.lo, AnyRefClass.tpe)) ).tpe - ) + } /** Cleans the anyrefSpecCache of all type parameter symbols of a class. */ - private def cleanAnyRefSpecCache(clazz: Symbol, decls: List[Symbol]) = ( + private def cleanAnyRefSpecCache(clazz: Symbol, decls: List[Symbol]) { // remove class type parameters and those of normalized members. - clazz :: decls foreach { - _.tpe match { - case PolyType(tparams, _) => tparams.foreach { - s => anyrefSpecCache.remove((s, clazz)) - } - case _ => () - } - } - ) + clazz :: decls foreach (anyrefSpecCache remove _) + } /** Type parameters that survive when specializing in the specified environment. */ def survivingParams(params: List[Symbol], env: TypeEnv) = @@ -1710,7 +1704,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { * - there is a getter for the specialized field in the same class */ def initializesSpecializedField(f: Symbol) = ( - (f.name endsWith nme.SPECIALIZED_SUFFIX_NAME) + (f.name endsWith nme.SPECIALIZED_SUFFIX) && clazz.info.member(nme.originalName(f.name)).isPublic && clazz.info.decl(f.name).suchThat(_.isGetter) != NoSymbol ) |