aboutsummaryrefslogtreecommitdiff
path: root/src/dotty
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2015-11-07 19:09:07 +0100
committerMartin Odersky <odersky@gmail.com>2015-11-09 15:45:39 +0100
commit5398c5a723b0f8b0d35e6c3ad230c5046169e837 (patch)
tree832f93128ce25194d9418b682f4e248adba51dd4 /src/dotty
parent5db52d25256568cf7d8c2335ee733a38b059b5ad (diff)
downloaddotty-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.scala5
-rw-r--r--src/dotty/tools/dotc/ast/tpd.scala3
-rw-r--r--src/dotty/tools/dotc/core/Definitions.scala44
-rw-r--r--src/dotty/tools/dotc/core/SymDenotations.scala6
-rw-r--r--src/dotty/tools/dotc/core/Types.scala4
-rw-r--r--src/dotty/tools/dotc/transform/CapturedVars.scala2
-rw-r--r--src/dotty/tools/dotc/transform/ClassTags.scala2
-rw-r--r--src/dotty/tools/dotc/transform/Erasure.scala6
-rw-r--r--src/dotty/tools/dotc/transform/ExtensionMethods.scala5
-rw-r--r--src/dotty/tools/dotc/transform/InterceptedMethods.scala4
-rw-r--r--src/dotty/tools/dotc/transform/PatternMatcher.scala2
-rw-r--r--src/dotty/tools/dotc/transform/TreeChecker.scala2
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")