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/tools/dotc/core/Definitions.scala | |
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/tools/dotc/core/Definitions.scala')
-rw-r--r-- | src/dotty/tools/dotc/core/Definitions.scala | 44 |
1 files changed, 29 insertions, 15 deletions
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 } } |