< prev index next >

src/java.base/share/classes/java/lang/AbstractStringBuilder.java

Print this page
rev 13764 : [mq]: 8149330-Friendly-realloc-in-StringBuilder


 121      * </ul>
 122      * If the {@code minimumCapacity} argument is nonpositive, this
 123      * method takes no action and simply returns.
 124      * Note that subsequent operations on this object can reduce the
 125      * actual capacity below that requested here.
 126      *
 127      * @param   minimumCapacity   the minimum desired capacity.
 128      */
 129     public void ensureCapacity(int minimumCapacity) {
 130         if (minimumCapacity > 0) {
 131             ensureCapacityInternal(minimumCapacity);
 132         }
 133     }
 134 
 135     /**
 136      * This method has the same contract as ensureCapacity, but is
 137      * never synchronized.
 138      */
 139     private void ensureCapacityInternal(int minimumCapacity) {
 140         // overflow-conscious code
 141         int capacity = value.length >> coder;
 142         if (minimumCapacity - capacity > 0) {
 143             expandCapacity(minimumCapacity);

 144         }
 145     }
 146 
 147     /**
 148      * This implements the expansion semantics of ensureCapacity with no
 149      * size check or synchronization.


 150      */
 151     private void expandCapacity(int minimumCapacity) {
 152         int newCapacity = (value.length >> coder) * 2 + 2;
 153         if (newCapacity - minimumCapacity < 0) {
 154             newCapacity = minimumCapacity;
 155         }
 156         if (newCapacity < 0) {
 157             if (minimumCapacity < 0) {// overflow
 158                 throw new OutOfMemoryError();
 159             }
 160             newCapacity = Integer.MAX_VALUE;














 161         }
 162         if (coder != LATIN1 && newCapacity > StringUTF16.MAX_LENGTH) {
 163             if (minimumCapacity >= StringUTF16.MAX_LENGTH) {



 164                 throw new OutOfMemoryError();
 165             }
 166             newCapacity = StringUTF16.MAX_LENGTH;
 167         }
 168         this.value = Arrays.copyOf(value, newCapacity << coder);
 169     }
 170 
 171     /**
 172      * If the coder is "isLatin1", this inflates the internal 8-bit storage
 173      * to 16-bit <hi=0, low> pair storage.
 174      */
 175     private void inflate() {
 176         if (!isLatin1()) {
 177             return;
 178         }
 179         byte[] buf = StringUTF16.newBytesFor(value.length);
 180         StringLatin1.inflate(value, 0, buf, 0, count);
 181         this.value = buf;
 182         this.coder = UTF16;
 183     }
 184 
 185     /**
 186      * Attempts to reduce storage used for the character sequence.
 187      * If the buffer is larger than necessary to hold its current sequence of
 188      * characters, then it may be resized to become more space efficient.




 121      * </ul>
 122      * If the {@code minimumCapacity} argument is nonpositive, this
 123      * method takes no action and simply returns.
 124      * Note that subsequent operations on this object can reduce the
 125      * actual capacity below that requested here.
 126      *
 127      * @param   minimumCapacity   the minimum desired capacity.
 128      */
 129     public void ensureCapacity(int minimumCapacity) {
 130         if (minimumCapacity > 0) {
 131             ensureCapacityInternal(minimumCapacity);
 132         }
 133     }
 134 
 135     /**
 136      * This method has the same contract as ensureCapacity, but is
 137      * never synchronized.
 138      */
 139     private void ensureCapacityInternal(int minimumCapacity) {
 140         // overflow-conscious code
 141         int oldCapacity = value.length >> coder;
 142         if (minimumCapacity - oldCapacity > 0) {
 143             value = Arrays.copyOf(value,
 144                     newCapacity(minimumCapacity) << coder);
 145         }
 146     }
 147 
 148     /**
 149      * The maximum size of array to allocate (unless necessary).
 150      * Some VMs reserve some header words in an array.
 151      * Attempts to allocate larger arrays may result in
 152      * OutOfMemoryError: Requested array size exceeds VM limit
 153      */
 154     private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
 155 
 156     /**
 157      * Returns a capacity at least as large as the given minimum capacity.
 158      * Returns the current capacity increased by the same amount + 2 if
 159      * that suffices.
 160      * Will not return a capacity greater than (MAX_ARRAY_SIZE >> coder)
 161      * unless the given minimum capacity is greater than that.
 162      *
 163      * @param minCapacity the desired minimum capacity
 164      * @throws OutOfMemoryError if minCapacity is less than zero or
 165      *         greater than (Integer.MAX_VALUE >> coder)
 166      */
 167     private int newCapacity(int minCapacity) {
 168         // overflow-conscious code
 169         int oldCapacity = value.length >> coder;
 170         int newCapacity = (oldCapacity << 1) + 2;
 171         if (newCapacity - minCapacity < 0) {
 172             newCapacity = minCapacity;
 173         }
 174         int SAFE_BOUND = MAX_ARRAY_SIZE >> coder;
 175         return (newCapacity <= 0 || SAFE_BOUND - newCapacity < 0)
 176             ? hugeCapacity(minCapacity)
 177             : newCapacity;
 178     }
 179 
 180     private int hugeCapacity(int minCapacity) {
 181         int SAFE_BOUND = MAX_ARRAY_SIZE >> coder;
 182         int UNSAFE_BOUND = Integer.MAX_VALUE >> coder;
 183         if (UNSAFE_BOUND - minCapacity < 0) { // overflow
 184             throw new OutOfMemoryError();
 185         }
 186         return (minCapacity > SAFE_BOUND)
 187             ? minCapacity : SAFE_BOUND;

 188     }
 189 
 190     /**
 191      * If the coder is "isLatin1", this inflates the internal 8-bit storage
 192      * to 16-bit <hi=0, low> pair storage.
 193      */
 194     private void inflate() {
 195         if (!isLatin1()) {
 196             return;
 197         }
 198         byte[] buf = StringUTF16.newBytesFor(value.length);
 199         StringLatin1.inflate(value, 0, buf, 0, count);
 200         this.value = buf;
 201         this.coder = UTF16;
 202     }
 203 
 204     /**
 205      * Attempts to reduce storage used for the character sequence.
 206      * If the buffer is larger than necessary to hold its current sequence of
 207      * characters, then it may be resized to become more space efficient.


< prev index next >