2008/5/12 David Daney <[EMAIL PROTECTED]>: > Andrew John Hughes wrote: > > > This adds a feature to CPStringBuilder so that it knows > > when its array has been shared with a String object. Once > > this has happened, any future write operations will allocate > > a new array and reset the flag. This fixes the issue in > > PR36147. > > > > ChangeLog: > > > > 2008-05-11 Andrew John Hughes <[EMAIL PROTECTED]> > > > > PR classpath/36147 > > * gnu/java/lang/CPStringBuilder.java: > > (allocated): New flag to mark whether or > > not the array has been allocated to a String object. > > (ensureCapacity(int)): Removed. > > (ensureCapacity_unsynchronized(int)): Renamed to > > ensureCapacity, and creates an array when allocated > > is true. > > (allocateArray(int)): Added. > > (trimToSize()): Use allocateArray method. > > (toString()): Set allocated to true; > > (substring(int,int)): Likewise. > > > > > > > Why not just use java.lang.StingBuilder in the cases where the > StringBuilder is modified after an initial toString() call? >
We do. > My understanding of your CPStringBuilder work is that it was for the > constrained conditions of single threaded access with a single toString() > call after which it would be discarded. It is, and this is where it has been used. If we have to allocate another > array, we gain nothing over java.lang.StringBuilder other than making the > code more confusing. I am uncomfortable with this change as well as the use > of CPStringBuilder that makes it necessary. > > Am I missing something here? > I agree. This patch doesn't advocate such use, it just makes it safe should it occur. Otherwise we end up with mutable Strings. StringBuilder and CPStringBuilder are still different. In the normal usage of single threaded access with a closing toString() or substring() call, CPStringBuilder operates exactly as it did before; this patch doesn't change that. It has one character array, and this is assigned not copied to the String when toString or substring is called. By comparison, StringBuilder fills one array, and then allocates a new one and copies over the data when toString() or substring() is called. CPStringBuilder only does such a copy should some mutable operation be called after toString or substring. We try and avoid this, but this at least makes CPStringBuilder safe and equivalent to StringBuilder should this happen. To clarify, the process for CPStringBuilder is: 1. An array is allocated on creation 2. Append/insert/replace/delete operations affect the data in this array. These may cause a new array to be allocated if the capacity of the current one is exceeded (see ensureCapacity). 3. toString or substring is called. The package-private String constructor is called with a reference to the array so that both the CPStringBuilder and the newly created String have a reference to the array. The CPStringBuilder sets a flag to remember this. 4. In the usual case, the CPStringBuilder now goes out of scope and so only the String maintains a reference to the array. Should this not be the case and a mutable operation is called, we allocate a new array, copy over the data and start from step 2 again. By contrast, a copy *always* happens with a StringBuilder in stage 3. So, assuming the array does not need to grow, the CPStringBuilder can operate with no array copies, while the StringBuilder has a minimum of 1. > David Daney > > Hope that clears things up, -- 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