From 00050c6bd06928b045e583c7f15f1223faf6fbee Mon Sep 17 00:00:00 2001 From: Sébastien Doeraene Date: Wed, 13 Apr 2016 11:07:01 +0200 Subject: Inline ArrayRuntime methods in ScalaRunTime.array_clone(). Support for Array[T].clone() was introduced in 36ef60e68c03bc1c7fd2e910ae7d70d4ec32d3bf. At the time, all calls to array.clone() were redirected to ScalaRunTime.array_clone(), which meant that array_clone() itself could not be implemented in terms of `x.clone()`. A Java binding was necessary. Now, the rewriting to `array_clone()` is only done for unbounded generic arrays. Since all the calls within `array_clone()` are monomorphic arrays, the rewriting is not applied, and the Java binding is unnecessary. --- src/library/scala/runtime/ArrayRuntime.java | 26 ---------------------- src/library/scala/runtime/ScalaRunTime.scala | 18 +++++++-------- .../library/scala/runtime/ScalaRunTime.scala | 18 +++++++-------- 3 files changed, 18 insertions(+), 44 deletions(-) delete mode 100644 src/library/scala/runtime/ArrayRuntime.java diff --git a/src/library/scala/runtime/ArrayRuntime.java b/src/library/scala/runtime/ArrayRuntime.java deleted file mode 100644 index 1a0f748931..0000000000 --- a/src/library/scala/runtime/ArrayRuntime.java +++ /dev/null @@ -1,26 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2002-2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - - - -package scala.runtime; - -/** - * Methods on Java arrays - */ -class ArrayRuntime { - static boolean[] cloneArray(boolean[] array) { return array.clone(); } - static byte[] cloneArray(byte[] array) { return array.clone(); } - static short[] cloneArray(short[] array) { return array.clone(); } - static char[] cloneArray(char[] array) { return array.clone(); } - static int[] cloneArray(int[] array) { return array.clone(); } - static long[] cloneArray(long[] array) { return array.clone(); } - static float[] cloneArray(float[] array) { return array.clone(); } - static double[] cloneArray(double[] array) { return array.clone(); } - static Object[] cloneArray(Object[] array) { return array.clone(); } -} diff --git a/src/library/scala/runtime/ScalaRunTime.scala b/src/library/scala/runtime/ScalaRunTime.scala index 1195f95093..4c85eaa9ee 100644 --- a/src/library/scala/runtime/ScalaRunTime.scala +++ b/src/library/scala/runtime/ScalaRunTime.scala @@ -116,15 +116,15 @@ object ScalaRunTime { } def array_clone(xs: AnyRef): AnyRef = xs match { - case x: Array[AnyRef] => ArrayRuntime.cloneArray(x) - case x: Array[Int] => ArrayRuntime.cloneArray(x) - case x: Array[Double] => ArrayRuntime.cloneArray(x) - case x: Array[Long] => ArrayRuntime.cloneArray(x) - case x: Array[Float] => ArrayRuntime.cloneArray(x) - case x: Array[Char] => ArrayRuntime.cloneArray(x) - case x: Array[Byte] => ArrayRuntime.cloneArray(x) - case x: Array[Short] => ArrayRuntime.cloneArray(x) - case x: Array[Boolean] => ArrayRuntime.cloneArray(x) + case x: Array[AnyRef] => x.clone() + case x: Array[Int] => x.clone() + case x: Array[Double] => x.clone() + case x: Array[Long] => x.clone() + case x: Array[Float] => x.clone() + case x: Array[Char] => x.clone() + case x: Array[Byte] => x.clone() + case x: Array[Short] => x.clone() + case x: Array[Boolean] => x.clone() case x: Array[Unit] => x case null => throw new NullPointerException } diff --git a/test/instrumented/library/scala/runtime/ScalaRunTime.scala b/test/instrumented/library/scala/runtime/ScalaRunTime.scala index 6b45a4e9f3..ca59fc1509 100644 --- a/test/instrumented/library/scala/runtime/ScalaRunTime.scala +++ b/test/instrumented/library/scala/runtime/ScalaRunTime.scala @@ -122,15 +122,15 @@ object ScalaRunTime { } def array_clone(xs: AnyRef): AnyRef = xs match { - case x: Array[AnyRef] => ArrayRuntime.cloneArray(x) - case x: Array[Int] => ArrayRuntime.cloneArray(x) - case x: Array[Double] => ArrayRuntime.cloneArray(x) - case x: Array[Long] => ArrayRuntime.cloneArray(x) - case x: Array[Float] => ArrayRuntime.cloneArray(x) - case x: Array[Char] => ArrayRuntime.cloneArray(x) - case x: Array[Byte] => ArrayRuntime.cloneArray(x) - case x: Array[Short] => ArrayRuntime.cloneArray(x) - case x: Array[Boolean] => ArrayRuntime.cloneArray(x) + case x: Array[AnyRef] => x.clone() + case x: Array[Int] => x.clone() + case x: Array[Double] => x.clone() + case x: Array[Long] => x.clone() + case x: Array[Float] => x.clone() + case x: Array[Char] => x.clone() + case x: Array[Byte] => x.clone() + case x: Array[Short] => x.clone() + case x: Array[Boolean] => x.clone() case x: Array[Unit] => x case null => throw new NullPointerException } -- cgit v1.2.3 From 6090f53ee9ab2677f732ea5cc7144cb9684b2593 Mon Sep 17 00:00:00 2001 From: Sébastien Doeraene Date: Wed, 13 Apr 2016 11:54:47 +0200 Subject: Remove dead-code runtime hash() methods. ScalaRunTime had a bunch of overloads of the `hash()` method, but only the `Any` version is ever used by the codegen. Worse, their implementation was not in sync with the actual implementations in BoxesRunTime, called by the `Any` version. For example, hash(0x80000000L) != hash(0x80000000L: Any) This commit simply removes all of this dead code. Similarly, we remove BoxesRunTime.hashFromObject(), which was never called either. --- src/library/scala/runtime/BoxesRunTime.java | 4 --- src/library/scala/runtime/ScalaRunTime.scala | 41 +--------------------- test/files/pos/t5644/BoxesRunTime.java | 4 --- test/files/run/hashCodeBoxesRunTime.scala | 5 +-- .../library/scala/runtime/BoxesRunTime.java | 4 --- .../library/scala/runtime/ScalaRunTime.scala | 41 +--------------------- 6 files changed, 5 insertions(+), 94 deletions(-) diff --git a/src/library/scala/runtime/BoxesRunTime.java b/src/library/scala/runtime/BoxesRunTime.java index 9ae118f43f..b6b512d529 100644 --- a/src/library/scala/runtime/BoxesRunTime.java +++ b/src/library/scala/runtime/BoxesRunTime.java @@ -257,10 +257,6 @@ public final class BoxesRunTime else if (n instanceof java.lang.Float) return hashFromFloat((java.lang.Float)n); else return n.hashCode(); } - public static int hashFromObject(Object a) { - if (a instanceof Number) return hashFromNumber((Number)a); - else return a.hashCode(); - } private static int unboxCharOrInt(Object arg1, int code) { if (code == CHAR) diff --git a/src/library/scala/runtime/ScalaRunTime.scala b/src/library/scala/runtime/ScalaRunTime.scala index 4c85eaa9ee..9a2c917ae2 100644 --- a/src/library/scala/runtime/ScalaRunTime.scala +++ b/src/library/scala/runtime/ScalaRunTime.scala @@ -193,51 +193,12 @@ object ScalaRunTime { case _ => false } - // hashcode ----------------------------------------------------------- - // - // Note that these are the implementations called by ##, so they - // must not call ## themselves. - + /** Implementation of `##`. */ def hash(x: Any): Int = if (x == null) 0 else if (x.isInstanceOf[java.lang.Number]) BoxesRunTime.hashFromNumber(x.asInstanceOf[java.lang.Number]) else x.hashCode - def hash(dv: Double): Int = { - val iv = dv.toInt - if (iv == dv) return iv - - val lv = dv.toLong - if (lv == dv) return lv.hashCode - - val fv = dv.toFloat - if (fv == dv) fv.hashCode else dv.hashCode - } - def hash(fv: Float): Int = { - val iv = fv.toInt - if (iv == fv) return iv - - val lv = fv.toLong - if (lv == fv) hash(lv) - else fv.hashCode - } - def hash(lv: Long): Int = { - val low = lv.toInt - val lowSign = low >>> 31 - val high = (lv >>> 32).toInt - low ^ (high + lowSign) - } - def hash(x: Number): Int = runtime.BoxesRunTime.hashFromNumber(x) - - // The remaining overloads are here for completeness, but the compiler - // inlines these definitions directly so they're not generally used. - def hash(x: Int): Int = x - def hash(x: Short): Int = x.toInt - def hash(x: Byte): Int = x.toInt - def hash(x: Char): Int = x.toInt - def hash(x: Boolean): Int = if (x) true.hashCode else false.hashCode - def hash(x: Unit): Int = 0 - /** A helper method for constructing case class equality methods, * because existential types get in the way of a clean outcome and * it's performing a series of Any/Any equals comparisons anyway. diff --git a/test/files/pos/t5644/BoxesRunTime.java b/test/files/pos/t5644/BoxesRunTime.java index 74c4c6b4b9..2b931519aa 100644 --- a/test/files/pos/t5644/BoxesRunTime.java +++ b/test/files/pos/t5644/BoxesRunTime.java @@ -267,10 +267,6 @@ public final class BoxesRunTime else if (n instanceof java.lang.Float) return hashFromFloat((java.lang.Float)n); else return n.hashCode(); } - public static int hashFromObject(Object a) { - if (a instanceof Number) return hashFromNumber((Number)a); - else return a.hashCode(); - } private static int unboxCharOrInt(Object arg1, int code) { if (code == CHAR) diff --git a/test/files/run/hashCodeBoxesRunTime.scala b/test/files/run/hashCodeBoxesRunTime.scala index ba1a30f5fb..8ad94c252a 100644 --- a/test/files/run/hashCodeBoxesRunTime.scala +++ b/test/files/run/hashCodeBoxesRunTime.scala @@ -3,7 +3,8 @@ object Test { import java.{ lang => jl } - import scala.runtime.BoxesRunTime.{ hashFromNumber, hashFromObject } + import scala.runtime.BoxesRunTime.hashFromNumber + import scala.runtime.ScalaRunTime.{ hash => hashFromAny } def allSame[T](xs: List[T]) = assert(xs.distinct.size == 1, "failed: " + xs) @@ -17,7 +18,7 @@ object Test val hashes = mkNumbers(n) map hashFromNumber allSame(hashes) if (n >= 0) { - val charCode = hashFromObject(n.toChar: Character) + val charCode = hashFromAny(n.toChar: Character) assert(charCode == hashes.head) } } diff --git a/test/instrumented/library/scala/runtime/BoxesRunTime.java b/test/instrumented/library/scala/runtime/BoxesRunTime.java index 57799bd9b1..05ce2941a8 100644 --- a/test/instrumented/library/scala/runtime/BoxesRunTime.java +++ b/test/instrumented/library/scala/runtime/BoxesRunTime.java @@ -278,10 +278,6 @@ public final class BoxesRunTime else if (n instanceof java.lang.Float) return hashFromFloat((java.lang.Float)n); else return n.hashCode(); } - public static int hashFromObject(Object a) { - if (a instanceof Number) return hashFromNumber((Number)a); - else return a.hashCode(); - } private static int unboxCharOrInt(Object arg1, int code) { if (code == CHAR) diff --git a/test/instrumented/library/scala/runtime/ScalaRunTime.scala b/test/instrumented/library/scala/runtime/ScalaRunTime.scala index ca59fc1509..9df3bea5d9 100644 --- a/test/instrumented/library/scala/runtime/ScalaRunTime.scala +++ b/test/instrumented/library/scala/runtime/ScalaRunTime.scala @@ -205,51 +205,12 @@ object ScalaRunTime { case _ => false } - // hashcode ----------------------------------------------------------- - // - // Note that these are the implementations called by ##, so they - // must not call ## themselves. - + /** Implementation of `##`. */ def hash(x: Any): Int = if (x == null) 0 else if (x.isInstanceOf[java.lang.Number]) BoxesRunTime.hashFromNumber(x.asInstanceOf[java.lang.Number]) else x.hashCode - def hash(dv: Double): Int = { - val iv = dv.toInt - if (iv == dv) return iv - - val lv = dv.toLong - if (lv == dv) return lv.hashCode - - val fv = dv.toFloat - if (fv == dv) fv.hashCode else dv.hashCode - } - def hash(fv: Float): Int = { - val iv = fv.toInt - if (iv == fv) return iv - - val lv = fv.toLong - if (lv == fv) return hash(lv) - else fv.hashCode - } - def hash(lv: Long): Int = { - val low = lv.toInt - val lowSign = low >>> 31 - val high = (lv >>> 32).toInt - low ^ (high + lowSign) - } - def hash(x: Number): Int = runtime.BoxesRunTime.hashFromNumber(x) - - // The remaining overloads are here for completeness, but the compiler - // inlines these definitions directly so they're not generally used. - def hash(x: Int): Int = x - def hash(x: Short): Int = x.toInt - def hash(x: Byte): Int = x.toInt - def hash(x: Char): Int = x.toInt - def hash(x: Boolean): Int = if (x) true.hashCode else false.hashCode - def hash(x: Unit): Int = 0 - /** A helper method for constructing case class equality methods, * because existential types get in the way of a clean outcome and * it's performing a series of Any/Any equals comparisons anyway. -- cgit v1.2.3 From 950f6df06ef122cc6b71a4b402b1b22d9e5376dc Mon Sep 17 00:00:00 2001 From: Sébastien Doeraene Date: Wed, 13 Apr 2016 13:05:39 +0200 Subject: Hide ScalaRunTime.isTuple inside stringOf. Because it is otherwise unused. --- src/library/scala/runtime/ScalaRunTime.scala | 5 +- .../library/scala/runtime/ScalaRunTime.scala | 5 +- test/junit/scala/runtime/ScalaRunTimeTest.scala | 65 ++-------------------- 3 files changed, 10 insertions(+), 65 deletions(-) diff --git a/src/library/scala/runtime/ScalaRunTime.scala b/src/library/scala/runtime/ScalaRunTime.scala index 9a2c917ae2..dd973d12da 100644 --- a/src/library/scala/runtime/ScalaRunTime.scala +++ b/src/library/scala/runtime/ScalaRunTime.scala @@ -31,8 +31,6 @@ object ScalaRunTime { def isValueClass(clazz: jClass[_]) = clazz.isPrimitive() - // includes specialized subclasses and future proofed against hypothetical TupleN (for N > 22) - def isTuple(x: Any) = x != null && x.getClass.getName.startsWith("scala.Tuple") def isAnyVal(x: Any) = x match { case _: Byte | _: Short | _: Char | _: Int | _: Long | _: Float | _: Double | _: Boolean | _: Unit => true case _ => false @@ -227,6 +225,9 @@ object ScalaRunTime { def isScalaClass(x: AnyRef) = packageOf(x) startsWith "scala." def isScalaCompilerClass(x: AnyRef) = packageOf(x) startsWith "scala.tools.nsc." + // includes specialized subclasses and future proofed against hypothetical TupleN (for N > 22) + def isTuple(x: Any) = x != null && x.getClass.getName.startsWith("scala.Tuple") + // We use reflection because the scala.xml package might not be available def isSubClassOf(potentialSubClass: Class[_], ofClass: String) = try { diff --git a/test/instrumented/library/scala/runtime/ScalaRunTime.scala b/test/instrumented/library/scala/runtime/ScalaRunTime.scala index 9df3bea5d9..9b01eec039 100644 --- a/test/instrumented/library/scala/runtime/ScalaRunTime.scala +++ b/test/instrumented/library/scala/runtime/ScalaRunTime.scala @@ -37,8 +37,6 @@ object ScalaRunTime { def isValueClass(clazz: jClass[_]) = clazz.isPrimitive() - // includes specialized subclasses and future proofed against hypothetical TupleN (for N > 22) - def isTuple(x: Any) = x != null && x.getClass.getName.startsWith("scala.Tuple") def isAnyVal(x: Any) = x match { case _: Byte | _: Short | _: Char | _: Int | _: Long | _: Float | _: Double | _: Boolean | _: Unit => true case _ => false @@ -239,6 +237,9 @@ object ScalaRunTime { def isScalaClass(x: AnyRef) = packageOf(x) startsWith "scala." def isScalaCompilerClass(x: AnyRef) = packageOf(x) startsWith "scala.tools.nsc." + // includes specialized subclasses and future proofed against hypothetical TupleN (for N > 22) + def isTuple(x: Any) = x != null && x.getClass.getName.startsWith("scala.Tuple") + // When doing our own iteration is dangerous def useOwnToString(x: Any) = x match { // Node extends NodeSeq extends Seq[Node] and MetaData extends Iterable[MetaData] diff --git a/test/junit/scala/runtime/ScalaRunTimeTest.scala b/test/junit/scala/runtime/ScalaRunTimeTest.scala index 728d8c0ce9..5bfb12610e 100644 --- a/test/junit/scala/runtime/ScalaRunTimeTest.scala +++ b/test/junit/scala/runtime/ScalaRunTimeTest.scala @@ -5,69 +5,9 @@ import org.junit.Test import org.junit.runner.RunWith import org.junit.runners.JUnit4 -/** Tests for the private class DefaultPromise */ +/** Tests for the runtime object ScalaRunTime */ @RunWith(classOf[JUnit4]) class ScalaRunTimeTest { - @Test - def testIsTuple() { - import ScalaRunTime.isTuple - def check(v: Any) = { - assertTrue(v.toString, isTuple(v)) - } - - val s = "" - check(Tuple1(s)) - check((s, s)) - check((s, s, s)) - check((s, s, s, s)) - check((s, s, s, s, s)) - check((s, s, s, s, s, s)) - check((s, s, s, s, s, s, s)) - check((s, s, s, s, s, s, s, s)) - check((s, s, s, s, s, s, s, s, s)) - check((s, s, s, s, s, s, s, s, s, s)) - check((s, s, s, s, s, s, s, s, s, s, s)) - check((s, s, s, s, s, s, s, s, s, s, s, s)) - check((s, s, s, s, s, s, s, s, s, s, s, s, s)) - check((s, s, s, s, s, s, s, s, s, s, s, s, s, s)) - check((s, s, s, s, s, s, s, s, s, s, s, s, s, s, s)) - check((s, s, s, s, s, s, s, s, s, s, s, s, s, s, s, s)) - check((s, s, s, s, s, s, s, s, s, s, s, s, s, s, s, s, s)) - check((s, s, s, s, s, s, s, s, s, s, s, s, s, s, s, s, s, s)) - check((s, s, s, s, s, s, s, s, s, s, s, s, s, s, s, s, s, s, s)) - check((s, s, s, s, s, s, s, s, s, s, s, s, s, s, s, s, s, s, s, s)) - check((s, s, s, s, s, s, s, s, s, s, s, s, s, s, s, s, s, s, s, s, s)) - check((s, s, s, s, s, s, s, s, s, s, s, s, s, s, s, s, s, s, s, s, s, s)) - - // some specialized variants will have mangled classnames - check(Tuple1(0)) - check((0, 0)) - check((0, 0, 0)) - check((0, 0, 0, 0)) - check((0, 0, 0, 0, 0)) - check((0, 0, 0, 0, 0, 0)) - check((0, 0, 0, 0, 0, 0, 0)) - check((0, 0, 0, 0, 0, 0, 0, 0)) - check((0, 0, 0, 0, 0, 0, 0, 0, 0)) - check((0, 0, 0, 0, 0, 0, 0, 0, 0, 0)) - check((0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)) - check((0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)) - check((0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)) - check((0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)) - check((0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)) - check((0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)) - check((0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)) - check((0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)) - check((0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)) - check((0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)) - check((0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)) - check((0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)) - - case class C() - val c = new C() - assertFalse(c.toString, isTuple(c)) - } - @Test def testStingOf() { import ScalaRunTime.stringOf @@ -109,14 +49,17 @@ class ScalaRunTimeTest { val tuple1 = Tuple1(0) assertEquals("(0,)", stringOf(tuple1)) assertEquals("(0,)", stringOf(tuple1, 0)) + assertEquals("(Array(0),)", stringOf(Tuple1(Array(0)))) val tuple2 = Tuple2(0, 1) assertEquals("(0,1)", stringOf(tuple2)) assertEquals("(0,1)", stringOf(tuple2, 0)) + assertEquals("(Array(0),1)", stringOf((Array(0), 1))) val tuple3 = Tuple3(0, 1, 2) assertEquals("(0,1,2)", stringOf(tuple3)) assertEquals("(0,1,2)", stringOf(tuple3, 0)) + assertEquals("(Array(0),1,2)", stringOf((Array(0), 1, 2))) val x = new Object { override def toString(): String = "this is the stringOf string" -- cgit v1.2.3 From 51996c8474a06656f8c21302af2b4151bdc2393e Mon Sep 17 00:00:00 2001 From: Sébastien Doeraene Date: Wed, 13 Apr 2016 13:09:19 +0200 Subject: Move ScalaRunTime.isAnyVal to reify.phases.Reify. Because that is the only call site of that method. --- src/compiler/scala/reflect/reify/phases/Reify.scala | 6 +++++- src/library/scala/runtime/ScalaRunTime.scala | 5 ----- test/instrumented/library/scala/runtime/ScalaRunTime.scala | 5 ----- 3 files changed, 5 insertions(+), 11 deletions(-) diff --git a/src/compiler/scala/reflect/reify/phases/Reify.scala b/src/compiler/scala/reflect/reify/phases/Reify.scala index 143424dac5..93f6f99d81 100644 --- a/src/compiler/scala/reflect/reify/phases/Reify.scala +++ b/src/compiler/scala/reflect/reify/phases/Reify.scala @@ -1,7 +1,6 @@ package scala.reflect.reify package phases -import scala.runtime.ScalaRunTime.isAnyVal import scala.reflect.reify.codegen._ trait Reify extends GenSymbols @@ -57,4 +56,9 @@ trait Reify extends GenSymbols case _ => throw new Error("reifee %s of type %s is not supported".format(reifee, reifee.getClass)) }) + + private def isAnyVal(x: Any) = x match { + case _: Byte | _: Short | _: Char | _: Int | _: Long | _: Float | _: Double | _: Boolean | _: Unit => true + case _ => false + } } diff --git a/src/library/scala/runtime/ScalaRunTime.scala b/src/library/scala/runtime/ScalaRunTime.scala index dd973d12da..71a3603a42 100644 --- a/src/library/scala/runtime/ScalaRunTime.scala +++ b/src/library/scala/runtime/ScalaRunTime.scala @@ -31,11 +31,6 @@ object ScalaRunTime { def isValueClass(clazz: jClass[_]) = clazz.isPrimitive() - def isAnyVal(x: Any) = x match { - case _: Byte | _: Short | _: Char | _: Int | _: Long | _: Float | _: Double | _: Boolean | _: Unit => true - case _ => false - } - // A helper method to make my life in the pattern matcher a lot easier. def drop[Repr](coll: Repr, num: Int)(implicit traversable: IsTraversableLike[Repr]): Repr = traversable conversion coll drop num diff --git a/test/instrumented/library/scala/runtime/ScalaRunTime.scala b/test/instrumented/library/scala/runtime/ScalaRunTime.scala index 9b01eec039..6e758abde0 100644 --- a/test/instrumented/library/scala/runtime/ScalaRunTime.scala +++ b/test/instrumented/library/scala/runtime/ScalaRunTime.scala @@ -37,11 +37,6 @@ object ScalaRunTime { def isValueClass(clazz: jClass[_]) = clazz.isPrimitive() - def isAnyVal(x: Any) = x match { - case _: Byte | _: Short | _: Char | _: Int | _: Long | _: Float | _: Double | _: Boolean | _: Unit => true - case _ => false - } - /** Return the class object representing an array with element class `clazz`. */ def arrayClass(clazz: jClass[_]): jClass[_] = { -- cgit v1.2.3 From 8fc0516d6deeb84af9bac5370f1d21511e0f86d6 Mon Sep 17 00:00:00 2001 From: Sébastien Doeraene Date: Wed, 13 Apr 2016 14:55:02 +0200 Subject: Inline ScalaRunTime.arrayElementClass at call sites. This method was awful. Not only it was using run-time type tests to essentially encode compile-time overloading. But it also did 2 slightly different things for the Class case and ClassTag case. All in all, it is much more readable to inline the appropriate implementation at every call site. --- src/library/scala/collection/mutable/ArrayOps.scala | 9 ++++----- src/library/scala/collection/mutable/WrappedArray.scala | 9 ++++----- src/library/scala/collection/mutable/WrappedArrayBuilder.scala | 3 +-- src/library/scala/reflect/ClassTag.scala | 3 +-- src/library/scala/runtime/ScalaRunTime.scala | 9 --------- src/reflect/scala/reflect/runtime/JavaMirrors.scala | 2 +- test/instrumented/library/scala/runtime/ScalaRunTime.scala | 9 --------- 7 files changed, 11 insertions(+), 33 deletions(-) diff --git a/src/library/scala/collection/mutable/ArrayOps.scala b/src/library/scala/collection/mutable/ArrayOps.scala index b7682c5ab9..507585b9cf 100644 --- a/src/library/scala/collection/mutable/ArrayOps.scala +++ b/src/library/scala/collection/mutable/ArrayOps.scala @@ -11,7 +11,6 @@ package collection package mutable import scala.reflect.ClassTag -import scala.runtime.ScalaRunTime._ import parallel.mutable.ParArray /** This class serves as a wrapper for `Array`s with all the operations found in @@ -35,7 +34,7 @@ import parallel.mutable.ParArray sealed trait ArrayOps[T] extends Any with ArrayLike[T, Array[T]] with CustomParallelizable[T, ParArray[T]] { private def elementClass: Class[_] = - arrayElementClass(repr.getClass) + repr.getClass.getComponentType override def copyToArray[U >: T](xs: Array[U], start: Int, len: Int) { val l = len min repr.length min (xs.length - start) @@ -43,7 +42,7 @@ sealed trait ArrayOps[T] extends Any with ArrayLike[T, Array[T]] with CustomPara } override def toArray[U >: T : ClassTag]: Array[U] = { - val thatElementClass = arrayElementClass(implicitly[ClassTag[U]]) + val thatElementClass = implicitly[ClassTag[U]].runtimeClass if (elementClass eq thatElementClass) repr.asInstanceOf[Array[U]] else @@ -91,7 +90,7 @@ sealed trait ArrayOps[T] extends Any with ArrayLike[T, Array[T]] with CustomPara val bb: Builder[Array[U], Array[Array[U]]] = Array.newBuilder(ClassTag[Array[U]](elementClass)) if (isEmpty) bb.result() else { - def mkRowBuilder() = Array.newBuilder(ClassTag[U](arrayElementClass(elementClass))) + def mkRowBuilder() = Array.newBuilder(ClassTag[U](elementClass.getComponentType)) val bs = asArray(head) map (_ => mkRowBuilder()) for (xs <- this) { var i = 0 @@ -184,7 +183,7 @@ object ArrayOps { override protected[this] def thisCollection: WrappedArray[T] = new WrappedArray.ofRef[T](repr) override protected[this] def toCollection(repr: Array[T]): WrappedArray[T] = new WrappedArray.ofRef[T](repr) - override protected[this] def newBuilder = new ArrayBuilder.ofRef[T]()(ClassTag[T](arrayElementClass(repr.getClass))) + override protected[this] def newBuilder = new ArrayBuilder.ofRef[T]()(ClassTag[T](repr.getClass.getComponentType)) def length: Int = repr.length def apply(index: Int): T = repr(index) diff --git a/src/library/scala/collection/mutable/WrappedArray.scala b/src/library/scala/collection/mutable/WrappedArray.scala index 8740bda835..01dcd9bde5 100644 --- a/src/library/scala/collection/mutable/WrappedArray.scala +++ b/src/library/scala/collection/mutable/WrappedArray.scala @@ -13,7 +13,6 @@ package collection package mutable import scala.reflect.ClassTag -import scala.runtime.ScalaRunTime._ import scala.collection.generic._ import scala.collection.parallel.mutable.ParArray @@ -46,7 +45,7 @@ extends AbstractSeq[T] def elemTag: ClassTag[T] @deprecated("use elemTag instead", "2.10.0") - def elemManifest: ClassManifest[T] = ClassManifest.fromClass[T](arrayElementClass(elemTag).asInstanceOf[Class[T]]) + def elemManifest: ClassManifest[T] = ClassManifest.fromClass[T](elemTag.runtimeClass.asInstanceOf[Class[T]]) /** The length of the array */ def length: Int @@ -63,10 +62,10 @@ extends AbstractSeq[T] override def par = ParArray.handoff(array) private def elementClass: Class[_] = - arrayElementClass(array.getClass) + array.getClass.getComponentType override def toArray[U >: T : ClassTag]: Array[U] = { - val thatElementClass = arrayElementClass(implicitly[ClassTag[U]]) + val thatElementClass = implicitly[ClassTag[U]].runtimeClass if (elementClass eq thatElementClass) array.asInstanceOf[Array[U]] else @@ -122,7 +121,7 @@ object WrappedArray { def newBuilder[A]: Builder[A, IndexedSeq[A]] = new ArrayBuffer final class ofRef[T <: AnyRef](val array: Array[T]) extends WrappedArray[T] with Serializable { - lazy val elemTag = ClassTag[T](arrayElementClass(array.getClass)) + lazy val elemTag = ClassTag[T](array.getClass.getComponentType) def length: Int = array.length def apply(index: Int): T = array(index).asInstanceOf[T] def update(index: Int, elem: T) { array(index) = elem } diff --git a/src/library/scala/collection/mutable/WrappedArrayBuilder.scala b/src/library/scala/collection/mutable/WrappedArrayBuilder.scala index c4781321d7..5bc5811450 100644 --- a/src/library/scala/collection/mutable/WrappedArrayBuilder.scala +++ b/src/library/scala/collection/mutable/WrappedArrayBuilder.scala @@ -13,7 +13,6 @@ package collection package mutable import scala.reflect.ClassTag -import scala.runtime.ScalaRunTime._ /** A builder class for arrays. * @@ -34,7 +33,7 @@ class WrappedArrayBuilder[A](tag: ClassTag[A]) extends ReusableBuilder[A, Wrappe private var size: Int = 0 private def mkArray(size: Int): WrappedArray[A] = { - val runtimeClass = arrayElementClass(tag) + val runtimeClass = tag.runtimeClass val newelems = runtimeClass match { case java.lang.Byte.TYPE => new WrappedArray.ofByte(new Array[Byte](size)).asInstanceOf[WrappedArray[A]] case java.lang.Short.TYPE => new WrappedArray.ofShort(new Array[Short](size)).asInstanceOf[WrappedArray[A]] diff --git a/src/library/scala/reflect/ClassTag.scala b/src/library/scala/reflect/ClassTag.scala index 9dd96183da..7f037ce17b 100644 --- a/src/library/scala/reflect/ClassTag.scala +++ b/src/library/scala/reflect/ClassTag.scala @@ -2,7 +2,6 @@ package scala package reflect import java.lang.{ Class => jClass } -import scala.runtime.ScalaRunTime.arrayElementClass /** * @@ -105,7 +104,7 @@ trait ClassTag[T] extends ClassManifestDeprecatedApis[T] with Equals with Serial override def hashCode = scala.runtime.ScalaRunTime.hash(runtimeClass) override def toString = { def prettyprint(clazz: jClass[_]): String = - if (clazz.isArray) s"Array[${prettyprint(arrayElementClass(clazz))}]" else + if (clazz.isArray) s"Array[${prettyprint(clazz.getComponentType)}]" else clazz.getName prettyprint(runtimeClass) } diff --git a/src/library/scala/runtime/ScalaRunTime.scala b/src/library/scala/runtime/ScalaRunTime.scala index 71a3603a42..151d4394bb 100644 --- a/src/library/scala/runtime/ScalaRunTime.scala +++ b/src/library/scala/runtime/ScalaRunTime.scala @@ -43,15 +43,6 @@ object ScalaRunTime { else java.lang.reflect.Array.newInstance(clazz, 0).getClass } - /** Return the class object representing elements in arrays described by a given schematic. - */ - def arrayElementClass(schematic: Any): jClass[_] = schematic match { - case cls: jClass[_] => cls.getComponentType - case tag: ClassTag[_] => tag.runtimeClass - case _ => - throw new UnsupportedOperationException(s"unsupported schematic $schematic (${schematic.getClass})") - } - /** Return the class object representing an unboxed value type, * e.g., classOf[int], not classOf[java.lang.Integer]. The compiler * rewrites expressions like 5.getClass to come here. diff --git a/src/reflect/scala/reflect/runtime/JavaMirrors.scala b/src/reflect/scala/reflect/runtime/JavaMirrors.scala index bdcfcabdd5..1dce979e79 100644 --- a/src/reflect/scala/reflect/runtime/JavaMirrors.scala +++ b/src/reflect/scala/reflect/runtime/JavaMirrors.scala @@ -154,7 +154,7 @@ private[scala] trait JavaMirrors extends internal.SymbolTable with api.JavaUnive } def apply(schemaAndValue: (jClass[_], Any)): ClassfileAnnotArg = schemaAndValue match { case ConstantArg(value) => LiteralAnnotArg(Constant(value)) - case (clazz @ ArrayClass(), value: Array[_]) => ArrayAnnotArg(value map (x => apply(ScalaRunTime.arrayElementClass(clazz) -> x))) + case (clazz @ ArrayClass(), value: Array[_]) => ArrayAnnotArg(value map (x => apply(clazz.getComponentType -> x))) case (AnnotationClass(), value: jAnnotation) => NestedAnnotArg(JavaAnnotationProxy(value)) case _ => UnmappableAnnotArg } diff --git a/test/instrumented/library/scala/runtime/ScalaRunTime.scala b/test/instrumented/library/scala/runtime/ScalaRunTime.scala index 6e758abde0..7bd94ef7ca 100644 --- a/test/instrumented/library/scala/runtime/ScalaRunTime.scala +++ b/test/instrumented/library/scala/runtime/ScalaRunTime.scala @@ -45,15 +45,6 @@ object ScalaRunTime { else java.lang.reflect.Array.newInstance(clazz, 0).getClass } - /** Return the class object representing elements in arrays described by a given schematic. - */ - def arrayElementClass(schematic: Any): jClass[_] = schematic match { - case cls: jClass[_] => cls.getComponentType - case tag: ClassTag[_] => tag.runtimeClass - case _ => - throw new UnsupportedOperationException(s"unsupported schematic $schematic (${schematic.getClass})") - } - /** Return the class object representing an unboxed value type, * e.g. classOf[int], not classOf[java.lang.Integer]. The compiler * rewrites expressions like 5.getClass to come here. -- cgit v1.2.3 From 702e86d3ce86489a8639d0ec47eace2d6262a7a1 Mon Sep 17 00:00:00 2001 From: Sébastien Doeraene Date: Wed, 13 Apr 2016 15:13:45 +0200 Subject: Move ScalaRunTime.box to typechecker.Macros. Because it was its only call site. --- src/compiler/scala/tools/nsc/typechecker/Macros.scala | 16 ++++++++++++++-- src/library/scala/runtime/ScalaRunTime.scala | 13 ------------- 2 files changed, 14 insertions(+), 15 deletions(-) diff --git a/src/compiler/scala/tools/nsc/typechecker/Macros.scala b/src/compiler/scala/tools/nsc/typechecker/Macros.scala index bcf9e018e2..d7c53ed3c4 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Macros.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Macros.scala @@ -12,7 +12,6 @@ import scala.reflect.internal.util.ListOfNil import scala.reflect.macros.runtime.{AbortMacroException, MacroRuntimes} import scala.reflect.macros.compiler.DefaultMacroCompiler import scala.tools.reflect.FastTrack -import scala.runtime.ScalaRunTime import Fingerprint._ /** @@ -239,7 +238,7 @@ trait Macros extends MacroRuntimes with Traces with Helpers { if (!payload.contains(field)) failField("is supposed to be there") val raw: Any = payload(field) if (raw == null) failField(s"is not supposed to be null") - val expected = ScalaRunTime.box(clazz) + val expected = box(clazz) val actual = raw.getClass if (!expected.isAssignableFrom(actual)) failField(s"has wrong type: expected $expected, actual $actual") raw.asInstanceOf[T] @@ -256,6 +255,19 @@ trait Macros extends MacroRuntimes with Traces with Helpers { val signature = unpickle("signature", classOf[List[List[Fingerprint]]]) MacroImplBinding(isBundle, isBlackbox, className, methodName, signature, targs) } + + private def box[T](clazz: Class[T]): Class[_] = clazz match { + case java.lang.Byte.TYPE => classOf[java.lang.Byte] + case java.lang.Short.TYPE => classOf[java.lang.Short] + case java.lang.Character.TYPE => classOf[java.lang.Character] + case java.lang.Integer.TYPE => classOf[java.lang.Integer] + case java.lang.Long.TYPE => classOf[java.lang.Long] + case java.lang.Float.TYPE => classOf[java.lang.Float] + case java.lang.Double.TYPE => classOf[java.lang.Double] + case java.lang.Void.TYPE => classOf[scala.runtime.BoxedUnit] + case java.lang.Boolean.TYPE => classOf[java.lang.Boolean] + case _ => clazz + } } def bindMacroImpl(macroDef: Symbol, macroImplRef: Tree): Unit = { diff --git a/src/library/scala/runtime/ScalaRunTime.scala b/src/library/scala/runtime/ScalaRunTime.scala index 151d4394bb..7c1a89e248 100644 --- a/src/library/scala/runtime/ScalaRunTime.scala +++ b/src/library/scala/runtime/ScalaRunTime.scala @@ -293,17 +293,4 @@ object ScalaRunTime { nl + s + "\n" } - - def box[T](clazz: jClass[T]): jClass[_] = clazz match { - case java.lang.Byte.TYPE => classOf[java.lang.Byte] - case java.lang.Short.TYPE => classOf[java.lang.Short] - case java.lang.Character.TYPE => classOf[java.lang.Character] - case java.lang.Integer.TYPE => classOf[java.lang.Integer] - case java.lang.Long.TYPE => classOf[java.lang.Long] - case java.lang.Float.TYPE => classOf[java.lang.Float] - case java.lang.Double.TYPE => classOf[java.lang.Double] - case java.lang.Void.TYPE => classOf[scala.runtime.BoxedUnit] - case java.lang.Boolean.TYPE => classOf[java.lang.Boolean] - case _ => clazz - } } -- cgit v1.2.3 From 246cd636b0e2e5861ee93e7a18d1940d2f6f6fce Mon Sep 17 00:00:00 2001 From: Sébastien Doeraene Date: Wed, 13 Apr 2016 16:43:35 +0200 Subject: Do not rely on ScalaRunTime.{inlineEquals,hash} in JavaMirrors. We can use the normal Scala language constructs instead. --- src/reflect/scala/reflect/runtime/JavaMirrors.scala | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/reflect/scala/reflect/runtime/JavaMirrors.scala b/src/reflect/scala/reflect/runtime/JavaMirrors.scala index 1dce979e79..37b07ce775 100644 --- a/src/reflect/scala/reflect/runtime/JavaMirrors.scala +++ b/src/reflect/scala/reflect/runtime/JavaMirrors.scala @@ -475,9 +475,9 @@ private[scala] trait JavaMirrors extends internal.SymbolTable with api.JavaUnive } symbol match { - case Any_== | Object_== => ScalaRunTime.inlinedEquals(objReceiver, objArg0) - case Any_!= | Object_!= => !ScalaRunTime.inlinedEquals(objReceiver, objArg0) - case Any_## | Object_## => ScalaRunTime.hash(objReceiver) + case Any_== | Object_== => objReceiver == objArg0 + case Any_!= | Object_!= => objReceiver != objArg0 + case Any_## | Object_## => objReceiver.## case Any_equals => receiver.equals(objArg0) case Any_hashCode => receiver.hashCode case Any_toString => receiver.toString -- cgit v1.2.3 From 5e7e81ab2a39182b8150c0d661cdbc89ca82c5b0 Mon Sep 17 00:00:00 2001 From: Sébastien Doeraene Date: Wed, 13 Apr 2016 17:11:15 +0200 Subject: Remove plain old dead code in ScalaRunTime. --- src/library/scala/runtime/ScalaRunTime.scala | 26 -------------- .../library/scala/runtime/ScalaRunTime.scala | 40 ---------------------- 2 files changed, 66 deletions(-) diff --git a/src/library/scala/runtime/ScalaRunTime.scala b/src/library/scala/runtime/ScalaRunTime.scala index 7c1a89e248..02f39f6f5f 100644 --- a/src/library/scala/runtime/ScalaRunTime.scala +++ b/src/library/scala/runtime/ScalaRunTime.scala @@ -29,8 +29,6 @@ object ScalaRunTime { private def isArrayClass(clazz: jClass[_], atLevel: Int): Boolean = clazz.isArray && (atLevel == 1 || isArrayClass(clazz.getComponentType, atLevel - 1)) - def isValueClass(clazz: jClass[_]) = clazz.isPrimitive() - // A helper method to make my life in the pattern matcher a lot easier. def drop[Repr](coll: Repr, num: Int)(implicit traversable: IsTraversableLike[Repr]): Repr = traversable conversion coll drop num @@ -141,9 +139,6 @@ object ScalaRunTime { // More background at ticket #2318. def ensureAccessible(m: JMethod): JMethod = scala.reflect.ensureAccessible(m) - def checkInitialized[T <: AnyRef](x: T): T = - if (x == null) throw new UninitializedError else x - def _toString(x: Product): String = x.productIterator.mkString(x.productPrefix + "(", ",", ")") @@ -163,33 +158,12 @@ object ScalaRunTime { } } - /** Fast path equality method for inlining; used when -optimise is set. - */ - @inline def inlinedEquals(x: Object, y: Object): Boolean = - if (x eq y) true - else if (x eq null) false - else if (x.isInstanceOf[java.lang.Number]) BoxesRunTime.equalsNumObject(x.asInstanceOf[java.lang.Number], y) - else if (x.isInstanceOf[java.lang.Character]) BoxesRunTime.equalsCharObject(x.asInstanceOf[java.lang.Character], y) - else x.equals(y) - - def _equals(x: Product, y: Any): Boolean = y match { - case y: Product if x.productArity == y.productArity => x.productIterator sameElements y.productIterator - case _ => false - } - /** Implementation of `##`. */ def hash(x: Any): Int = if (x == null) 0 else if (x.isInstanceOf[java.lang.Number]) BoxesRunTime.hashFromNumber(x.asInstanceOf[java.lang.Number]) else x.hashCode - /** A helper method for constructing case class equality methods, - * because existential types get in the way of a clean outcome and - * it's performing a series of Any/Any equals comparisons anyway. - * See ticket #2867 for specifics. - */ - def sameElements(xs1: scala.collection.Seq[Any], xs2: scala.collection.Seq[Any]) = xs1 sameElements xs2 - /** Given any Scala value, convert it to a String. * * The primary motivation for this method is to provide a means for diff --git a/test/instrumented/library/scala/runtime/ScalaRunTime.scala b/test/instrumented/library/scala/runtime/ScalaRunTime.scala index 7bd94ef7ca..7480ad6fbf 100644 --- a/test/instrumented/library/scala/runtime/ScalaRunTime.scala +++ b/test/instrumented/library/scala/runtime/ScalaRunTime.scala @@ -35,8 +35,6 @@ object ScalaRunTime { private def isArrayClass(clazz: jClass[_], atLevel: Int): Boolean = clazz.isArray && (atLevel == 1 || isArrayClass(clazz.getComponentType, atLevel - 1)) - def isValueClass(clazz: jClass[_]) = clazz.isPrimitive() - /** Return the class object representing an array with element class `clazz`. */ def arrayClass(clazz: jClass[_]): jClass[_] = { @@ -153,9 +151,6 @@ object ScalaRunTime { m } - def checkInitialized[T <: AnyRef](x: T): T = - if (x == null) throw new UninitializedError else x - def _toString(x: Product): String = x.productIterator.mkString(x.productPrefix + "(", ",", ")") @@ -175,33 +170,12 @@ object ScalaRunTime { } } - /** Fast path equality method for inlining; used when -optimise is set. - */ - @inline def inlinedEquals(x: Object, y: Object): Boolean = - if (x eq y) true - else if (x eq null) false - else if (x.isInstanceOf[java.lang.Number]) BoxesRunTime.equalsNumObject(x.asInstanceOf[java.lang.Number], y) - else if (x.isInstanceOf[java.lang.Character]) BoxesRunTime.equalsCharObject(x.asInstanceOf[java.lang.Character], y) - else x.equals(y) - - def _equals(x: Product, y: Any): Boolean = y match { - case y: Product if x.productArity == y.productArity => x.productIterator sameElements y.productIterator - case _ => false - } - /** Implementation of `##`. */ def hash(x: Any): Int = if (x == null) 0 else if (x.isInstanceOf[java.lang.Number]) BoxesRunTime.hashFromNumber(x.asInstanceOf[java.lang.Number]) else x.hashCode - /** A helper method for constructing case class equality methods, - * because existential types get in the way of a clean outcome and - * it's performing a series of Any/Any equals comparisons anyway. - * See ticket #2867 for specifics. - */ - def sameElements(xs1: scala.collection.Seq[Any], xs2: scala.collection.Seq[Any]) = xs1 sameElements xs2 - /** Given any Scala value, convert it to a String. * * The primary motivation for this method is to provide a means for @@ -293,18 +267,4 @@ object ScalaRunTime { nl + s + "\n" } - private[scala] def checkZip(what: String, coll1: TraversableOnce[_], coll2: TraversableOnce[_]) { - if (sys.props contains "scala.debug.zip") { - val xs = coll1.toIndexedSeq - val ys = coll2.toIndexedSeq - if (xs.length != ys.length) { - Console.err.println( - "Mismatched zip in " + what + ":\n" + - " this: " + xs.mkString(", ") + "\n" + - " that: " + ys.mkString(", ") - ) - (new Exception).getStackTrace.drop(2).take(10).foreach(println) - } - } - } } -- cgit v1.2.3 From 468deadf2aad90fbb61036c66cfa298f33ff6009 Mon Sep 17 00:00:00 2001 From: Sébastien Doeraene Date: Wed, 13 Apr 2016 17:12:16 +0200 Subject: Remove the unused scala.runtime.Boxed trait. --- src/library/scala/runtime/Boxed.scala | 12 ------------ 1 file changed, 12 deletions(-) delete mode 100644 src/library/scala/runtime/Boxed.scala diff --git a/src/library/scala/runtime/Boxed.scala b/src/library/scala/runtime/Boxed.scala deleted file mode 100644 index 933444773d..0000000000 --- a/src/library/scala/runtime/Boxed.scala +++ /dev/null @@ -1,12 +0,0 @@ -/* __ *\ -** ________ ___ / / ___ Scala API ** -** / __/ __// _ | / / / _ | (c) 2003-2013, LAMP/EPFL ** -** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** -** /____/\___/_/ |_/____/_/ | | ** -** |/ ** -\* */ - -package scala -package runtime - -trait Boxed { } -- cgit v1.2.3