summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xbuild.xml9
-rw-r--r--src/reflect/scala/reflect/internal/SymbolTable.scala8
-rw-r--r--test/junit/scala/collection/IterableViewLikeTest.scala1
-rw-r--r--test/junit/scala/tools/nsc/backend/jvm/BTypesTest.scala52
-rw-r--r--test/junit/scala/tools/nsc/backend/jvm/DirectCompileTest.scala12
-rw-r--r--test/junit/scala/tools/nsc/backend/jvm/opt/BTypesFromClassfileTest.scala4
-rw-r--r--test/junit/scala/tools/nsc/backend/jvm/opt/EmptyExceptionHandlersTest.scala19
-rw-r--r--test/junit/scala/tools/nsc/backend/jvm/opt/InlinerIllegalAccessTest.scala12
-rw-r--r--test/junit/scala/tools/nsc/backend/jvm/opt/InlinerTest.scala29
-rw-r--r--test/junit/scala/tools/nsc/backend/jvm/opt/MethodLevelOpts.scala12
-rw-r--r--test/junit/scala/tools/nsc/backend/jvm/opt/UnreachableCodeTest.scala36
-rw-r--r--test/junit/scala/tools/nsc/backend/jvm/opt/UnusedLocalVariablesTest.scala12
-rw-r--r--test/junit/scala/tools/testing/ClearAfterClass.java20
13 files changed, 175 insertions, 51 deletions
diff --git a/build.xml b/build.xml
index 5f6b04b8e4..ee6a045bda 100755
--- a/build.xml
+++ b/build.xml
@@ -1448,6 +1448,15 @@ TODO:
<target name="test.junit.comp" depends="pack.done">
<stopwatch name="test.junit.compiler.timer"/>
<mkdir dir="${test.junit.classes}"/>
+ <javac
+ debug="true"
+ srcdir="${test.junit.src}"
+ destdir="${test.junit.classes}"
+ classpathref="test.junit.compiler.build.path"
+ target="1.6"
+ source="1.5"
+ compiler="javac1.6"
+ includes="**/*.java"/>
<scalacfork
destdir="${test.junit.classes}"
compilerpathref="quick.compiler.path"
diff --git a/src/reflect/scala/reflect/internal/SymbolTable.scala b/src/reflect/scala/reflect/internal/SymbolTable.scala
index 01e4cdf367..ef63078f90 100644
--- a/src/reflect/scala/reflect/internal/SymbolTable.scala
+++ b/src/reflect/scala/reflect/internal/SymbolTable.scala
@@ -355,6 +355,14 @@ abstract class SymbolTable extends macros.Universe
cache
}
+ /**
+ * Removes a cache from the per-run caches. This is useful for testing: it allows running the
+ * compiler and then inspect the state of a cache.
+ */
+ def unrecordCache[T <: Clearable](cache: T): Unit = {
+ caches = caches.filterNot(_.get eq cache)
+ }
+
def clearAll() = {
debuglog("Clearing " + caches.size + " caches.")
caches foreach (ref => Option(ref.get).foreach(_.clear))
diff --git a/test/junit/scala/collection/IterableViewLikeTest.scala b/test/junit/scala/collection/IterableViewLikeTest.scala
index ab09c4930b..435a43c215 100644
--- a/test/junit/scala/collection/IterableViewLikeTest.scala
+++ b/test/junit/scala/collection/IterableViewLikeTest.scala
@@ -13,6 +13,7 @@ class IterableViewLikeTest {
def hasCorrectDropAndTakeMethods() {
val iter = Iterable(1, 2, 3)
+ import scala.language.postfixOps
assertEquals(Iterable.empty[Int], iter.view take Int.MinValue force)
assertEquals(Iterable.empty[Int], iter.view takeRight Int.MinValue force)
assertEquals(iter, iter.view drop Int.MinValue force)
diff --git a/test/junit/scala/tools/nsc/backend/jvm/BTypesTest.scala b/test/junit/scala/tools/nsc/backend/jvm/BTypesTest.scala
index 2347e8288e..6ada0e20fb 100644
--- a/test/junit/scala/tools/nsc/backend/jvm/BTypesTest.scala
+++ b/test/junit/scala/tools/nsc/backend/jvm/BTypesTest.scala
@@ -7,35 +7,41 @@ import org.junit.Test
import scala.tools.asm.Opcodes
import org.junit.Assert._
-@RunWith(classOf[JUnit4])
-class BTypesTest {
- val settings = new Settings()
- settings.processArgumentString("-usejavacp")
- val g: Global = new Global(settings)
- val run = new g.Run() // initializes some compiler internals
- import g.{definitions => d, Symbol}
+import scala.tools.nsc.backend.jvm.CodeGenTools._
+import scala.tools.testing.ClearAfterClass
- def duringBackend[T](f: => T) = g.exitingDelambdafy(f)
+object BTypesTest extends ClearAfterClass.Clearable {
+ var compiler = {
+ val comp = newCompiler(extraArgs = "-Ybackend:GenBCode -Yopt:l:none")
+ new comp.Run() // initializes some of the compiler
+ comp.exitingDelambdafy(comp.scalaPrimitives.init()) // needed: it's only done when running the backend, and we don't actually run the compiler
+ comp.exitingDelambdafy(comp.genBCode.bTypes.initializeCoreBTypes())
+ comp
+ }
+ def clear(): Unit = { compiler = null }
+}
- val btypes = new BTypesFromSymbols[g.type](g)
- import btypes._
- duringBackend(btypes.initializeCoreBTypes())
+@RunWith(classOf[JUnit4])
+class BTypesTest extends ClearAfterClass {
+ ClearAfterClass.stateToClear = BTypesTest
- def classBTypeFromSymbol(sym: Symbol) = duringBackend(btypes.classBTypeFromSymbol(sym))
+ val compiler = BTypesTest.compiler
+ import compiler.genBCode.bTypes._
- val jlo = d.ObjectClass
- val jls = d.StringClass
+ def classBTFS(sym: compiler.Symbol) = compiler.exitingDelambdafy(classBTypeFromSymbol(sym))
- val o = classBTypeFromSymbol(jlo)
- val s = classBTypeFromSymbol(jls)
- val oArr = ArrayBType(o)
- val method = MethodBType(List(oArr, INT, DOUBLE, s), UNIT)
+ def jlo = compiler.definitions.ObjectClass
+ def jls = compiler.definitions.StringClass
+ def o = classBTFS(jlo)
+ def s = classBTFS(jls)
+ def oArr = ArrayBType(o)
+ def method = MethodBType(List(oArr, INT, DOUBLE, s), UNIT)
@Test
def classBTypesEquality() {
- val s1 = classBTypeFromSymbol(jls)
- val s2 = classBTypeFromSymbol(jls)
- val o = classBTypeFromSymbol(jlo)
+ val s1 = classBTFS(jls)
+ val s2 = classBTFS(jls)
+ val o = classBTFS(jlo)
assertEquals(s1, s2)
assertEquals(s1.hashCode, s2.hashCode)
assert(s1 != o)
@@ -53,7 +59,7 @@ class BTypesTest {
assert(FLOAT.typedOpcode(Opcodes.IALOAD) == Opcodes.FALOAD)
assert(LONG.typedOpcode(Opcodes.IALOAD) == Opcodes.LALOAD)
assert(DOUBLE.typedOpcode(Opcodes.IALOAD) == Opcodes.DALOAD)
- assert(classBTypeFromSymbol(jls).typedOpcode(Opcodes.IALOAD) == Opcodes.AALOAD)
+ assert(classBTFS(jls).typedOpcode(Opcodes.IALOAD) == Opcodes.AALOAD)
assert(UNIT.typedOpcode(Opcodes.IRETURN) == Opcodes.RETURN)
assert(BOOL.typedOpcode(Opcodes.IRETURN) == Opcodes.IRETURN)
@@ -64,7 +70,7 @@ class BTypesTest {
assert(FLOAT.typedOpcode(Opcodes.IRETURN) == Opcodes.FRETURN)
assert(LONG.typedOpcode(Opcodes.IRETURN) == Opcodes.LRETURN)
assert(DOUBLE.typedOpcode(Opcodes.IRETURN) == Opcodes.DRETURN)
- assert(classBTypeFromSymbol(jls).typedOpcode(Opcodes.IRETURN) == Opcodes.ARETURN)
+ assert(classBTFS(jls).typedOpcode(Opcodes.IRETURN) == Opcodes.ARETURN)
}
@Test
diff --git a/test/junit/scala/tools/nsc/backend/jvm/DirectCompileTest.scala b/test/junit/scala/tools/nsc/backend/jvm/DirectCompileTest.scala
index 89900291ca..3b1b009037 100644
--- a/test/junit/scala/tools/nsc/backend/jvm/DirectCompileTest.scala
+++ b/test/junit/scala/tools/nsc/backend/jvm/DirectCompileTest.scala
@@ -7,10 +7,18 @@ import org.junit.Assert._
import CodeGenTools._
import scala.tools.asm.Opcodes._
import scala.tools.partest.ASMConverters._
+import scala.tools.testing.ClearAfterClass
+
+object DirectCompileTest extends ClearAfterClass.Clearable {
+ var compiler = newCompiler(extraArgs = "-Ybackend:GenBCode -Yopt:l:method")
+ def clear(): Unit = { compiler = null }
+}
@RunWith(classOf[JUnit4])
-class DirectCompileTest {
- val compiler = newCompiler(extraArgs = "-Ybackend:GenBCode -Yopt:l:method")
+class DirectCompileTest extends ClearAfterClass {
+ ClearAfterClass.stateToClear = DirectCompileTest
+
+ val compiler = DirectCompileTest.compiler
@Test
def testCompile(): Unit = {
diff --git a/test/junit/scala/tools/nsc/backend/jvm/opt/BTypesFromClassfileTest.scala b/test/junit/scala/tools/nsc/backend/jvm/opt/BTypesFromClassfileTest.scala
index 2975bd060d..4481fcd6be 100644
--- a/test/junit/scala/tools/nsc/backend/jvm/opt/BTypesFromClassfileTest.scala
+++ b/test/junit/scala/tools/nsc/backend/jvm/opt/BTypesFromClassfileTest.scala
@@ -19,7 +19,8 @@ import scala.collection.convert.decorateAsScala._
@RunWith(classOf[JUnit4])
class BTypesFromClassfileTest {
- val compiler = newCompiler(extraArgs = "-Ybackend:GenBCode")
+ // inliner enabled -> inlineInfos are collected (and compared) in ClassBTypes
+ val compiler = newCompiler(extraArgs = "-Ybackend:GenBCode -Yopt:inline-global")
import compiler._
import definitions._
@@ -29,6 +30,7 @@ class BTypesFromClassfileTest {
def duringBackend[T](f: => T) = compiler.exitingDelambdafy(f)
val run = new compiler.Run() // initializes some of the compiler
+ duringBackend(compiler.scalaPrimitives.init()) // needed: it's only done when running the backend, and we don't actually run the compiler
duringBackend(bTypes.initializeCoreBTypes())
def clearCache() = bTypes.classBTypeFromInternalName.clear()
diff --git a/test/junit/scala/tools/nsc/backend/jvm/opt/EmptyExceptionHandlersTest.scala b/test/junit/scala/tools/nsc/backend/jvm/opt/EmptyExceptionHandlersTest.scala
index 7d83c54b5b..7b0504fec0 100644
--- a/test/junit/scala/tools/nsc/backend/jvm/opt/EmptyExceptionHandlersTest.scala
+++ b/test/junit/scala/tools/nsc/backend/jvm/opt/EmptyExceptionHandlersTest.scala
@@ -11,9 +11,23 @@ import org.junit.Assert._
import CodeGenTools._
import scala.tools.partest.ASMConverters
import ASMConverters._
+import scala.tools.testing.ClearAfterClass
+
+object EmptyExceptionHandlersTest extends ClearAfterClass.Clearable {
+ var noOptCompiler = newCompiler(extraArgs = "-Ybackend:GenBCode -Yopt:l:none")
+ var dceCompiler = newCompiler(extraArgs = "-Ybackend:GenBCode -Yopt:unreachable-code")
+ def clear(): Unit = {
+ noOptCompiler = null
+ dceCompiler = null
+ }
+}
@RunWith(classOf[JUnit4])
-class EmptyExceptionHandlersTest {
+class EmptyExceptionHandlersTest extends ClearAfterClass {
+ ClearAfterClass.stateToClear = EmptyExceptionHandlersTest
+
+ val noOptCompiler = EmptyExceptionHandlersTest.noOptCompiler
+ val dceCompiler = EmptyExceptionHandlersTest.dceCompiler
val exceptionDescriptor = "java/lang/Exception"
@@ -51,9 +65,6 @@ class EmptyExceptionHandlersTest {
assertTrue(convertMethod(asmMethod).handlers.isEmpty)
}
- val noOptCompiler = newCompiler(extraArgs = "-Ybackend:GenBCode -Yopt:l:none")
- val dceCompiler = newCompiler(extraArgs = "-Ybackend:GenBCode -Yopt:unreachable-code")
-
@Test
def eliminateUnreachableHandler(): Unit = {
val code = "def f: Unit = try { } catch { case _: Exception => println(0) }; println(1)"
diff --git a/test/junit/scala/tools/nsc/backend/jvm/opt/InlinerIllegalAccessTest.scala b/test/junit/scala/tools/nsc/backend/jvm/opt/InlinerIllegalAccessTest.scala
index 406b8da570..36f297767e 100644
--- a/test/junit/scala/tools/nsc/backend/jvm/opt/InlinerIllegalAccessTest.scala
+++ b/test/junit/scala/tools/nsc/backend/jvm/opt/InlinerIllegalAccessTest.scala
@@ -17,10 +17,18 @@ import ASMConverters._
import AsmUtils._
import scala.collection.convert.decorateAsScala._
+import scala.tools.testing.ClearAfterClass
+
+object InlinerIllegalAccessTest extends ClearAfterClass.Clearable {
+ var compiler = newCompiler(extraArgs = "-Ybackend:GenBCode -Yopt:l:none")
+ def clear(): Unit = { compiler = null }
+}
@RunWith(classOf[JUnit4])
-class InlinerIllegalAccessTest {
- val compiler = newCompiler(extraArgs = "-Ybackend:GenBCode -Yopt:l:none")
+class InlinerIllegalAccessTest extends ClearAfterClass {
+ ClearAfterClass.stateToClear = InlinerIllegalAccessTest
+
+ val compiler = InlinerIllegalAccessTest.compiler
import compiler.genBCode.bTypes._
def addToRepo(cls: List[ClassNode]): Unit = for (c <- cls) byteCodeRepository.classes(c.name) = (c, ByteCodeRepository.Classfile)
diff --git a/test/junit/scala/tools/nsc/backend/jvm/opt/InlinerTest.scala b/test/junit/scala/tools/nsc/backend/jvm/opt/InlinerTest.scala
index 1aa7bd1391..2ec6853f13 100644
--- a/test/junit/scala/tools/nsc/backend/jvm/opt/InlinerTest.scala
+++ b/test/junit/scala/tools/nsc/backend/jvm/opt/InlinerTest.scala
@@ -5,6 +5,7 @@ package opt
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
import org.junit.Test
+import scala.collection.generic.Clearable
import scala.tools.asm.Opcodes._
import org.junit.Assert._
@@ -19,19 +20,37 @@ import ASMConverters._
import AsmUtils._
import scala.collection.convert.decorateAsScala._
+import scala.tools.testing.ClearAfterClass
+
+object InlinerTest extends ClearAfterClass.Clearable {
+ var compiler = newCompiler(extraArgs = "-Ybackend:GenBCode -Yopt:l:project")
+
+ // allows inspecting the caches after a compilation run
+ def notPerRun: List[Clearable] = List(compiler.genBCode.bTypes.classBTypeFromInternalName, compiler.genBCode.bTypes.byteCodeRepository.classes)
+ notPerRun foreach compiler.perRunCaches.unrecordCache
+
+ def clear(): Unit = { compiler = null }
+}
@RunWith(classOf[JUnit4])
-class InlinerTest {
- val compiler = newCompiler(extraArgs = "-Ybackend:GenBCode -Yopt:l:none")
+class InlinerTest extends ClearAfterClass {
+ ClearAfterClass.stateToClear = InlinerTest
+
+ val compiler = InlinerTest.compiler
import compiler.genBCode.bTypes._
- def addToRepo(cls: List[ClassNode]): List[ClassNode] = {
+
+ def compile(code: String): List[ClassNode] = {
+ InlinerTest.notPerRun.foreach(_.clear())
+ val cls = compileClasses(compiler)(code)
+ // the compiler doesn't add classes being compiled to the code repo yet, so we do it manually.
+ // this line is removed in the next commit.
for (c <- cls) byteCodeRepository.classes(c.name) = (c, ByteCodeRepository.Classfile)
cls
}
// inline first invocation of f into g in class C
def inlineTest(code: String, mod: ClassNode => Unit = _ => ()): (MethodNode, Option[String]) = {
- val List(cls) = addToRepo(compileClasses(compiler)(code))
+ val List(cls) = compile(code)
mod(cls)
val clsBType = classBTypeFromParsedClassfile(cls.name)
@@ -165,7 +184,7 @@ class InlinerTest {
|}
""".stripMargin
- val List(c, d) = addToRepo(compileClasses(compiler)(code))
+ val List(c, d) = compile(code)
val cTp = classBTypeFromParsedClassfile(c.name)
val dTp = classBTypeFromParsedClassfile(d.name)
diff --git a/test/junit/scala/tools/nsc/backend/jvm/opt/MethodLevelOpts.scala b/test/junit/scala/tools/nsc/backend/jvm/opt/MethodLevelOpts.scala
index 5430e33d6c..2c71e9d533 100644
--- a/test/junit/scala/tools/nsc/backend/jvm/opt/MethodLevelOpts.scala
+++ b/test/junit/scala/tools/nsc/backend/jvm/opt/MethodLevelOpts.scala
@@ -13,10 +13,18 @@ import scala.tools.testing.AssertUtil._
import CodeGenTools._
import scala.tools.partest.ASMConverters
import ASMConverters._
+import scala.tools.testing.ClearAfterClass
+
+object MethodLevelOpts extends ClearAfterClass.Clearable {
+ var methodOptCompiler = newCompiler(extraArgs = "-target:jvm-1.6 -Ybackend:GenBCode -Yopt:l:method")
+ def clear(): Unit = { methodOptCompiler = null }
+}
@RunWith(classOf[JUnit4])
-class MethodLevelOpts {
- val methodOptCompiler = newCompiler(extraArgs = "-target:jvm-1.6 -Ybackend:GenBCode -Yopt:l:method")
+class MethodLevelOpts extends ClearAfterClass {
+ ClearAfterClass.stateToClear = MethodLevelOpts
+
+ val methodOptCompiler = MethodLevelOpts.methodOptCompiler
def wrapInDefault(code: Instruction*) = List(Label(0), LineNumber(1, Label(0))) ::: code.toList ::: List(Label(1))
diff --git a/test/junit/scala/tools/nsc/backend/jvm/opt/UnreachableCodeTest.scala b/test/junit/scala/tools/nsc/backend/jvm/opt/UnreachableCodeTest.scala
index 4a45dd9138..7c9636b8b7 100644
--- a/test/junit/scala/tools/nsc/backend/jvm/opt/UnreachableCodeTest.scala
+++ b/test/junit/scala/tools/nsc/backend/jvm/opt/UnreachableCodeTest.scala
@@ -13,9 +13,34 @@ import scala.tools.testing.AssertUtil._
import CodeGenTools._
import scala.tools.partest.ASMConverters
import ASMConverters._
+import scala.tools.testing.ClearAfterClass
+
+object UnreachableCodeTest extends ClearAfterClass.Clearable {
+ // jvm-1.6 enables emitting stack map frames, which impacts the code generation wrt dead basic blocks,
+ // see comment in BCodeBodyBuilder
+ var methodOptCompiler = newCompiler(extraArgs = "-target:jvm-1.6 -Ybackend:GenBCode -Yopt:l:method")
+ var dceCompiler = newCompiler(extraArgs = "-target:jvm-1.6 -Ybackend:GenBCode -Yopt:unreachable-code")
+ var noOptCompiler = newCompiler(extraArgs = "-target:jvm-1.6 -Ybackend:GenBCode -Yopt:l:none")
+
+ // jvm-1.5 disables computing stack map frames, and it emits dead code as-is.
+ var noOptNoFramesCompiler = newCompiler(extraArgs = "-target:jvm-1.5 -Ybackend:GenBCode -Yopt:l:none")
+
+ def clear(): Unit = {
+ methodOptCompiler = null
+ dceCompiler = null
+ noOptCompiler = null
+ noOptNoFramesCompiler = null
+ }
+}
@RunWith(classOf[JUnit4])
-class UnreachableCodeTest {
+class UnreachableCodeTest extends ClearAfterClass {
+ ClearAfterClass.stateToClear = UnreachableCodeTest
+
+ val methodOptCompiler = UnreachableCodeTest.methodOptCompiler
+ val dceCompiler = UnreachableCodeTest.dceCompiler
+ val noOptCompiler = UnreachableCodeTest.noOptCompiler
+ val noOptNoFramesCompiler = UnreachableCodeTest.noOptNoFramesCompiler
def assertEliminateDead(code: (Instruction, Boolean)*): Unit = {
val method = genMethod()(code.map(_._1): _*)
@@ -25,15 +50,6 @@ class UnreachableCodeTest {
assertSameCode(nonEliminated, expectedLive)
}
- // jvm-1.6 enables emitting stack map frames, which impacts the code generation wrt dead basic blocks,
- // see comment in BCodeBodyBuilder
- val methodOptCompiler = newCompiler(extraArgs = "-target:jvm-1.6 -Ybackend:GenBCode -Yopt:l:method")
- val dceCompiler = newCompiler(extraArgs = "-target:jvm-1.6 -Ybackend:GenBCode -Yopt:unreachable-code")
- val noOptCompiler = newCompiler(extraArgs = "-target:jvm-1.6 -Ybackend:GenBCode -Yopt:l:none")
-
- // jvm-1.5 disables computing stack map frames, and it emits dead code as-is.
- val noOptNoFramesCompiler = newCompiler(extraArgs = "-target:jvm-1.5 -Ybackend:GenBCode -Yopt:l:none")
-
@Test
def basicElimination(): Unit = {
assertEliminateDead(
diff --git a/test/junit/scala/tools/nsc/backend/jvm/opt/UnusedLocalVariablesTest.scala b/test/junit/scala/tools/nsc/backend/jvm/opt/UnusedLocalVariablesTest.scala
index 24a1f9d1c1..769736669b 100644
--- a/test/junit/scala/tools/nsc/backend/jvm/opt/UnusedLocalVariablesTest.scala
+++ b/test/junit/scala/tools/nsc/backend/jvm/opt/UnusedLocalVariablesTest.scala
@@ -12,10 +12,18 @@ import scala.collection.JavaConverters._
import CodeGenTools._
import scala.tools.partest.ASMConverters
import ASMConverters._
+import scala.tools.testing.ClearAfterClass
+
+object UnusedLocalVariablesTest extends ClearAfterClass.Clearable {
+ var dceCompiler = newCompiler(extraArgs = "-Ybackend:GenBCode -Yopt:unreachable-code")
+ def clear(): Unit = { dceCompiler = null }
+}
@RunWith(classOf[JUnit4])
-class UnusedLocalVariablesTest {
- val dceCompiler = newCompiler(extraArgs = "-Ybackend:GenBCode -Yopt:unreachable-code")
+class UnusedLocalVariablesTest extends ClearAfterClass {
+ ClearAfterClass.stateToClear = UnusedLocalVariablesTest
+
+ val dceCompiler = UnusedLocalVariablesTest.dceCompiler
@Test
def removeUnusedVar(): Unit = {
diff --git a/test/junit/scala/tools/testing/ClearAfterClass.java b/test/junit/scala/tools/testing/ClearAfterClass.java
new file mode 100644
index 0000000000..232d459c4e
--- /dev/null
+++ b/test/junit/scala/tools/testing/ClearAfterClass.java
@@ -0,0 +1,20 @@
+package scala.tools.testing;
+
+import org.junit.AfterClass;
+
+/**
+ * Extend this class to use JUnit's @AfterClass. This annotation only works on static methods,
+ * which cannot be written in Scala.
+ *
+ * Example: {@link scala.tools.nsc.backend.jvm.opt.InlinerTest}
+ */
+public class ClearAfterClass {
+ public static interface Clearable {
+ void clear();
+ }
+
+ public static Clearable stateToClear;
+
+ @AfterClass
+ public static void clearState() { stateToClear.clear(); }
+}