mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-27 23:04:50 +02:00
8289908: Skip bounds check for cases when String is constructed from entirely used byte[]
Reviewed-by: prr, rriggs, aturbanov
This commit is contained in:
parent
b2010a7481
commit
efed7a7f65
5 changed files with 96 additions and 13 deletions
|
@ -484,7 +484,7 @@ public final class String
|
||||||
*/
|
*/
|
||||||
public String(byte[] bytes, int offset, int length, String charsetName)
|
public String(byte[] bytes, int offset, int length, String charsetName)
|
||||||
throws UnsupportedEncodingException {
|
throws UnsupportedEncodingException {
|
||||||
this(bytes, offset, length, lookupCharset(charsetName));
|
this(lookupCharset(charsetName), bytes, checkBoundsOffCount(offset, length, bytes.length), length);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -517,10 +517,18 @@ public final class String
|
||||||
*
|
*
|
||||||
* @since 1.6
|
* @since 1.6
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("removal")
|
|
||||||
public String(byte[] bytes, int offset, int length, Charset charset) {
|
public String(byte[] bytes, int offset, int length, Charset charset) {
|
||||||
Objects.requireNonNull(charset);
|
this(Objects.requireNonNull(charset), bytes, checkBoundsOffCount(offset, length, bytes.length), length);
|
||||||
checkBoundsOffCount(offset, length, bytes.length);
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method does not do any precondition checks on its arguments.
|
||||||
|
* <p>
|
||||||
|
* Important: parameter order of this method is deliberately changed in order to
|
||||||
|
* disambiguate it against other similar methods of this class.
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("removal")
|
||||||
|
private String(Charset charset, byte[] bytes, int offset, int length) {
|
||||||
if (length == 0) {
|
if (length == 0) {
|
||||||
this.value = "".value;
|
this.value = "".value;
|
||||||
this.coder = "".coder;
|
this.coder = "".coder;
|
||||||
|
@ -1370,7 +1378,7 @@ public final class String
|
||||||
*/
|
*/
|
||||||
public String(byte[] bytes, String charsetName)
|
public String(byte[] bytes, String charsetName)
|
||||||
throws UnsupportedEncodingException {
|
throws UnsupportedEncodingException {
|
||||||
this(bytes, 0, bytes.length, charsetName);
|
this(lookupCharset(charsetName), bytes, 0, bytes.length);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1394,7 +1402,7 @@ public final class String
|
||||||
* @since 1.6
|
* @since 1.6
|
||||||
*/
|
*/
|
||||||
public String(byte[] bytes, Charset charset) {
|
public String(byte[] bytes, Charset charset) {
|
||||||
this(bytes, 0, bytes.length, charset);
|
this(Objects.requireNonNull(charset), bytes, 0, bytes.length);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1424,7 +1432,7 @@ public final class String
|
||||||
* @since 1.1
|
* @since 1.1
|
||||||
*/
|
*/
|
||||||
public String(byte[] bytes, int offset, int length) {
|
public String(byte[] bytes, int offset, int length) {
|
||||||
this(bytes, offset, length, Charset.defaultCharset());
|
this(Charset.defaultCharset(), bytes, checkBoundsOffCount(offset, length, bytes.length), length);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1444,7 +1452,7 @@ public final class String
|
||||||
* @since 1.1
|
* @since 1.1
|
||||||
*/
|
*/
|
||||||
public String(byte[] bytes) {
|
public String(byte[] bytes) {
|
||||||
this(bytes, 0, bytes.length);
|
this(Charset.defaultCharset(), bytes, 0, bytes.length);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -4582,12 +4590,13 @@ public final class String
|
||||||
* Check {@code offset}, {@code count} against {@code 0} and {@code length}
|
* Check {@code offset}, {@code count} against {@code 0} and {@code length}
|
||||||
* bounds.
|
* bounds.
|
||||||
*
|
*
|
||||||
|
* @return {@code offset} if the sub-range within bounds of the range
|
||||||
* @throws StringIndexOutOfBoundsException
|
* @throws StringIndexOutOfBoundsException
|
||||||
* If {@code offset} is negative, {@code count} is negative,
|
* If {@code offset} is negative, {@code count} is negative,
|
||||||
* or {@code offset} is greater than {@code length - count}
|
* or {@code offset} is greater than {@code length - count}
|
||||||
*/
|
*/
|
||||||
static void checkBoundsOffCount(int offset, int count, int length) {
|
static int checkBoundsOffCount(int offset, int count, int length) {
|
||||||
Preconditions.checkFromIndexSize(offset, count, length, Preconditions.SIOOBE_FORMATTER);
|
return Preconditions.checkFromIndexSize(offset, count, length, Preconditions.SIOOBE_FORMATTER);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -336,7 +336,7 @@ public class Manifest implements Cloneable {
|
||||||
lastline = buf;
|
lastline = buf;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
name = new String(buf, 0, buf.length, UTF_8.INSTANCE);
|
name = new String(buf, UTF_8.INSTANCE);
|
||||||
lastline = null;
|
lastline = null;
|
||||||
}
|
}
|
||||||
Attributes attr = getAttributes(name);
|
Attributes attr = getAttributes(name);
|
||||||
|
|
|
@ -114,7 +114,7 @@ class Entity implements DTDConstants {
|
||||||
* @return the data as a <code>String</code>
|
* @return the data as a <code>String</code>
|
||||||
*/
|
*/
|
||||||
public String getString() {
|
public String getString() {
|
||||||
return new String(data, 0, data.length);
|
return new String(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -241,7 +241,7 @@ final class WDataTransferer extends DataTransferer {
|
||||||
if (bytes == null || !DataFlavor.javaFileListFlavor.equals(flavor)) {
|
if (bytes == null || !DataFlavor.javaFileListFlavor.equals(flavor)) {
|
||||||
throw new IOException("data translation failed");
|
throw new IOException("data translation failed");
|
||||||
}
|
}
|
||||||
String st = new String(bytes, 0, bytes.length, UTF_16LE);
|
String st = new String(bytes, UTF_16LE);
|
||||||
String[] filenames = st.split("\0");
|
String[] filenames = st.split("\0");
|
||||||
if( 0 == filenames.length ){
|
if( 0 == filenames.length ){
|
||||||
return null;
|
return null;
|
||||||
|
|
|
@ -0,0 +1,74 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2018, 2022, 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.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||||
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
|
* questions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package micro.org.openjdk.bench.java.lang;
|
||||||
|
|
||||||
|
import org.openjdk.jmh.annotations.*;
|
||||||
|
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
@Fork(5)
|
||||||
|
@State(Scope.Thread)
|
||||||
|
@BenchmarkMode(Mode.AverageTime)
|
||||||
|
@OutputTimeUnit(TimeUnit.NANOSECONDS)
|
||||||
|
@Warmup(iterations = 5, time = 5)
|
||||||
|
@Measurement(iterations = 10, time = 5)
|
||||||
|
public class StringConstructor {
|
||||||
|
private byte[] array;
|
||||||
|
|
||||||
|
@Setup
|
||||||
|
public void setup() {
|
||||||
|
array = "".getBytes(StandardCharsets.UTF_8);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public String newStringFromArray() {
|
||||||
|
return new String(array);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public String newStringFromArrayWithCharset() {
|
||||||
|
return new String(array, StandardCharsets.UTF_8);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public String newStringFromArrayWithCharsetName() throws Exception {
|
||||||
|
return new String(array, StandardCharsets.UTF_8.name());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public String newStringFromRangedArray() {
|
||||||
|
return new String(array, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public String newStringFromRangedArrayWithCharset() {
|
||||||
|
return new String(array, 0, 0, StandardCharsets.UTF_8);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Benchmark
|
||||||
|
public String newStringFromRangedArrayWithCharsetName() throws Exception {
|
||||||
|
return new String(array, 0, 0, StandardCharsets.UTF_8.name());
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue