diff options
author | Martin Odersky <odersky@gmail.com> | 2015-11-07 19:09:07 +0100 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2015-11-09 15:45:39 +0100 |
commit | 5398c5a723b0f8b0d35e6c3ad230c5046169e837 (patch) | |
tree | 832f93128ce25194d9418b682f4e248adba51dd4 /src/dotty | |
parent | 5db52d25256568cf7d8c2335ee733a38b059b5ad (diff) | |
download | dotty-5398c5a723b0f8b0d35e6c3ad230c5046169e837.tar.gz dotty-5398c5a723b0f8b0d35e6c3ad230c5046169e837.tar.bz2 dotty-5398c5a723b0f8b0d35e6c3ad230c5046169e837.zip |
Avoid overhead of generating symbol sets on each access
1) Have symbol sets cached per run
2) Use methods Denotation#isPrimitiveValueClass, Denotation#isNumericValueClass
instead of calling contains directly on symbol sets.
Diffstat (limited to 'src/dotty')
-rw-r--r-- | src/dotty/tools/backend/jvm/DottyBackendInterface.scala | 5 | ||||
-rw-r--r-- | src/dotty/tools/dotc/ast/tpd.scala | 3 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/Definitions.scala | 44 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/SymDenotations.scala | 6 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/Types.scala | 4 | ||||
-rw-r--r-- | src/dotty/tools/dotc/transform/CapturedVars.scala | 2 | ||||
-rw-r--r-- | src/dotty/tools/dotc/transform/ClassTags.scala | 2 | ||||
-rw-r--r-- | src/dotty/tools/dotc/transform/Erasure.scala | 6 | ||||
-rw-r--r-- | src/dotty/tools/dotc/transform/ExtensionMethods.scala | 5 | ||||
-rw-r--r-- | src/dotty/tools/dotc/transform/InterceptedMethods.scala | 4 | ||||
-rw-r--r-- | src/dotty/tools/dotc/transform/PatternMatcher.scala | 2 | ||||
-rw-r--r-- | src/dotty/tools/dotc/transform/TreeChecker.scala | 2 |
12 files changed, 49 insertions, 36 deletions
diff --git a/src/dotty/tools/backend/jvm/DottyBackendInterface.scala b/src/dotty/tools/backend/jvm/DottyBackendInterface.scala index 09313b0a2..fb84377d7 100644 --- a/src/dotty/tools/backend/jvm/DottyBackendInterface.scala +++ b/src/dotty/tools/backend/jvm/DottyBackendInterface.scala @@ -148,11 +148,10 @@ class DottyBackendInterface()(implicit ctx: Context) extends BackendInterface{ lazy val AnnotationRetentionRuntimeAttr = ctx.requiredClass("java.lang.annotation.RetentionPolicy").linkedClass.requiredValue("RUNTIME") lazy val JavaAnnotationClass = ctx.requiredClass("java.lang.annotation.Annotation") - - def boxMethods: Map[Symbol, Symbol] = defn.ScalaValueClasses.map{x => + def boxMethods: Map[Symbol, Symbol] = defn.ScalaValueClasses().map{x => // @darkdimius Are you sure this should be a def? (x, Erasure.Boxing.boxMethod(x.asClass)) }.toMap - def unboxMethods: Map[Symbol, Symbol] = defn.ScalaValueClasses.map(x => (x, Erasure.Boxing.unboxMethod(x.asClass))).toMap + def unboxMethods: Map[Symbol, Symbol] = defn.ScalaValueClasses().map(x => (x, Erasure.Boxing.unboxMethod(x.asClass))).toMap private val mkArrayNames: Set[Name] = Set("Byte", "Float", "Char", "Double", "Boolean", "Unit", "Long", "Int", "Short", "Ref").map{ x=> ("new" + x + "Array").toTermName diff --git a/src/dotty/tools/dotc/ast/tpd.scala b/src/dotty/tools/dotc/ast/tpd.scala index c1c8c3d51..a945f8ba9 100644 --- a/src/dotty/tools/dotc/ast/tpd.scala +++ b/src/dotty/tools/dotc/ast/tpd.scala @@ -2,7 +2,7 @@ package dotty.tools package dotc package ast -import dotty.tools.dotc.transform.ExplicitOuter +import dotty.tools.dotc.transform.{ExplicitOuter, Erasure} import dotty.tools.dotc.typer.ProtoTypes.FunProtoTyped import transform.SymUtils._ import core._ @@ -13,7 +13,6 @@ import config.Printers._ import typer.Mode import collection.mutable import typer.ErrorReporting._ -import transform.Erasure import scala.annotation.tailrec diff --git a/src/dotty/tools/dotc/core/Definitions.scala b/src/dotty/tools/dotc/core/Definitions.scala index d57897eb1..66e5f062d 100644 --- a/src/dotty/tools/dotc/core/Definitions.scala +++ b/src/dotty/tools/dotc/core/Definitions.scala @@ -3,7 +3,7 @@ package dotc package core import Types._, Contexts._, Symbols._, Denotations._, SymDenotations._, StdNames._, Names._ -import Flags._, Scopes._, Decorators._, NameOps._, util.Positions._ +import Flags._, Scopes._, Decorators._, NameOps._, util.Positions._, Periods._ import unpickleScala2.Scala2Unpickler.ensureConstructor import scala.annotation.{ switch, meta } import scala.collection.{ mutable, immutable } @@ -558,15 +558,17 @@ class Definitions { private lazy val TupleTypeRefs: Set[TypeRef] = TupleTypeRef.toSet private lazy val ProductTypeRefs: Set[TypeRef] = ProductNTypeRef.toSet - /** If type refers to a class in the scala package, its name, otherwise EmptyTypeName */ - def scalaClassName(ref: Type)(implicit ctx: Context): TypeName = { - val cls = ref.classSymbol + /** If `cls` is a class in the scala package, its name, otherwise EmptyTypeName */ + def scalaClassName(cls: Symbol)(implicit ctx: Context): TypeName = if (cls.isClass && cls.owner == ScalaPackageClass) cls.asClass.name else EmptyTypeName - } - def isVarArityClass(cls: Symbol, prefix: Name) = - cls.owner == ScalaPackageClass && cls.name.startsWith(prefix) && - cls.name.drop(prefix.length).forall(_.isDigit) + /** If type `ref` refers to a class in the scala package, its name, otherwise EmptyTypeName */ + def scalaClassName(ref: Type)(implicit ctx: Context): TypeName = scalaClassName(ref.classSymbol) + + private def isVarArityClass(cls: Symbol, prefix: Name) = { + val name = scalaClassName(cls) + name.startsWith(prefix) && name.drop(prefix.length).forall(_.isDigit) + } def isFunctionClass(cls: Symbol) = isVarArityClass(cls, tpnme.Function) def isAbstractFunctionClass(cls: Symbol) = isVarArityClass(cls, tpnme.AbstractFunction) @@ -676,6 +678,18 @@ class Definitions { // ----- primitive value class machinery ------------------------------------------ + class SymbolsPerRun(generate: Context => collection.Set[Symbol]) { + private var current: RunId = NoRunId + private var syms: collection.Set[Symbol] = _ + def apply()(implicit ctx: Context) = { + if (current != ctx.runId) { + syms = generate(ctx) + current = ctx.runId + } + syms + } + } + lazy val ScalaNumericValueTypeList = List( ByteTypeRef, ShortTypeRef, @@ -686,12 +700,12 @@ class Definitions { DoubleTypeRef) private lazy val ScalaNumericValueTypes: collection.Set[TypeRef] = ScalaNumericValueTypeList.toSet - def ScalaNumericValueClasses = ScalaNumericValueTypes.map(_.symbol) private lazy val ScalaValueTypes: collection.Set[TypeRef] = ScalaNumericValueTypes + UnitTypeRef + BooleanTypeRef - def ScalaValueClasses = ScalaValueTypes.map(_.symbol) + private lazy val ScalaBoxedTypeRefs = ScalaValueTypes map (t => boxedTypeRef(t.name)) - lazy val ScalaBoxedTypeRefs = ScalaValueTypes map (t => boxedTypeRef(t.name)) - def ScalaBoxedClasses = ScalaBoxedTypeRefs.map(_.symbol) + val ScalaNumericValueClasses = new SymbolsPerRun(implicit ctx => ScalaNumericValueTypes.map(_.symbol)) + val ScalaValueClasses = new SymbolsPerRun(implicit ctx => ScalaValueTypes.map(_.symbol)) + val ScalaBoxedClasses = new SymbolsPerRun(implicit ctx => ScalaBoxedTypeRefs.map(_.symbol)) private val boxedTypeRef = mutable.Map[TypeName, TypeRef]() private val valueTypeEnc = mutable.Map[TypeName, PrimitiveClassEnc]() @@ -735,7 +749,7 @@ class Definitions { def isValueSubType(tref1: TypeRef, tref2: TypeRef)(implicit ctx: Context) = valueTypeEnc(tref2.name) % valueTypeEnc(tref1.name) == 0 def isValueSubClass(sym1: Symbol, sym2: Symbol) = - isValueSubType(sym1.typeRef, sym2.typeRef) + valueTypeEnc(sym2.asClass.name) % valueTypeEnc(sym1.asClass.name) == 0 // ----- Initialization --------------------------------------------------- @@ -757,13 +771,13 @@ class Definitions { lazy val syntheticCoreMethods = AnyMethods ++ ObjectMethods ++ List(String_+) private[this] var _isInitialized = false - def isInitialized = _isInitialized + private def isInitialized = _isInitialized def init(implicit ctx: Context) = { this.ctx = ctx if (!_isInitialized) { // force initialization of every symbol that is synthesized or hijacked by the compiler - val forced = syntheticCoreClasses ++ syntheticCoreMethods ++ ScalaValueClasses + val forced = syntheticCoreClasses ++ syntheticCoreMethods ++ ScalaValueClasses() _isInitialized = true } } diff --git a/src/dotty/tools/dotc/core/SymDenotations.scala b/src/dotty/tools/dotc/core/SymDenotations.scala index 20d674b86..a74cf0000 100644 --- a/src/dotty/tools/dotc/core/SymDenotations.scala +++ b/src/dotty/tools/dotc/core/SymDenotations.scala @@ -417,10 +417,12 @@ object SymDenotations { name.toTermName == nme.EVT2U /** Is symbol a primitive value class? */ - def isPrimitiveValueClass(implicit ctx: Context) = defn.ScalaValueClasses contains symbol + def isPrimitiveValueClass(implicit ctx: Context) = + maybeOwner == defn.ScalaPackageClass && defn.ScalaValueClasses().contains(symbol) /** Is symbol a primitive numeric value class? */ - def isNumericValueClass(implicit ctx: Context) = defn.ScalaNumericValueClasses contains symbol + def isNumericValueClass(implicit ctx: Context) = + maybeOwner == defn.ScalaPackageClass && defn.ScalaNumericValueClasses().contains(symbol) /** Is symbol a phantom class for which no runtime representation exists? */ def isPhantomClass(implicit ctx: Context) = defn.PhantomClasses contains symbol diff --git a/src/dotty/tools/dotc/core/Types.scala b/src/dotty/tools/dotc/core/Types.scala index bfff1a448..a9956c433 100644 --- a/src/dotty/tools/dotc/core/Types.scala +++ b/src/dotty/tools/dotc/core/Types.scala @@ -607,9 +607,9 @@ object Types { /** Is this type a primitive value type which can be widened to the primitive value type `that`? */ def isValueSubType(that: Type)(implicit ctx: Context) = widen match { - case self: TypeRef if defn.ScalaValueClasses contains self.symbol => + case self: TypeRef if self.symbol.isPrimitiveValueClass => that.widenExpr match { - case that: TypeRef if defn.ScalaValueClasses contains that.symbol => + case that: TypeRef if that.symbol.isPrimitiveValueClass => defn.isValueSubClass(self.symbol, that.symbol) case _ => false diff --git a/src/dotty/tools/dotc/transform/CapturedVars.scala b/src/dotty/tools/dotc/transform/CapturedVars.scala index 9d6acb4b9..cd05589c3 100644 --- a/src/dotty/tools/dotc/transform/CapturedVars.scala +++ b/src/dotty/tools/dotc/transform/CapturedVars.scala @@ -27,7 +27,7 @@ class CapturedVars extends MiniPhase with IdentityDenotTransformer { thisTransfo private class RefInfo(implicit ctx: Context) { /** The classes for which a Ref type exists. */ val refClassKeys: collection.Set[Symbol] = - defn.ScalaNumericValueClasses + defn.BooleanClass + defn.ObjectClass + defn.ScalaNumericValueClasses() + defn.BooleanClass + defn.ObjectClass val refClass: Map[Symbol, Symbol] = refClassKeys.map(rc => rc -> ctx.requiredClass(s"scala.runtime.${rc.name}Ref")).toMap diff --git a/src/dotty/tools/dotc/transform/ClassTags.scala b/src/dotty/tools/dotc/transform/ClassTags.scala index c6d33fcae..2ad348b05 100644 --- a/src/dotty/tools/dotc/transform/ClassTags.scala +++ b/src/dotty/tools/dotc/transform/ClassTags.scala @@ -51,7 +51,7 @@ class ClassTags extends MiniPhaseTransform with IdentityDenotTransformer { thisT val claz = tp.classSymbol val elemClaz = elemType.classSymbol assert(!claz.isPrimitiveValueClass) // should be inserted by typer - val elemTag = if (defn.ScalaValueClasses.contains(elemClaz) || elemClaz == defn.NothingClass || elemClaz == defn.NullClass) + val elemTag = if (elemClaz.isPrimitiveValueClass || elemClaz == defn.NothingClass || elemClaz == defn.NullClass) ref(defn.DottyPredefModule).select(s"${elemClaz.name}ClassTag".toTermName) else if (ValueClasses.isDerivedValueClass(elemClaz)) ref(claz.companionModule) else if (elemClaz eq defn.AnyClass) ref(scala2ClassTagModule).select(nme.Any) diff --git a/src/dotty/tools/dotc/transform/Erasure.scala b/src/dotty/tools/dotc/transform/Erasure.scala index a540dafb0..1b9b898f2 100644 --- a/src/dotty/tools/dotc/transform/Erasure.scala +++ b/src/dotty/tools/dotc/transform/Erasure.scala @@ -119,10 +119,10 @@ object Erasure extends TypeTestsCasts{ object Boxing { def isUnbox(sym: Symbol)(implicit ctx: Context) = - sym.name == nme.unbox && (defn.ScalaValueClasses contains sym.owner.linkedClass) + sym.name == nme.unbox && sym.owner.linkedClass.isPrimitiveValueClass def isBox(sym: Symbol)(implicit ctx: Context) = - sym.name == nme.box && (defn.ScalaValueClasses contains sym.owner.linkedClass) + sym.name == nme.box && sym.owner.linkedClass.isPrimitiveValueClass def boxMethod(cls: ClassSymbol)(implicit ctx: Context) = cls.linkedClass.info.member(nme.box).symbol @@ -138,7 +138,7 @@ object Erasure extends TypeTestsCasts{ */ private def safelyRemovableUnboxArg(tree: Tree)(implicit ctx: Context): Tree = tree match { case Apply(fn, arg :: Nil) - if isUnbox(fn.symbol) && (defn.ScalaBoxedClasses contains arg.tpe.widen.typeSymbol) => + if isUnbox(fn.symbol) && defn.ScalaBoxedClasses().contains(arg.tpe.widen.typeSymbol) => arg case _ => EmptyTree diff --git a/src/dotty/tools/dotc/transform/ExtensionMethods.scala b/src/dotty/tools/dotc/transform/ExtensionMethods.scala index 02c01bca8..90e105ee7 100644 --- a/src/dotty/tools/dotc/transform/ExtensionMethods.scala +++ b/src/dotty/tools/dotc/transform/ExtensionMethods.scala @@ -76,9 +76,8 @@ class ExtensionMethods extends MiniPhaseTransform with DenotTransformer with Ful val underlyingCls = underlying.classSymbol val underlyingClsName = - if (defn.ScalaNumericValueClasses.contains(underlyingCls) || - underlyingCls == defn.BooleanClass) underlyingCls.name else nme.Object - + if (underlyingCls.isNumericValueClass || underlyingCls == defn.BooleanClass) underlyingCls.name + else nme.Object val syp = ctx.requiredClass(s"dotty.runtime.vc.VC${underlyingClsName}Companion").asClass diff --git a/src/dotty/tools/dotc/transform/InterceptedMethods.scala b/src/dotty/tools/dotc/transform/InterceptedMethods.scala index ff354a54c..ffb4ae756 100644 --- a/src/dotty/tools/dotc/transform/InterceptedMethods.scala +++ b/src/dotty/tools/dotc/transform/InterceptedMethods.scala @@ -51,7 +51,7 @@ class InterceptedMethods extends MiniPhaseTransform { /** perform context-dependant initialization */ override def prepareForUnit(tree: Tree)(implicit ctx: Context) = { this.Any_## = defn.Any_## - primitiveGetClassMethods = Set[Symbol]() ++ defn.ScalaValueClasses.map(x => x.requiredMethod(nme.getClass_)) + primitiveGetClassMethods = Set[Symbol]() ++ defn.ScalaValueClasses().map(x => x.requiredMethod(nme.getClass_)) this } @@ -86,7 +86,7 @@ class InterceptedMethods extends MiniPhaseTransform { def alt2 = defn.ScalaRuntimeModule.info.member(nme.hash_) .suchThat(_.info.firstParamTypes.head.typeSymbol == defn.AnyClass) - Ident((if (defn.ScalaNumericValueClasses contains s) alt1 else alt2).termRef) + Ident((if (s.isNumericValueClass) alt1 else alt2).termRef) .appliedTo(tree) } } diff --git a/src/dotty/tools/dotc/transform/PatternMatcher.scala b/src/dotty/tools/dotc/transform/PatternMatcher.scala index a47762ebe..4b45f7cc2 100644 --- a/src/dotty/tools/dotc/transform/PatternMatcher.scala +++ b/src/dotty/tools/dotc/transform/PatternMatcher.scala @@ -755,7 +755,7 @@ class PatternMatcher extends MiniPhaseTransform with DenotTransformer {thisTrans def expectedWide = expectedTp.widen def isAnyRef = testedWide <:< defn.AnyRefType def isAsExpected = testedWide <:< expectedTp - def isExpectedPrimitiveType = isAsExpected && defn.ScalaValueClasses.contains(expectedTp.classSymbol) + def isExpectedPrimitiveType = isAsExpected && expectedTp.classSymbol.isPrimitiveValueClass def isExpectedReferenceType = isAsExpected && (expectedTp <:< defn.AnyRefType) def mkNullTest = nonNullTest(testedBinder) def mkOuterTest = outerTest(testedBinder, expectedTp) diff --git a/src/dotty/tools/dotc/transform/TreeChecker.scala b/src/dotty/tools/dotc/transform/TreeChecker.scala index 1f47b4486..0084b1710 100644 --- a/src/dotty/tools/dotc/transform/TreeChecker.scala +++ b/src/dotty/tools/dotc/transform/TreeChecker.scala @@ -79,7 +79,7 @@ class TreeChecker extends Phase with SymTransformer { val sym = symd.symbol if (sym.isClass && !sym.isAbsent) { - val validSuperclass = defn.ScalaValueClasses.contains(sym) || defn.syntheticCoreClasses.contains(sym) || + val validSuperclass = sym.isPrimitiveValueClass || defn.syntheticCoreClasses.contains(sym) || (sym eq defn.ObjectClass) || (sym is NoSuperClass) || (sym.asClass.superClass.exists) if (!validSuperclass) printError(s"$sym has no superclass set") |