This fixes PR36477 by allocating a different new capacity when allocating a new array following a write rather than growing. CPStringBuilder was continually allocating larger and larger arrays even when the current array was still underused.
ChangeLog: 2008-06-15 Andrew John Hughes <[EMAIL PROTECTED]> PR classpath/36477: * gnu/java/lang/CPStringBuilder.java, (setLength(int)): Don't ensure capacity when new length is 0. (ensureCapacity(int)): Allocate double the minimum capacity rather than double the array length when allocating a new array after a write. -- Andrew :) Support Free Java! Contribute to GNU Classpath and the OpenJDK http://www.gnu.org/software/classpath http://openjdk.java.net PGP Key: 94EFD9D8 (http://subkeys.pgp.net) Fingerprint = F8EF F1EA 401E 2E60 15FA 7927 142C 2591 94EF D9D8
Index: gnu/java/lang/CPStringBuilder.java =================================================================== RCS file: /sources/classpath/classpath/gnu/java/lang/CPStringBuilder.java,v retrieving revision 1.9 diff -u -u -r1.9 CPStringBuilder.java --- gnu/java/lang/CPStringBuilder.java 11 May 2008 22:57:16 -0000 1.9 +++ gnu/java/lang/CPStringBuilder.java 15 Jun 2008 21:25:21 -0000 @@ -204,8 +204,11 @@ int valueLength = value.length; /* Always call ensureCapacity in order to preserve - copy-on-write semantics. */ - ensureCapacity(newLength); + copy-on-write semantics, except when the position + is simply being reset + */ + if (newLength > 0) + ensureCapacity(newLength); if (newLength < valueLength) { @@ -1036,18 +1039,24 @@ * Increase the capacity of this <code>StringBuilder</code>. This will * ensure that an expensive growing operation will not occur until either * <code>minimumCapacity</code> is reached or the array has been allocated. - * The buffer is grown to the larger of <code>minimumCapacity</code> and + * The buffer is grown to either <code>minimumCapacity * 2</code>, if + * the array has been allocated or the larger of <code>minimumCapacity</code> and * <code>capacity() * 2 + 2</code>, if it is not already large enough. * * @param minimumCapacity the new capacity - * @see #capacity() + * @see #length() */ public void ensureCapacity(int minimumCapacity) { if (allocated || minimumCapacity > value.length) { - int max = value.length * 2 + 2; - minimumCapacity = (minimumCapacity < max ? max : minimumCapacity); + if (minimumCapacity > value.length) + { + int max = value.length * 2 + 2; + minimumCapacity = (minimumCapacity < max ? max : minimumCapacity); + } + else + minimumCapacity *= 2; allocateArray(minimumCapacity); } }