mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-27 06:45:07 +02:00
8221430: StringBuffer(CharSequence) constructor truncates when -XX:-CompactStrings specified
Co-authored-by: Andrew Leonard <andrew_m_leonard@uk.ibm.com> Reviewed-by: igerasim, rriggs
This commit is contained in:
parent
758f02e6cc
commit
eebe346715
5 changed files with 83 additions and 19 deletions
|
@ -92,19 +92,57 @@ abstract class AbstractStringBuilder implements Appendable, CharSequence {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates an AbstractStringBuilder with the specified coder and with
|
* Constructs an AbstractStringBuilder that contains the same characters
|
||||||
* the initial capacity equal to the smaller of (length + addition)
|
* as the specified {@code String}. The initial capacity of
|
||||||
* and Integer.MAX_VALUE.
|
* the string builder is {@code 16} plus the length of the
|
||||||
|
* {@code String} argument.
|
||||||
|
*
|
||||||
|
* @param str the string to copy.
|
||||||
*/
|
*/
|
||||||
AbstractStringBuilder(byte coder, int length, int addition) {
|
AbstractStringBuilder(String str) {
|
||||||
|
int length = str.length();
|
||||||
|
int capacity = (length < Integer.MAX_VALUE - 16)
|
||||||
|
? length + 16 : Integer.MAX_VALUE;
|
||||||
|
final byte initCoder = str.coder();
|
||||||
|
coder = initCoder;
|
||||||
|
value = (initCoder == LATIN1)
|
||||||
|
? new byte[capacity] : StringUTF16.newBytesFor(capacity);
|
||||||
|
append(str);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs an AbstractStringBuilder that contains the same characters
|
||||||
|
* as the specified {@code CharSequence}. The initial capacity of
|
||||||
|
* the string builder is {@code 16} plus the length of the
|
||||||
|
* {@code CharSequence} argument.
|
||||||
|
*
|
||||||
|
* @param seq the sequence to copy.
|
||||||
|
*/
|
||||||
|
AbstractStringBuilder(CharSequence seq) {
|
||||||
|
int length = seq.length();
|
||||||
if (length < 0) {
|
if (length < 0) {
|
||||||
throw new NegativeArraySizeException("Negative length: " + length);
|
throw new NegativeArraySizeException("Negative length: " + length);
|
||||||
}
|
}
|
||||||
this.coder = coder;
|
int capacity = (length < Integer.MAX_VALUE - 16)
|
||||||
int capacity = (length < Integer.MAX_VALUE - addition)
|
? length + 16 : Integer.MAX_VALUE;
|
||||||
? length + addition : Integer.MAX_VALUE;
|
|
||||||
value = (coder == LATIN1)
|
final byte initCoder;
|
||||||
|
if (COMPACT_STRINGS) {
|
||||||
|
if (seq instanceof AbstractStringBuilder) {
|
||||||
|
initCoder = ((AbstractStringBuilder)seq).getCoder();
|
||||||
|
} else if (seq instanceof String) {
|
||||||
|
initCoder = ((String)seq).coder();
|
||||||
|
} else {
|
||||||
|
initCoder = LATIN1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
initCoder = UTF16;
|
||||||
|
}
|
||||||
|
|
||||||
|
coder = initCoder;
|
||||||
|
value = (initCoder == LATIN1)
|
||||||
? new byte[capacity] : StringUTF16.newBytesFor(capacity);
|
? new byte[capacity] : StringUTF16.newBytesFor(capacity);
|
||||||
|
append(seq);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -148,8 +148,7 @@ import jdk.internal.HotSpotIntrinsicCandidate;
|
||||||
*/
|
*/
|
||||||
@HotSpotIntrinsicCandidate
|
@HotSpotIntrinsicCandidate
|
||||||
public StringBuffer(String str) {
|
public StringBuffer(String str) {
|
||||||
super(str.coder(), str.length(), 16);
|
super(str);
|
||||||
append(str);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -162,8 +161,7 @@ import jdk.internal.HotSpotIntrinsicCandidate;
|
||||||
* @since 1.5
|
* @since 1.5
|
||||||
*/
|
*/
|
||||||
public StringBuffer(CharSequence seq) {
|
public StringBuffer(CharSequence seq) {
|
||||||
super(String.LATIN1, seq.length(), 16);
|
super(seq);
|
||||||
append(seq);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -121,8 +121,7 @@ public final class StringBuilder
|
||||||
*/
|
*/
|
||||||
@HotSpotIntrinsicCandidate
|
@HotSpotIntrinsicCandidate
|
||||||
public StringBuilder(String str) {
|
public StringBuilder(String str) {
|
||||||
super(str.coder(), str.length(), 16);
|
super(str);
|
||||||
append(str);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -134,8 +133,7 @@ public final class StringBuilder
|
||||||
* @param seq the sequence to copy.
|
* @param seq the sequence to copy.
|
||||||
*/
|
*/
|
||||||
public StringBuilder(CharSequence seq) {
|
public StringBuilder(CharSequence seq) {
|
||||||
super(String.LATIN1, seq.length(), 16);
|
super(seq);
|
||||||
append(seq);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -30,7 +30,7 @@ import static org.testng.Assert.assertTrue;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @test
|
* @test
|
||||||
* @bug 8077559
|
* @bug 8077559 8221430
|
||||||
* @summary Tests Compact String. This test is testing StringBuffer
|
* @summary Tests Compact String. This test is testing StringBuffer
|
||||||
* behavior related to Compact String.
|
* behavior related to Compact String.
|
||||||
* @run testng/othervm -XX:+CompactStrings CompactStringBuffer
|
* @run testng/othervm -XX:+CompactStrings CompactStringBuffer
|
||||||
|
@ -440,6 +440,12 @@ public class CompactStringBuffer {
|
||||||
"abcdefgh1.23456");
|
"abcdefgh1.23456");
|
||||||
check(new StringBuffer().append(bmp).append(1.23456).toString(),
|
check(new StringBuffer().append(bmp).append(1.23456).toString(),
|
||||||
"\u4e00\u4e01\u4e02\u4e03\u4e04\u4e05\u4e06\u4e07\u4e081.23456");
|
"\u4e00\u4e01\u4e02\u4e03\u4e04\u4e05\u4e06\u4e07\u4e081.23456");
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
check(new StringBuffer((CharSequence)new StringBuffer(ascii)).toString(),
|
||||||
|
ascii);
|
||||||
|
check(new StringBuffer((CharSequence)new StringBuffer(asciiMixed)).toString(),
|
||||||
|
asciiMixed);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkGetChars(StringBuffer sb, int srcBegin, int srcEnd,
|
private void checkGetChars(StringBuffer sb, int srcBegin, int srcEnd,
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
@ -42,6 +42,8 @@ public class StringBuilders {
|
||||||
private String[] str16p8p7;
|
private String[] str16p8p7;
|
||||||
private String[] str3p9p8;
|
private String[] str3p9p8;
|
||||||
private String[] str22p40p31;
|
private String[] str22p40p31;
|
||||||
|
private StringBuilder sbLatin1;
|
||||||
|
private StringBuilder sbUtf16;
|
||||||
|
|
||||||
@Setup
|
@Setup
|
||||||
public void setup() {
|
public void setup() {
|
||||||
|
@ -53,6 +55,8 @@ public class StringBuilders {
|
||||||
str16p8p7 = new String[]{"1234567890123456", "12345678", "1234567"};
|
str16p8p7 = new String[]{"1234567890123456", "12345678", "1234567"};
|
||||||
str3p9p8 = new String[]{"123", "123456789", "12345678"};
|
str3p9p8 = new String[]{"123", "123456789", "12345678"};
|
||||||
str22p40p31 = new String[]{"1234567890123456789012", "1234567890123456789012345678901234567890", "1234567890123456789012345678901"};
|
str22p40p31 = new String[]{"1234567890123456789012", "1234567890123456789012345678901234567890", "1234567890123456789012345678901"};
|
||||||
|
sbLatin1 = new StringBuilder("Latin1 string");
|
||||||
|
sbUtf16 = new StringBuilder("UTF-\uFF11\uFF16 string");
|
||||||
}
|
}
|
||||||
|
|
||||||
/** StringBuilder wins over StringMaker. */
|
/** StringBuilder wins over StringMaker. */
|
||||||
|
@ -256,4 +260,24 @@ public class StringBuilders {
|
||||||
result.append("stringelinglinglinglong");
|
result.append("stringelinglinglinglong");
|
||||||
return result.toString();
|
return result.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public StringBuilder fromLatin1String() {
|
||||||
|
return new StringBuilder("Latin1 string");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public StringBuilder fromUtf16String() {
|
||||||
|
return new StringBuilder("UTF-\uFF11\uFF16 string");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public StringBuilder fromLatin1StringBuilder() {
|
||||||
|
return new StringBuilder(sbLatin1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public StringBuilder fromUtf16StringBuilder() {
|
||||||
|
return new StringBuilder(sbUtf16);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue