Skip to content

Commit

Permalink
8299807: newStringNoRepl should avoid copying arrays for ASCII compat…
Browse files Browse the repository at this point in the history
…ible charsets

Reviewed-by: rriggs
  • Loading branch information
Glavo authored and Roger Riggs committed Mar 3, 2023
1 parent c6de66c commit 7449e1c
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 5 deletions.
19 changes: 15 additions & 4 deletions src/java.base/share/classes/java/lang/String.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 1994, 2022, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1994, 2023, 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
Expand Down Expand Up @@ -698,8 +698,13 @@ private String(Charset charset, byte[] bytes, int offset, int length) {

/*
* Throws iae, instead of replacing, if malformed or unmappable.
*
* @param noShare
* {@code true} if the resulting string MUST NOT share the byte array,
* {@code false} if the byte array can be exclusively used to construct
* the string and is not modified or used for any other purpose.
*/
static String newStringUTF8NoRepl(byte[] bytes, int offset, int length) {
static String newStringUTF8NoRepl(byte[] bytes, int offset, int length, boolean noShare) {
checkBoundsOffCount(offset, length, bytes.length);
if (length == 0) {
return "";
Expand All @@ -710,7 +715,11 @@ static String newStringUTF8NoRepl(byte[] bytes, int offset, int length) {
dp = StringCoding.countPositives(bytes, offset, length);
int sl = offset + length;
if (dp == length) {
return new String(Arrays.copyOfRange(bytes, offset, offset + length), LATIN1);
if (noShare || length != bytes.length) {
return new String(Arrays.copyOfRange(bytes, offset, offset + length), LATIN1);
} else {
return new String(bytes, LATIN1);
}
}
dst = new byte[length];
System.arraycopy(bytes, offset, dst, 0, dp);
Expand Down Expand Up @@ -778,7 +787,7 @@ private static String newStringNoRepl1(byte[] src, Charset cs) {
return "";
}
if (cs == UTF_8.INSTANCE) {
return newStringUTF8NoRepl(src, 0, src.length);
return newStringUTF8NoRepl(src, 0, src.length, false);
}
if (cs == ISO_8859_1.INSTANCE) {
if (COMPACT_STRINGS)
Expand All @@ -800,6 +809,8 @@ private static String newStringNoRepl1(byte[] src, Charset cs) {
if (cd instanceof ArrayDecoder ad &&
ad.isASCIICompatible() &&
!StringCoding.hasNegatives(src, 0, src.length)) {
if (COMPACT_STRINGS)
return new String(src, LATIN1);
return new String(src, 0, src.length, ISO_8859_1.INSTANCE);
}
int en = scale(len, cd.maxCharsPerByte());
Expand Down
2 changes: 1 addition & 1 deletion src/java.base/share/classes/java/lang/System.java
Original file line number Diff line number Diff line change
Expand Up @@ -2478,7 +2478,7 @@ public byte[] getBytesNoRepl(String s, Charset cs) throws CharacterCodingExcepti
}

public String newStringUTF8NoRepl(byte[] bytes, int off, int len) {
return String.newStringUTF8NoRepl(bytes, off, len);
return String.newStringUTF8NoRepl(bytes, off, len, true);
}

public byte[] getBytesUTF8NoRepl(String s) {
Expand Down

1 comment on commit 7449e1c

@openjdk-notifier
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.