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