From 43b3042517bf4aa9b22c22547433cc6c2c24d7d1 Mon Sep 17 00:00:00 2001 From: Jason Zaugg Date: Tue, 29 Mar 2016 09:15:22 +1000 Subject: Avoid intermediate boxing in BoxesRuntime.hashCodeFrom By using newly introduced static methods in the Java standard library. --- src/library/scala/runtime/BoxesRunTime.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/library') diff --git a/src/library/scala/runtime/BoxesRunTime.java b/src/library/scala/runtime/BoxesRunTime.java index 96e0f23f3d..9ae118f43f 100644 --- a/src/library/scala/runtime/BoxesRunTime.java +++ b/src/library/scala/runtime/BoxesRunTime.java @@ -236,10 +236,10 @@ public final class BoxesRunTime if (iv == dv) return iv; long lv = n.longValue(); - if (lv == dv) return java.lang.Long.valueOf(lv).hashCode(); + if (lv == dv) return java.lang.Long.hashCode(lv); float fv = n.floatValue(); - if (fv == dv) return java.lang.Float.valueOf(fv).hashCode(); + if (fv == dv) return java.lang.Float.hashCode(fv); else return n.hashCode(); } public static int hashFromFloat(java.lang.Float n) { @@ -248,7 +248,7 @@ public final class BoxesRunTime if (iv == fv) return iv; long lv = n.longValue(); - if (lv == fv) return java.lang.Long.valueOf(lv).hashCode(); + if (lv == fv) return java.lang.Long.hashCode(lv); else return n.hashCode(); } public static int hashFromNumber(java.lang.Number n) { -- cgit v1.2.3 From ca606e6943c405e487c54c3fd14a3a8ac917bb2e Mon Sep 17 00:00:00 2001 From: Jason Zaugg Date: Tue, 29 Mar 2016 09:30:31 +1000 Subject: Delegate more primitive comparison to the Java stdlib The API for doing so efficiently was made regular in Java 1.8. --- src/library/scala/math/Ordering.scala | 22 ++++++---------------- 1 file changed, 6 insertions(+), 16 deletions(-) (limited to 'src/library') diff --git a/src/library/scala/math/Ordering.scala b/src/library/scala/math/Ordering.scala index 827cccc77e..37096d5ed0 100644 --- a/src/library/scala/math/Ordering.scala +++ b/src/library/scala/math/Ordering.scala @@ -224,42 +224,32 @@ object Ordering extends LowPriorityOrderingImplicits { implicit object Unit extends UnitOrdering trait BooleanOrdering extends Ordering[Boolean] { - def compare(x: Boolean, y: Boolean) = (x, y) match { - case (false, true) => -1 - case (true, false) => 1 - case _ => 0 - } + def compare(x: Boolean, y: Boolean) = java.lang.Boolean.compare(x, y) } implicit object Boolean extends BooleanOrdering trait ByteOrdering extends Ordering[Byte] { - def compare(x: Byte, y: Byte) = x.toInt - y.toInt + def compare(x: Byte, y: Byte) = java.lang.Byte.compare(x, y) } implicit object Byte extends ByteOrdering trait CharOrdering extends Ordering[Char] { - def compare(x: Char, y: Char) = x.toInt - y.toInt + def compare(x: Char, y: Char) = java.lang.Character.compare(x, y) } implicit object Char extends CharOrdering trait ShortOrdering extends Ordering[Short] { - def compare(x: Short, y: Short) = x.toInt - y.toInt + def compare(x: Short, y: Short) = java.lang.Short.compare(x, y) } implicit object Short extends ShortOrdering trait IntOrdering extends Ordering[Int] { - def compare(x: Int, y: Int) = - if (x < y) -1 - else if (x == y) 0 - else 1 + def compare(x: Int, y: Int) = java.lang.Integer.compare(x, y) } implicit object Int extends IntOrdering trait LongOrdering extends Ordering[Long] { - def compare(x: Long, y: Long) = - if (x < y) -1 - else if (x == y) 0 - else 1 + def compare(x: Long, y: Long) = java.lang.Long.compare(x, y) } implicit object Long extends LongOrdering -- cgit v1.2.3 From d40f1b81372e1cdb101790d14c5bc8c7c304c128 Mon Sep 17 00:00:00 2001 From: Jason Zaugg Date: Tue, 29 Mar 2016 10:01:24 +1000 Subject: SI-7474 Record extra errors in Throwable#suppressedExceptions ... in parallel collection operations. Followup to bcbe38d18, which did away with the the approach to use a composite exception when more than one error happened. --- src/library/scala/collection/parallel/Tasks.scala | 11 ++++------- test/files/run/t5375.check | 1 - test/files/run/t5375.scala | 16 ++++++++++++---- 3 files changed, 16 insertions(+), 12 deletions(-) (limited to 'src/library') diff --git a/src/library/scala/collection/parallel/Tasks.scala b/src/library/scala/collection/parallel/Tasks.scala index c9a75752df..2a4e40dd16 100644 --- a/src/library/scala/collection/parallel/Tasks.scala +++ b/src/library/scala/collection/parallel/Tasks.scala @@ -66,13 +66,10 @@ trait Task[R, +Tp] { } private[parallel] def mergeThrowables(that: Task[_, _]) { - // TODO: As soon as we target Java >= 7, use Throwable#addSuppressed - // to pass additional Throwables to the caller, e. g. - // if (this.throwable != null && that.throwable != null) - // this.throwable.addSuppressed(that.throwable) - // For now, we just use whatever Throwable comes across “first”. - if (this.throwable == null && that.throwable != null) - this.throwable = that.throwable + if (this.throwable != null && that.throwable != null) + this.throwable.addSuppressed(that.throwable) + else if (this.throwable == null && that.throwable != null) + this.throwable = that.throwable } // override in concrete task implementations to signal abort to other tasks diff --git a/test/files/run/t5375.check b/test/files/run/t5375.check index b1a57eeeec..e69de29bb2 100644 --- a/test/files/run/t5375.check +++ b/test/files/run/t5375.check @@ -1 +0,0 @@ -Runtime exception diff --git a/test/files/run/t5375.scala b/test/files/run/t5375.scala index 826ecd841e..2028b6f05d 100644 --- a/test/files/run/t5375.scala +++ b/test/files/run/t5375.scala @@ -1,8 +1,16 @@ object Test extends App { val foos = (1 to 1000).toSeq - try - foos.par.map(i => if (i % 37 == 0) sys.error("i div 37") else i) - catch { - case ex: RuntimeException => println("Runtime exception") + try { + foos.par.map(i => if (i % 37 == 0) throw new MultipleOf37Exception(i) else i) + assert(false) + } catch { + case ex: MultipleOf37Exception => + assert(ex.getSuppressed.size > 0) + assert(ex.getSuppressed.forall(_.isInstanceOf[MultipleOf37Exception])) + assert(ex.i == 37) + assert(ex.getSuppressed.map(_.asInstanceOf[MultipleOf37Exception].i).toList == List(74, 148, 259, 518)) + case _: Throwable => + assert(false) } + class MultipleOf37Exception(val i: Int) extends RuntimeException } -- cgit v1.2.3 From eb6e29d27eb9cac0430fb34c485788cf3108fe00 Mon Sep 17 00:00:00 2001 From: Jason Zaugg Date: Tue, 29 Mar 2016 10:07:28 +1000 Subject: Note the availability of writableStackTrace in JDK 1.7+ --- src/library/scala/util/control/NoStackTrace.scala | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/library') diff --git a/src/library/scala/util/control/NoStackTrace.scala b/src/library/scala/util/control/NoStackTrace.scala index 3c42944af1..3647af4ac3 100644 --- a/src/library/scala/util/control/NoStackTrace.scala +++ b/src/library/scala/util/control/NoStackTrace.scala @@ -14,6 +14,8 @@ package util.control * on a global basis via a system property wrapper in * [[scala.sys.SystemProperties]]. * + * @note Since JDK 1.7, a similar effect can be achieved with `class Ex extends Throwable(..., writableStackTrace = false)` + * * @author Paul Phillips * @since 2.8 */ -- cgit v1.2.3 From 8b2e616c75026484fcfb75c4fdb50f2f94fda4e6 Mon Sep 17 00:00:00 2001 From: Jason Zaugg Date: Tue, 29 Mar 2016 10:23:36 +1000 Subject: Use Java's highestOneBit, rather than our own versions. The original code came from 2008, (a4ace382), at which point we probably couldn't use JDK 1.5+ methods. I haven't changed `unsignedCompare` yet to use the standard library version, as it our version might have different performance characteristics. Background: http://www.drmaciver.com/2008/08/unsigned-comparison-in-javascala/ --- .../scala/collection/generic/BitOperations.scala | 23 ++-------------------- 1 file changed, 2 insertions(+), 21 deletions(-) (limited to 'src/library') diff --git a/src/library/scala/collection/generic/BitOperations.scala b/src/library/scala/collection/generic/BitOperations.scala index d430ece2f5..2f460eee1f 100644 --- a/src/library/scala/collection/generic/BitOperations.scala +++ b/src/library/scala/collection/generic/BitOperations.scala @@ -26,16 +26,7 @@ private[collection] object BitOperations { def complement(i: Int) = (-1) ^ i def bits(num: Int) = 31 to 0 by -1 map (i => (num >>> i & 1) != 0) def bitString(num: Int, sep: String = "") = bits(num) map (b => if (b) "1" else "0") mkString sep - - def highestOneBit(j: Int) = { - var i = j - i |= (i >> 1) - i |= (i >> 2) - i |= (i >> 4) - i |= (i >> 8) - i |= (i >> 16) - i - (i >>> 1) - } + def highestOneBit(j: Int) = java.lang.Integer.highestOneBit(j) } object Int extends Int @@ -49,17 +40,7 @@ private[collection] object BitOperations { def complement(i: Long) = (-1L) ^ i def bits(num: Long) = 63L to 0L by -1L map (i => (num >>> i & 1L) != 0L) def bitString(num: Long, sep: String = "") = bits(num) map (b => if (b) "1" else "0") mkString sep - - def highestOneBit(j: Long) = { - var i = j - i |= (i >> 1) - i |= (i >> 2) - i |= (i >> 4) - i |= (i >> 8) - i |= (i >> 16) - i |= (i >> 32) - i - (i >>> 1) - } + def highestOneBit(j: Long) = java.lang.Long.highestOneBit(j) } object Long extends Long } -- cgit v1.2.3 From 5b11d3ecad2803a0d0cb81a7a29faf0a4389a6b3 Mon Sep 17 00:00:00 2001 From: Jason Zaugg Date: Tue, 29 Mar 2016 10:36:16 +1000 Subject: Use System.lineSeparator, rather than sys.props --- src/library/scala/compat/Platform.scala | 3 +-- src/library/scala/sys/process/BasicIO.scala | 2 +- src/library/scala/util/Properties.scala | 2 +- 3 files changed, 3 insertions(+), 4 deletions(-) (limited to 'src/library') diff --git a/src/library/scala/compat/Platform.scala b/src/library/scala/compat/Platform.scala index 42dfcbfdde..f3745bc189 100644 --- a/src/library/scala/compat/Platform.scala +++ b/src/library/scala/compat/Platform.scala @@ -105,8 +105,7 @@ object Platform { /** The default line separator. * * On the JVM, this is equivalent to calling the method: - * `System.getProperty("line.separator")` - * with a default value of "\n". + * `java.lang.System.lineSeparator` */ val EOL = scala.util.Properties.lineSeparator diff --git a/src/library/scala/sys/process/BasicIO.scala b/src/library/scala/sys/process/BasicIO.scala index 640f7e68c2..b39ae77c62 100644 --- a/src/library/scala/sys/process/BasicIO.scala +++ b/src/library/scala/sys/process/BasicIO.scala @@ -33,7 +33,7 @@ object BasicIO { final val BufferSize = 8192 /** Used to separate lines in the `processFully` function that takes `Appendable`. */ - final val Newline = props("line.separator") + final val Newline = System.lineSeparator private[process] final class Streamed[T]( val process: T => Unit, diff --git a/src/library/scala/util/Properties.scala b/src/library/scala/util/Properties.scala index 583f1539d1..a176748cd6 100644 --- a/src/library/scala/util/Properties.scala +++ b/src/library/scala/util/Properties.scala @@ -120,7 +120,7 @@ private[scala] trait PropertiesTrait { /** The default end of line character. */ - def lineSeparator = propOrElse("line.separator", "\n") + def lineSeparator = System.lineSeparator() /* Various well-known properties. */ def javaClassPath = propOrEmpty("java.class.path") -- cgit v1.2.3