summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdriaan Moors <adriaan@lightbend.com>2016-09-28 09:40:24 -0700
committerGitHub <noreply@github.com>2016-09-28 09:40:24 -0700
commit50fca2d66388f43e4a6b4ae7cd70b5a21eb57aa3 (patch)
tree97addf829fd2766ff4c066c17cfe67a7e82b9ad2
parent1064ada823bbed74ea01d473b4f5924fac3a60a4 (diff)
parente07585c256b3dd2ab4d197c5480d1d962607879e (diff)
downloadscala-50fca2d66388f43e4a6b4ae7cd70b5a21eb57aa3.tar.gz
scala-50fca2d66388f43e4a6b4ae7cd70b5a21eb57aa3.tar.bz2
scala-50fca2d66388f43e4a6b4ae7cd70b5a21eb57aa3.zip
Merge pull request #5412 from retronym/ticket/SD-226
Be lazier in Fields info transform for better performance Fix scala-dev#226
-rw-r--r--src/compiler/scala/tools/nsc/transform/Fields.scala9
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/RefChecks.scala11
2 files changed, 19 insertions, 1 deletions
diff --git a/src/compiler/scala/tools/nsc/transform/Fields.scala b/src/compiler/scala/tools/nsc/transform/Fields.scala
index f75e6f5efa..6cf6a5abce 100644
--- a/src/compiler/scala/tools/nsc/transform/Fields.scala
+++ b/src/compiler/scala/tools/nsc/transform/Fields.scala
@@ -305,6 +305,10 @@ abstract class Fields extends InfoTransform with ast.TreeDSL with TypingTransfor
lazyCallingSuper setInfo tp
}
+ private def classNeedsInfoTransform(cls: Symbol): Boolean = {
+ !(cls.isPackageClass || cls.isJavaDefined) && (currentRun.compiles(cls) || refChecks.isSeparatelyCompiledScalaSuperclass(cls))
+ }
+
def apply(tp0: Type): Type = tp0 match {
// TODO: make less destructive (name changes, decl additions, flag setting --
// none of this is actually undone when travelling back in time using atPhase)
@@ -360,9 +364,12 @@ abstract class Fields extends InfoTransform with ast.TreeDSL with TypingTransfor
ClassInfoType(parents, allDecls, clazz)
} else tp
+
+ case tp@ClassInfoType(parents, oldDecls, clazz) if !classNeedsInfoTransform(clazz) => tp
+
// mix in fields & accessors for all mixed in traits
+ case tp@ClassInfoType(parents, oldDecls, clazz) =>
- case tp@ClassInfoType(parents, oldDecls, clazz) if !clazz.isPackageClass =>
val site = clazz.thisType
// setter conflicts cannot arise independently from a getter conflict, since a setter without a getter does not a val definition make
diff --git a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
index 8034d056d7..106b076eef 100644
--- a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
@@ -95,6 +95,15 @@ abstract class RefChecks extends Transform {
)
}
+ private val separatelyCompiledScalaSuperclass = perRunCaches.newAnyRefMap[Symbol, Unit]()
+ final def isSeparatelyCompiledScalaSuperclass(sym: Symbol) = if (globalPhase.refChecked){
+ separatelyCompiledScalaSuperclass.contains(sym)
+ } else {
+ // conservative approximation in case someone in pre-refchecks phase asks for `exitingFields(someClass.info)`
+ // and we haven't run the refchecks tree transform which populates `separatelyCompiledScalaSuperclass`
+ false
+ }
+
class RefCheckTransformer(unit: CompilationUnit) extends Transformer {
var localTyper: analyzer.Typer = typer
@@ -854,6 +863,8 @@ abstract class RefChecks extends Transform {
// println("validate base type "+tp)
val baseClass = tp.typeSymbol
if (baseClass.isClass) {
+ if (!baseClass.isTrait && !baseClass.isJavaDefined && !currentRun.compiles(baseClass) && !separatelyCompiledScalaSuperclass.contains(baseClass))
+ separatelyCompiledScalaSuperclass.update(baseClass, ())
val index = clazz.info.baseTypeIndex(baseClass)
if (index >= 0) {
if (seenTypes(index) forall (tp1 => !(tp1 <:< tp)))