diff options
author | Miguel Garcia <miguelalfredo.garcia@epfl.ch> | 2012-12-28 15:21:28 +0100 |
---|---|---|
committer | Miguel Garcia <miguelalfredo.garcia@epfl.ch> | 2012-12-28 15:21:28 +0100 |
commit | 7abb0c911a7c3d60057fbcab6fc3687322a67082 (patch) | |
tree | 02f347d74ae77e3197aa279a7c7bbb206de19907 /src | |
parent | 5b5635ee9d227ff61834f5a538d0f8082192f9b6 (diff) | |
download | scala-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.scala | 22 |
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 } } |