src/share/classes/java/lang/StringBuffer.java
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File
*** old/src/share/classes/java/lang/StringBuffer.java	Mon May 13 03:10:19 2013
--- new/src/share/classes/java/lang/StringBuffer.java	Mon May 13 03:10:17 2013

*** 1,7 **** --- 1,7 ---- /* ! * Copyright (c) 1994, 2012, Oracle and/or its affiliates. All rights reserved. ! * Copyright (c) 1994, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this
*** 23,32 **** --- 23,33 ---- * questions. */ package java.lang; + import java.util.Arrays; /** * A thread-safe, mutable sequence of characters. * A string buffer is like a {@link String}, but can be modified. At any * point in time it contains some particular sequence of characters, but
*** 100,109 **** --- 101,127 ---- /** use serialVersionUID from JDK 1.0.2 for interoperability */ static final long serialVersionUID = 3388685877147921107L; /** + * Tracks if our char[] has been shared with a String returned + * from toString(). We implement a copy-on-write-if-shared scheme + * so that we can avoid an array-copy on toString. Each mutating + * operation copies the char[] if it is being shared. + */ + private transient boolean isShared = false; + + /** + * Performs the copy-on-write-if-shared update + */ + private void COWIS() { + if (isShared) { + value = Arrays.copyOf(value, value.length); + isShared = false; + } + } + /** * Constructs a string buffer with no characters in it and an * initial capacity of 16 characters. */ public StringBuffer() { super(16);
*** 164,190 **** --- 182,214 ---- @Override public synchronized void ensureCapacity(int minimumCapacity) { if (minimumCapacity > value.length) { expandCapacity(minimumCapacity); + isShared = false; } } /** * @since 1.5 */ @Override public synchronized void trimToSize() { + char[] old = value; super.trimToSize(); + if (old != value) { + isShared = false; + } } /** * @throws IndexOutOfBoundsException {@inheritDoc} * @see #length() */ @Override public synchronized void setLength(int newLength) { + COWIS(); super.setLength(newLength); } /** * @throws IndexOutOfBoundsException {@inheritDoc}
*** 245,265 **** --- 269,292 ---- */ @Override public synchronized void setCharAt(int index, char ch) { if ((index < 0) || (index >= count)) throw new StringIndexOutOfBoundsException(index); + COWIS(); value[index] = ch; } @Override public synchronized StringBuffer append(Object obj) { + COWIS(); super.append(String.valueOf(obj)); return this; } @Override public synchronized StringBuffer append(String str) { + COWIS(); super.append(str); return this; } /**
*** 285,303 **** --- 312,332 ---- * @param sb the {@code StringBuffer} to append. * @return a reference to this object. * @since 1.4 */ public synchronized StringBuffer append(StringBuffer sb) { + COWIS(); super.append(sb); return this; } /** * @since 1.8 */ @Override synchronized StringBuffer append(AbstractStringBuilder asb) { + COWIS(); super.append(asb); return this; } /**
*** 323,332 **** --- 352,362 ---- */ @Override public StringBuffer append(CharSequence s) { // Note, synchronization achieved via invocations of other StringBuffer methods after // narrowing of s to specific type + // Ditto for COWIS super.append(s); return this; } /**
*** 334,433 **** --- 364,476 ---- * @since 1.5 */ @Override public synchronized StringBuffer append(CharSequence s, int start, int end) { + COWIS(); super.append(s, start, end); return this; } @Override public synchronized StringBuffer append(char[] str) { + COWIS(); super.append(str); return this; } /** * @throws IndexOutOfBoundsException {@inheritDoc} */ @Override public synchronized StringBuffer append(char[] str, int offset, int len) { + COWIS(); super.append(str, offset, len); return this; } @Override public synchronized StringBuffer append(boolean b) { + COWIS(); super.append(b); return this; } @Override public synchronized StringBuffer append(char c) { + COWIS(); super.append(c); return this; } @Override public synchronized StringBuffer append(int i) { + COWIS(); super.append(i); return this; } /** * @since 1.5 */ @Override public synchronized StringBuffer appendCodePoint(int codePoint) { + COWIS(); super.appendCodePoint(codePoint); return this; } @Override public synchronized StringBuffer append(long lng) { + COWIS(); super.append(lng); return this; } @Override public synchronized StringBuffer append(float f) { + COWIS(); super.append(f); return this; } @Override public synchronized StringBuffer append(double d) { + COWIS(); super.append(d); return this; } /** * @throws StringIndexOutOfBoundsException {@inheritDoc} * @since 1.2 */ @Override public synchronized StringBuffer delete(int start, int end) { + COWIS(); super.delete(start, end); return this; } /** * @throws StringIndexOutOfBoundsException {@inheritDoc} * @since 1.2 */ @Override public synchronized StringBuffer deleteCharAt(int index) { + COWIS(); super.deleteCharAt(index); return this; } /** * @throws StringIndexOutOfBoundsException {@inheritDoc} * @since 1.2 */ @Override public synchronized StringBuffer replace(int start, int end, String str) { + COWIS(); super.replace(start, end, str); return this; } /**
*** 463,499 **** --- 506,546 ---- */ @Override public synchronized StringBuffer insert(int index, char[] str, int offset, int len) { + COWIS(); super.insert(index, str, offset, len); return this; } /** * @throws StringIndexOutOfBoundsException {@inheritDoc} */ @Override public synchronized StringBuffer insert(int offset, Object obj) { + COWIS(); super.insert(offset, String.valueOf(obj)); return this; } /** * @throws StringIndexOutOfBoundsException {@inheritDoc} */ @Override public synchronized StringBuffer insert(int offset, String str) { + COWIS(); super.insert(offset, str); return this; } /** * @throws StringIndexOutOfBoundsException {@inheritDoc} */ @Override public synchronized StringBuffer insert(int offset, char[] str) { + COWIS(); super.insert(offset, str); return this; } /**
*** 502,511 **** --- 549,559 ---- */ @Override public StringBuffer insert(int dstOffset, CharSequence s) { // Note, synchronization achieved via invocations of other StringBuffer methods // after narrowing of s to specific type + // Ditto for COWIS super.insert(dstOffset, s); return this; } /**
*** 514,523 **** --- 562,572 ---- */ @Override public synchronized StringBuffer insert(int dstOffset, CharSequence s, int start, int end) { + COWIS(); super.insert(dstOffset, s, start, end); return this; } /**
*** 525,543 **** --- 574,594 ---- */ @Override public StringBuffer insert(int offset, boolean b) { // Note, synchronization achieved via invocation of StringBuffer insert(int, String) // after conversion of b to String by super class method + // Ditto for COWIS super.insert(offset, b); return this; } /** * @throws IndexOutOfBoundsException {@inheritDoc} */ @Override public synchronized StringBuffer insert(int offset, char c) { + COWIS(); super.insert(offset, c); return this; } /**
*** 545,554 **** --- 596,606 ---- */ @Override public StringBuffer insert(int offset, int i) { // Note, synchronization achieved via invocation of StringBuffer insert(int, String) // after conversion of i to String by super class method + // Ditto for COWIS super.insert(offset, i); return this; } /**
*** 556,565 **** --- 608,618 ---- */ @Override public StringBuffer insert(int offset, long l) { // Note, synchronization achieved via invocation of StringBuffer insert(int, String) // after conversion of l to String by super class method + // Ditto for COWIS super.insert(offset, l); return this; } /**
*** 567,576 **** --- 620,630 ---- */ @Override public StringBuffer insert(int offset, float f) { // Note, synchronization achieved via invocation of StringBuffer insert(int, String) // after conversion of f to String by super class method + // Ditto for COWIS super.insert(offset, f); return this; } /**
*** 578,587 **** --- 632,642 ---- */ @Override public StringBuffer insert(int offset, double d) { // Note, synchronization achieved via invocation of StringBuffer insert(int, String) // after conversion of d to String by super class method + // Ditto for COWIS super.insert(offset, d); return this; } /**
*** 621,637 **** --- 676,694 ---- /** * @since JDK1.0.2 */ @Override public synchronized StringBuffer reverse() { + COWIS(); super.reverse(); return this; } @Override public synchronized String toString() { ! return new String(value, 0, count); ! isShared = true; + return new String(value, true); } /** * Serializable fields for StringBuffer. *
*** 670,676 **** --- 727,734 ---- private void readObject(java.io.ObjectInputStream s) throws java.io.IOException, ClassNotFoundException { java.io.ObjectInputStream.GetField fields = s.readFields(); value = (char[])fields.get("value", null); count = fields.get("count", 0); + isShared = false; } }

src/share/classes/java/lang/StringBuffer.java
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File