8000 Merge pull request #3860 from gourlaysama/wip/t7710-backport · scala/scala-dev@ac7e102 · GitHub
[go: up one dir, main page]

Skip to content

Commit ac7e102

Browse files
committed
Merge pull request #3860 from gourlaysama/wip/t7710-backport
[backport] SI-7710 fix memory performance of RegexParsers in jdk7u6+
2 parents b5759ef + fceae70 commit ac7e102

File tree

3 files changed

+39
-3
lines changed

3 files changed

+39
-3
lines changed

bincompat-forward.whitelist.conf

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,11 @@ filter {
177177
{
178178
matchName="scala.reflect.runtime.JavaMirrors#JavaMirror.scala$reflect$runtime$JavaMirrors$JavaMirror$$followStatic"
179179
problemName=MissingMethodProblem
180+
},
181+
{
182+
# only accessible from util.parsing.combinator package
183+
matchName="scala.util.parsing.combinator.SubSequence"
184+
problemName=MissingClassProblem
180185
}
181-
182186
]
183187
}

src/library/scala/util/parsing/combinator/RegexParsers.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ trait RegexParsers extends Parsers {
7272
*/
7373
protected def handleWhiteSpace(source: java.lang.CharSequence, offset: Int): Int =
7474
if (skipWhitespace)
75-
(whiteSpace findPrefixMatchOf (source.subSequence(offset, source.length))) match {
75+
(whiteSpace findPrefixMatchOf (new SubSequence(source, offset))) match {
7676
case Some(matched) => offset + matched.end
7777
case None => offset
7878
}
@@ -106,7 +106,7 @@ trait RegexParsers extends Parsers {
106106
val source = in.source
107107
val offset = in.offset
108108
val start = handleWhiteSpace(source, offset)
109-
(r findPrefixMatchOf (source.subSequence(start, source.length))) match {
109+
(r findPrefixMatchOf (new SubSequence(source, start))) match {
110110
case Some(matched) =>
111111
Success(source.subSequence(start, start + matched.end).toString,
112112
in.drop(start + matched.end - offset))
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/* __ *\
2+
** ________ ___ / / ___ Scala API **
3+
** / __/ __// _ | / / / _ | (c) 2006-2013, LAMP/EPFL **
4+
** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
5+
** /____/\___/_/ |_/____/_/ | | **
6+
** |/ **
7+
\* */
8+
9+
10+
package scala
11+
package util.parsing.combinator
12+
13+
// A shallow wrapper over another CharSequence (usually a String)
14+
//
15+
// See SI-7710: in jdk7u6 String.subSequence stopped sharing the char array of the original
16+
// string and began copying it.
17+
// RegexParsers calls subSequence twice per input character: that's a lot of array copying!
18+
private[combinator] class SubSequence(s: CharSequence, start: Int, val length: Int) extends CharSequence {
19+
def this(s: CharSequence, start: Int) = this(s, start, s.length - start)
20+
21+
def charAt(i: Int) =
22+
if (i >= 0 && i < length) s.charAt(start + i) else throw new IndexOutOfBoundsException(s"index: $i, length: $length")
23+
24+
def subSequence(_start: Int, _end: Int) = {
25+
if (_start < 0 || _end < 0 || _end > length || _start > _end)
26+
throw new IndexOutOfBoundsException(s"start: ${_start}, end: ${_end}, length: $length")
27+
28+
new SubSequence(s, start + _start, _end - _start)
29+
}
30+
31+
override def toString = s.subSequence(start, start + length).toString
32+
}

0 commit comments

Comments
 (0)
0