From 16e7ad360d1a902d6bd5c845642dbe14bcecdb9d Mon Sep 17 00:00:00 2001 From: Aleksandar Pokopec Date: Mon, 17 Jan 2011 15:18:06 +0000 Subject: Adapted specialization tests to track number of... Adapted specialization tests to track number of boxings. Review by dragos --- test/files/specialized/spec-absfun.check | 1 + test/files/specialized/spec-absfun.scala | 44 ++++++++++++++++++ test/files/specialized/spec-ame.check | 3 ++ test/files/specialized/spec-ame.scala | 18 ++++++++ test/files/specialized/spec-constr.check | 3 ++ test/files/specialized/spec-constr.scala | 15 ++++++ test/files/specialized/spec-early.check | 5 ++ test/files/specialized/spec-early.scala | 16 +++++++ test/files/specialized/spec-init.check | 10 ++++ test/files/specialized/spec-init.scala | 42 +++++++++++++++++ test/files/specialized/spec-matrix.check | 2 + test/files/specialized/spec-matrix.scala | 72 +++++++++++++++++++++++++++++ test/files/specialized/spec-overrides.check | 1 + test/files/specialized/spec-overrides.scala | 22 +++++++++ test/files/specialized/spec-patmatch.check | 20 ++++++++ test/files/specialized/spec-patmatch.scala | 53 +++++++++++++++++++++ test/files/specialized/spec-super.check | 3 ++ test/files/specialized/spec-super.scala | 20 ++++++++ test/files/specialized/spec-t3896.check | 3 ++ test/files/specialized/spec-t3896.scala | 20 ++++++++ 20 files changed, 373 insertions(+) create mode 100644 test/files/specialized/spec-absfun.check create mode 100644 test/files/specialized/spec-absfun.scala create mode 100644 test/files/specialized/spec-ame.check create mode 100644 test/files/specialized/spec-ame.scala create mode 100644 test/files/specialized/spec-constr.check create mode 100644 test/files/specialized/spec-constr.scala create mode 100644 test/files/specialized/spec-early.check create mode 100644 test/files/specialized/spec-early.scala create mode 100644 test/files/specialized/spec-init.check create mode 100644 test/files/specialized/spec-init.scala create mode 100644 test/files/specialized/spec-matrix.check create mode 100644 test/files/specialized/spec-matrix.scala create mode 100644 test/files/specialized/spec-overrides.check create mode 100644 test/files/specialized/spec-overrides.scala create mode 100644 test/files/specialized/spec-patmatch.check create mode 100644 test/files/specialized/spec-patmatch.scala create mode 100644 test/files/specialized/spec-super.check create mode 100644 test/files/specialized/spec-super.scala create mode 100644 test/files/specialized/spec-t3896.check create mode 100644 test/files/specialized/spec-t3896.scala (limited to 'test/files/specialized') diff --git a/test/files/specialized/spec-absfun.check b/test/files/specialized/spec-absfun.check new file mode 100644 index 0000000000..ffa577696d --- /dev/null +++ b/test/files/specialized/spec-absfun.check @@ -0,0 +1 @@ +4006000 \ No newline at end of file diff --git a/test/files/specialized/spec-absfun.scala b/test/files/specialized/spec-absfun.scala new file mode 100644 index 0000000000..57b54235c9 --- /dev/null +++ b/test/files/specialized/spec-absfun.scala @@ -0,0 +1,44 @@ + +/** Test inheritance. See #3085. + * Anonymous functions extend AbstractFunction1[SpecializedPair[Int], Unit]. The + * specialized type SpecializedPair$mcI$sp should not leak into the superclass because + * the definition of apply would vary covariantly, and erasure won't consider it an + * override of the abstract apply, leading to an AbstractMethodError at runtime. + */ + +object Test { + + private val Max = 1000 + + def main(args: Array[String]) { + notSpecialized() + specialized() + println(runtime.BoxesRunTime.integerBoxCount) + } + + def notSpecialized() { + val pairs = for { i <- 1 to Max; j <- 1 to i } yield new Pair(i, j) + val time0 = System.nanoTime + pairs foreach { p => p.first * p.second } + val time1 = System.nanoTime +// println(time1 - time0) + } + + def specialized() { + val pairs = for { i <- 1 to Max; j <- 1 to i } yield new SpecializedPair(i, j) + val time0 = System.nanoTime + pairs foreach { p => p.first * p.second } + val time1 = System.nanoTime +// println(time1 - time0) + } +} + +class Pair[A](_first: A, _second: A) { + def first = _first + def second = _second +} + +class SpecializedPair[@specialized(Int) A](_first: A, _second: A) { + def first = _first + def second = _second +} diff --git a/test/files/specialized/spec-ame.check b/test/files/specialized/spec-ame.check new file mode 100644 index 0000000000..9c1713cc8a --- /dev/null +++ b/test/files/specialized/spec-ame.check @@ -0,0 +1,3 @@ +abc +10 +3 \ No newline at end of file diff --git a/test/files/specialized/spec-ame.scala b/test/files/specialized/spec-ame.scala new file mode 100644 index 0000000000..45e88266eb --- /dev/null +++ b/test/files/specialized/spec-ame.scala @@ -0,0 +1,18 @@ +// ticket #3432 +object Test { + trait B[@specialized(Int) T] { + def value: T + } + + class A[@specialized(Int) T](x: T) { + def foo: B[T] = new B[T] { + def value = x + } + } + + def main(args: Array[String]) { + println((new A("abc")).foo.value) + println((new A(10)).foo.value) + println(runtime.BoxesRunTime.integerBoxCount) + } +} diff --git a/test/files/specialized/spec-constr.check b/test/files/specialized/spec-constr.check new file mode 100644 index 0000000000..2e3a7fdceb --- /dev/null +++ b/test/files/specialized/spec-constr.check @@ -0,0 +1,3 @@ +hello? +goodbye +0 \ No newline at end of file diff --git a/test/files/specialized/spec-constr.scala b/test/files/specialized/spec-constr.scala new file mode 100644 index 0000000000..38ee597299 --- /dev/null +++ b/test/files/specialized/spec-constr.scala @@ -0,0 +1,15 @@ +object Test { + class E[@specialized(Int) A](var f: A => Boolean) { + def this() = this(null) + + println("hello?") + if (f == null) f = { _ => false } + } + + def main(args: Array[String]) { + new E[Int] + println("goodbye") + println(runtime.BoxesRunTime.integerBoxCount) + } +} + diff --git a/test/files/specialized/spec-early.check b/test/files/specialized/spec-early.check new file mode 100644 index 0000000000..9c578a1af1 --- /dev/null +++ b/test/files/specialized/spec-early.check @@ -0,0 +1,5 @@ +a +abc +42 +abc +2 \ No newline at end of file diff --git a/test/files/specialized/spec-early.scala b/test/files/specialized/spec-early.scala new file mode 100644 index 0000000000..065dd57db5 --- /dev/null +++ b/test/files/specialized/spec-early.scala @@ -0,0 +1,16 @@ +trait Tr + +class Foo[@specialized(Int) T](_x: T) extends { + val bar = "abc" + val baz = "bbc" +} with Tr { + val x = _x + println(x) + println(bar) +} + +object Test extends Application { + new Foo("a") + new Foo(42) + println(runtime.BoxesRunTime.integerBoxCount) +} diff --git a/test/files/specialized/spec-init.check b/test/files/specialized/spec-init.check new file mode 100644 index 0000000000..46c031004a --- /dev/null +++ b/test/files/specialized/spec-init.check @@ -0,0 +1,10 @@ +abc +abc +abc +shouldn't see two initialized values and one uninitialized +42 +42 +42 +ok +ok +5 \ No newline at end of file diff --git a/test/files/specialized/spec-init.scala b/test/files/specialized/spec-init.scala new file mode 100644 index 0000000000..94cd0ee82b --- /dev/null +++ b/test/files/specialized/spec-init.scala @@ -0,0 +1,42 @@ +class Foo[@specialized(Int) T](_x: T) { + val x = _x + def bar {} + + val y = x + println(x) + println(y) + + def baz {} + val z = y + println(z) +} + +class Bar[@specialized(Int) T] { + def foo(x: T) = print(x) +} + +object Global { + var msg = "ok" +} + +class TouchGlobal[@specialized(Int) T](_x: T) { + println(Global.msg) + val x = { + Global.msg = "not ok" + _x + } +} + +object Test { + def main(args: Array[String]) { + (new Foo("abc")) + println("shouldn't see two initialized values and one uninitialized") + (new Foo(42)) + + (new TouchGlobal(new Object)) + Global.msg = "ok" // reset the value + (new TouchGlobal(42)) + + println(runtime.BoxesRunTime.integerBoxCount) + } +} diff --git a/test/files/specialized/spec-matrix.check b/test/files/specialized/spec-matrix.check new file mode 100644 index 0000000000..77b8d536fb --- /dev/null +++ b/test/files/specialized/spec-matrix.check @@ -0,0 +1,2 @@ +* +4080500 \ No newline at end of file diff --git a/test/files/specialized/spec-matrix.scala b/test/files/specialized/spec-matrix.scala new file mode 100644 index 0000000000..52bd3077d7 --- /dev/null +++ b/test/files/specialized/spec-matrix.scala @@ -0,0 +1,72 @@ +/** Test matrix multiplication with specialization. + */ + +class Matrix[@specialized A: ClassManifest](val rows: Int, val cols: Int) { + private val arr: Array[Array[A]] = new Array[Array[A]](rows, cols) + + def apply(i: Int, j: Int): A = { + if (i < 0 || i >= rows || j < 0 || j >= cols) + throw new NoSuchElementException("Indexes out of bounds: " + (i, j)) + + arr(i)(j) + } + + def update(i: Int, j: Int, e: A) { + arr(i)(j) = e + } + + def rowsIterator: Iterator[Array[A]] = new Iterator[Array[A]] { + var idx = 0; + def hasNext = idx < rows + def next = { + idx += 1 + arr(idx - 1) + } + } +} + +object Test { + def main(args: Array[String]) { + val m = randomMatrix(200, 100) + val n = randomMatrix(100, 200) + + mult(m, n) + println("*") + + println(runtime.BoxesRunTime.integerBoxCount) + } + + def randomMatrix(n: Int, m: Int) = { + val r = new util.Random(10) + val x = new Matrix[Int](n, m) + for (i <- 0 until n; j <- 0 until m) + x(i, j) = r.nextInt + x + } + + + def multManifest[@specialized(Int) T](m: Matrix[T], n: Matrix[T])(implicit cm: ClassManifest[T], num: Numeric[T]) { + val p = new Matrix[T](m.rows, n.cols) + import num._ + + for (i <- 0 until m.rows) + for (j <- 0 until n.cols) { + var sum = num.zero + for (k <- 0 until n.rows) + sum += m(i, k) * n(k, j) + p(i, j) = sum + } + } + + def mult(m: Matrix[Int], n: Matrix[Int]) { + val p = new Matrix[Int](m.rows, n.cols) + + for (i <- 0 until m.rows) + for (j <- 0 until n.cols) { + var sum = 0 + for (k <- 0 until n.rows) + sum += m(i, k) * n(k, j) + p(i, j) = sum + } + } +} diff --git a/test/files/specialized/spec-overrides.check b/test/files/specialized/spec-overrides.check new file mode 100644 index 0000000000..c227083464 --- /dev/null +++ b/test/files/specialized/spec-overrides.check @@ -0,0 +1 @@ +0 \ No newline at end of file diff --git a/test/files/specialized/spec-overrides.scala b/test/files/specialized/spec-overrides.scala new file mode 100644 index 0000000000..e89480984e --- /dev/null +++ b/test/files/specialized/spec-overrides.scala @@ -0,0 +1,22 @@ + trait Base[@specialized(Double) B] { + def default: B; + } + + trait D1 extends Base[Double] { + override def default = 0.0; + } + + class D2 extends D1 { + override def default: Double = 1.0; + } + + +object Test extends Application { + val d2 = new D2 + + assert(d2.default == 1.0, d2.default) + assert((d2: Base[_]).default == 1.0, (d2: Base[_]).default) + assert((d2: D1).default == 1.0, (d2: D1).default) + + println(runtime.BoxesRunTime.integerBoxCount) +} diff --git a/test/files/specialized/spec-patmatch.check b/test/files/specialized/spec-patmatch.check new file mode 100644 index 0000000000..33306ab5d9 --- /dev/null +++ b/test/files/specialized/spec-patmatch.check @@ -0,0 +1,20 @@ +bool +byte +short +char +int +long +double +float +default +object instantiations: +bool +byte +short +char +int +long +double +float +default +2 \ No newline at end of file diff --git a/test/files/specialized/spec-patmatch.scala b/test/files/specialized/spec-patmatch.scala new file mode 100644 index 0000000000..909629455d --- /dev/null +++ b/test/files/specialized/spec-patmatch.scala @@ -0,0 +1,53 @@ +class Foo[@specialized A] { + def test(x: A) = println(x match { + case _: Boolean => "bool" + case _: Byte => "byte" + case _: Short => "short" + case _: Char => "char" + case i: Int => "int" + case l: Long => "long" + case d: Double => "double" + case e: Float => "float" + case _ => "default" + }) +} + +object Test { + def test[@specialized A] (x: A) = println(x match { + case _: Boolean => "bool" + case _: Byte => "byte" + case _: Short => "short" + case _: Char => "char" + case i: Int => "int" + case l: Long => "long" + case d: Double => "double" + case e: Float => "float" + case _ => "default" + }) + + def main(args: Array[String]) { + test(true) + test(42.toByte) + test(42.toShort) + test('b') + test(42) + test(42l) + test(42.0) + test(42.0f) + test(new Object) + + println("object instantiations:") + (new Foo).test(true) + (new Foo).test(42.toByte) + (new Foo).test(42.toShort) + (new Foo).test('b') + (new Foo).test(42) + (new Foo).test(42l) + (new Foo).test(42.0) + (new Foo).test(42.0f) + (new Foo).test(new Object) + + println(runtime.BoxesRunTime.integerBoxCount) + } + +} diff --git a/test/files/specialized/spec-super.check b/test/files/specialized/spec-super.check new file mode 100644 index 0000000000..4be83ca9e6 --- /dev/null +++ b/test/files/specialized/spec-super.check @@ -0,0 +1,3 @@ +s +1 +2 \ No newline at end of file diff --git a/test/files/specialized/spec-super.scala b/test/files/specialized/spec-super.scala new file mode 100644 index 0000000000..056a7712f0 --- /dev/null +++ b/test/files/specialized/spec-super.scala @@ -0,0 +1,20 @@ + +// see ticket #3651 +object Test { + def main(args: Array[String]) { + val s = new Extended("s") + println(s.foo) //works + + val i = new Extended(1) + println(i.foo) //infinite loop with StackOverflowError + + println(runtime.BoxesRunTime.integerBoxCount) + } +} + +class Base[@specialized(Int) T](val t: T) { + def foo() :T = t +} +class Extended [@specialized(Int) T](t: T) extends Base[T](t) { + override def foo() :T = super.foo +} diff --git a/test/files/specialized/spec-t3896.check b/test/files/specialized/spec-t3896.check new file mode 100644 index 0000000000..63b0735a6f --- /dev/null +++ b/test/files/specialized/spec-t3896.check @@ -0,0 +1,3 @@ +true +true +0 \ No newline at end of file diff --git a/test/files/specialized/spec-t3896.scala b/test/files/specialized/spec-t3896.scala new file mode 100644 index 0000000000..89326b4284 --- /dev/null +++ b/test/files/specialized/spec-t3896.scala @@ -0,0 +1,20 @@ +// see ticket #3896. Tests interaction between overloading, specialization and default params +trait Atomic[@specialized(Boolean) T] { + def x: T + + // crash depends on the overloading: if second method is "g", no crash. + def f(fn: T => T): Boolean = f(fn(x)) + def f[R](a: T, b: R = true) = b +} +class AtomicBoolean(val x: Boolean) extends Atomic[Boolean] + +object Test { + def main(args: Array[String]): Unit = { + val e = new AtomicBoolean(false) + val x = e.f( (a : Boolean) => !a ) // ok + println( e.f( (a : Boolean) => !a ) toString ) // ok + println( e.f( (a : Boolean) => !a) ) // compiler crash + + println(runtime.BoxesRunTime.integerBoxCount) + } +} -- cgit v1.2.3