summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMiguel Garcia <miguelalfredo.garcia@epfl.ch>2012-12-28 15:21:28 +0100
committerMiguel Garcia <miguelalfredo.garcia@epfl.ch>2012-12-28 15:21:28 +0100
commit7abb0c911a7c3d60057fbcab6fc3687322a67082 (patch)
tree02f347d74ae77e3197aa279a7c7bbb206de19907 /src
parent5b5635ee9d227ff61834f5a538d0f8082192f9b6 (diff)
downloadscala-7abb0c911a7c3d60057fbcab6fc3687322a67082.tar.gz
scala-7abb0c911a7c3d60057fbcab6fc3687322a67082.tar.bz2
scala-7abb0c911a7c3d60057fbcab6fc3687322a67082.zip
fusion of loops in Range.foreach() and Range.validateRangeBoundaries()
This commit allows closure elimination in more cases. The non-inlined case also benefits from saving a Range.validateRangeBoundaries() invocation. Before this commit, the closure argument to Range.foreach() escaped to Range.validateRangeBoundaries(). As a consequence, closure elimination required inlining both of them. Given that the current optimizer duplicates a closure body whenever that closure's apply() is invoked, the resulting code size taxed the JIT compiler. In particular when apply() delegates to a specialized version, or when a bridge apply() stands in the way.
Diffstat (limited to 'src')
-rw-r--r--src/library/scala/collection/immutable/Range.scala22
1 files changed, 14 insertions, 8 deletions
diff --git a/src/library/scala/collection/immutable/Range.scala b/src/library/scala/collection/immutable/Range.scala
index 02c10700b1..480c88ddcf 100644
--- a/src/library/scala/collection/immutable/Range.scala
+++ b/src/library/scala/collection/immutable/Range.scala
@@ -112,6 +112,7 @@ extends scala.collection.AbstractSeq[Int]
fail()
}
+ @deprecated("Range.foreach() is now self-contained, making this auxiliary method redundant.", "2.10.1")
def validateRangeBoundaries(f: Int => Any): Boolean = {
validateMaxLength()
@@ -134,14 +135,19 @@ extends scala.collection.AbstractSeq[Int]
}
@inline final override def foreach[@specialized(Unit) U](f: Int => U) {
- if (validateRangeBoundaries(f)) {
- var i = start
- val terminal = terminalElement
- val step = this.step
- while (i != terminal) {
- f(i)
- i += step
- }
+ validateMaxLength()
+ val isCommonCase = (start != Int.MinValue || end != Int.MinValue)
+ var i = start
+ var count = 0
+ val terminal = terminalElement
+ val step = this.step
+ while(
+ if(isCommonCase) { i != terminal }
+ else { count < numRangeElements }
+ ) {
+ f(i)
+ count += 1
+ i += step
}
}