diff --git a/src/java.base/share/classes/java/lang/AbstractStringBuilder.java b/src/java.base/share/classes/java/lang/AbstractStringBuilder.java index fd9dcf60e54..94c4192ff5e 100644 --- a/src/java.base/share/classes/java/lang/AbstractStringBuilder.java +++ b/src/java.base/share/classes/java/lang/AbstractStringBuilder.java @@ -640,11 +640,14 @@ abstract sealed class AbstractStringBuilder implements Appendable, CharSequence int count = this.count; byte[] val = this.value; if (isLatin1()) { - StringLatin1.putCharsAt(val, count, 'n', 'u', 'l', 'l'); + val[count++] = 'n'; + val[count++] = 'u'; + val[count++] = 'l'; + val[count++] = 'l'; } else { - StringUTF16.putCharsAt(val, count, 'n', 'u', 'l', 'l'); + count = StringUTF16.putCharsAt(val, count, 'n', 'u', 'l', 'l'); } - this.count = count + 4; + this.count = count; return this; } @@ -769,18 +772,25 @@ abstract sealed class AbstractStringBuilder implements Appendable, CharSequence byte[] val = this.value; if (isLatin1()) { if (b) { - StringLatin1.putCharsAt(val, count, 't', 'r', 'u', 'e'); + val[count++] = 't'; + val[count++] = 'r'; + val[count++] = 'u'; + val[count++] = 'e'; } else { - StringLatin1.putCharsAt(val, count, 'f', 'a', 'l', 's', 'e'); + val[count++] = 'f'; + val[count++] = 'a'; + val[count++] = 'l'; + val[count++] = 's'; + val[count++] = 'e'; } } else { if (b) { - StringUTF16.putCharsAt(val, count, 't', 'r', 'u', 'e'); + count = StringUTF16.putCharsAt(val, count, 't', 'r', 'u', 'e'); } else { - StringUTF16.putCharsAt(val, count, 'f', 'a', 'l', 's', 'e'); + count = StringUTF16.putCharsAt(val, count, 'f', 'a', 'l', 's', 'e'); } } - this.count = count + (b ? 4 : 5); + this.count = count; return this; } diff --git a/src/java.base/share/classes/java/lang/StringConcatHelper.java b/src/java.base/share/classes/java/lang/StringConcatHelper.java index 632fe0f58b5..13ada0637ba 100644 --- a/src/java.base/share/classes/java/lang/StringConcatHelper.java +++ b/src/java.base/share/classes/java/lang/StringConcatHelper.java @@ -236,10 +236,17 @@ final class StringConcatHelper { if (indexCoder < UTF16) { if (value) { index -= 4; - StringLatin1.putCharsAt(buf, index, 't', 'r', 'u', 'e'); + buf[index] = 't'; + buf[index + 1] = 'r'; + buf[index + 2] = 'u'; + buf[index + 3] = 'e'; } else { index -= 5; - StringLatin1.putCharsAt(buf, index, 'f', 'a', 'l', 's', 'e'); + buf[index] = 'f'; + buf[index + 1] = 'a'; + buf[index + 2] = 'l'; + buf[index + 3] = 's'; + buf[index + 4] = 'e'; } index -= prefix.length(); prefix.getBytes(buf, index, String.LATIN1); @@ -247,10 +254,17 @@ final class StringConcatHelper { } else { if (value) { index -= 4; - StringUTF16.putCharsAt(buf, index, 't', 'r', 'u', 'e'); + StringUTF16.putChar(buf, index, 't'); + StringUTF16.putChar(buf, index + 1, 'r'); + StringUTF16.putChar(buf, index + 2, 'u'); + StringUTF16.putChar(buf, index + 3, 'e'); } else { index -= 5; - StringUTF16.putCharsAt(buf, index, 'f', 'a', 'l', 's', 'e'); + StringUTF16.putChar(buf, index, 'f'); + StringUTF16.putChar(buf, index + 1, 'a'); + StringUTF16.putChar(buf, index + 2, 'l'); + StringUTF16.putChar(buf, index + 3, 's'); + StringUTF16.putChar(buf, index + 4, 'e'); } index -= prefix.length(); prefix.getBytes(buf, index, String.UTF16); @@ -624,20 +638,34 @@ final class StringConcatHelper { if (coder == String.LATIN1) { if (value) { index -= 4; - StringLatin1.putCharsAt(buf, index, 't', 'r', 'u', 'e'); + buf[index] = 't'; + buf[index + 1] = 'r'; + buf[index + 2] = 'u'; + buf[index + 3] = 'e'; } else { index -= 5; - StringLatin1.putCharsAt(buf, index, 'f', 'a', 'l', 's', 'e'); + buf[index] = 'f'; + buf[index + 1] = 'a'; + buf[index + 2] = 'l'; + buf[index + 3] = 's'; + buf[index + 4] = 'e'; } index -= prefix.length(); prefix.getBytes(buf, index, String.LATIN1); } else { if (value) { index -= 4; - StringUTF16.putCharsAt(buf, index, 't', 'r', 'u', 'e'); + StringUTF16.putChar(buf, index, 't'); + StringUTF16.putChar(buf, index + 1, 'r'); + StringUTF16.putChar(buf, index + 2, 'u'); + StringUTF16.putChar(buf, index + 3, 'e'); } else { index -= 5; - StringUTF16.putCharsAt(buf, index, 'f', 'a', 'l', 's', 'e'); + StringUTF16.putChar(buf, index, 'f'); + StringUTF16.putChar(buf, index + 1, 'a'); + StringUTF16.putChar(buf, index + 2, 'l'); + StringUTF16.putChar(buf, index + 3, 's'); + StringUTF16.putChar(buf, index + 4, 'e'); } index -= prefix.length(); prefix.getBytes(buf, index, String.UTF16); diff --git a/src/java.base/share/classes/java/lang/StringLatin1.java b/src/java.base/share/classes/java/lang/StringLatin1.java index 264664e20e9..5303eefc25c 100644 --- a/src/java.base/share/classes/java/lang/StringLatin1.java +++ b/src/java.base/share/classes/java/lang/StringLatin1.java @@ -32,7 +32,6 @@ import java.util.function.Consumer; import java.util.function.IntConsumer; import java.util.stream.Stream; import java.util.stream.StreamSupport; -import jdk.internal.misc.Unsafe; import jdk.internal.util.ArraysSupport; import jdk.internal.vm.annotation.IntrinsicCandidate; @@ -42,8 +41,6 @@ import static java.lang.String.checkIndex; import static java.lang.String.checkOffset; final class StringLatin1 { - private static final Unsafe UNSAFE = Unsafe.getUnsafe(); - public static char charAt(byte[] value, int index) { checkIndex(index, value.length); return (char)(value[index] & 0xff); @@ -712,27 +709,6 @@ final class StringLatin1 { return StreamSupport.stream(LinesSpliterator.spliterator(value), false); } - static void putCharsAt(byte[] val, int index, int c1, int c2, int c3, int c4) { - assert index >= 0 && index + 3 < length(val) : "Trusted caller missed bounds check"; - // Don't use the putChar method, Its instrinsic will cause C2 unable to combining values into larger stores. - long offset = Unsafe.ARRAY_BYTE_BASE_OFFSET + index; - UNSAFE.putByte(val, offset , (byte)(c1)); - UNSAFE.putByte(val, offset + 1, (byte)(c2)); - UNSAFE.putByte(val, offset + 2, (byte)(c3)); - UNSAFE.putByte(val, offset + 3, (byte)(c4)); - } - - static void putCharsAt(byte[] val, int index, int c1, int c2, int c3, int c4, int c5) { - assert index >= 0 && index + 4 < length(val) : "Trusted caller missed bounds check"; - // Don't use the putChar method, Its instrinsic will cause C2 unable to combining values into larger stores. - long offset = Unsafe.ARRAY_BYTE_BASE_OFFSET + index; - UNSAFE.putByte(val, offset , (byte)(c1)); - UNSAFE.putByte(val, offset + 1, (byte)(c2)); - UNSAFE.putByte(val, offset + 2, (byte)(c3)); - UNSAFE.putByte(val, offset + 3, (byte)(c4)); - UNSAFE.putByte(val, offset + 4, (byte)(c5)); - } - public static void putChar(byte[] val, int index, int c) { //assert (canEncode(c)); val[index] = (byte)(c); diff --git a/src/java.base/share/classes/java/lang/StringUTF16.java b/src/java.base/share/classes/java/lang/StringUTF16.java index a1dcca8ffad..99226ac1012 100644 --- a/src/java.base/share/classes/java/lang/StringUTF16.java +++ b/src/java.base/share/classes/java/lang/StringUTF16.java @@ -42,6 +42,7 @@ import static java.lang.String.UTF16; import static java.lang.String.LATIN1; final class StringUTF16 { + // Return a new byte array for a UTF16-coded string for len chars // Throw an exception if out of range public static byte[] newBytesFor(int len) { @@ -1532,20 +1533,27 @@ final class StringUTF16 { return true; } - static void putCharsAt(byte[] val, int index, int c1, int c2, int c3, int c4) { - assert index >= 0 && index + 3 < length(val) : "Trusted caller missed bounds check"; - putChar(val, index , c1); - putChar(val, index + 1, c2); - putChar(val, index + 2, c3); - putChar(val, index + 3, c4); + public static int putCharsAt(byte[] value, int i, char c1, char c2, char c3, char c4) { + int end = i + 4; + checkBoundsBeginEnd(i, end, value); + putChar(value, i++, c1); + putChar(value, i++, c2); + putChar(value, i++, c3); + putChar(value, i++, c4); + assert(i == end); + return end; } - static void putCharsAt(byte[] val, int index, int c1, int c2, int c3, int c4, int c5) { - putChar(val, index , c1); - putChar(val, index + 1, c2); - putChar(val, index + 2, c3); - putChar(val, index + 3, c4); - putChar(val, index + 4, c5); + public static int putCharsAt(byte[] value, int i, char c1, char c2, char c3, char c4, char c5) { + int end = i + 5; + checkBoundsBeginEnd(i, end, value); + putChar(value, i++, c1); + putChar(value, i++, c2); + putChar(value, i++, c3); + putChar(value, i++, c4); + putChar(value, i++, c5); + assert(i == end); + return end; } public static char charAt(byte[] value, int index) { diff --git a/test/hotspot/jtreg/compiler/patches/java.base/java/lang/Helper.java b/test/hotspot/jtreg/compiler/patches/java.base/java/lang/Helper.java index a60354ec2fc..540c0774fd0 100644 --- a/test/hotspot/jtreg/compiler/patches/java.base/java/lang/Helper.java +++ b/test/hotspot/jtreg/compiler/patches/java.base/java/lang/Helper.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2018, 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 @@ -141,17 +141,11 @@ public class Helper { } public static int putCharsAt(byte[] value, int i, char c1, char c2, char c3, char c4) { - int end = i + 4; - StringUTF16.checkBoundsBeginEnd(i, end, value); - StringUTF16.putCharsAt(value, i, c1, c2, c3, c4); - return end; + return StringUTF16.putCharsAt(value, i, c1, c2, c3, c4); } public static int putCharsAt(byte[] value, int i, char c1, char c2, char c3, char c4, char c5) { - int end = i + 5; - StringUTF16.checkBoundsBeginEnd(i, end, value); - StringUTF16.putCharsAt(value, i, c1, c2, c3, c4, c5); - return end; + return StringUTF16.putCharsAt(value, i, c1, c2, c3, c4, c5); } public static char charAt(byte[] value, int index) { diff --git a/test/micro/org/openjdk/bench/java/lang/StringBuilders.java b/test/micro/org/openjdk/bench/java/lang/StringBuilders.java index f857a77d80e..4ef60d88fbf 100644 --- a/test/micro/org/openjdk/bench/java/lang/StringBuilders.java +++ b/test/micro/org/openjdk/bench/java/lang/StringBuilders.java @@ -274,66 +274,17 @@ public class StringBuilders { } @Benchmark - public int appendWithBool8Latin1() { - StringBuilder buf = sbLatin1; - buf.setLength(0); - buf.append(true); - buf.append(false); - buf.append(true); - buf.append(true); - buf.append(false); - buf.append(true); - buf.append(false); - buf.append(false); - return buf.length(); - } - - - @Benchmark - public int appendWithBool8Utf16() { - StringBuilder buf = sbUtf16; - buf.setLength(0); - buf.append(true); - buf.append(false); - buf.append(true); - buf.append(true); - buf.append(false); - buf.append(true); - buf.append(false); - buf.append(false); - return buf.length(); - } - - - @Benchmark - public int appendWithNull8Latin1() { - StringBuilder buf = sbLatin1; - buf.setLength(0); - buf.append((String) null); - buf.append((String) null); - buf.append((String) null); - buf.append((String) null); - buf.append((String) null); - buf.append((String) null); - buf.append((String) null); - buf.append((String) null); - return buf.length(); - } - - - @Benchmark - public int appendWithNull8Utf16() { - StringBuilder buf = sbUtf16; - buf.setLength(0); - buf.append((String) null); - buf.append((String) null); - buf.append((String) null); - buf.append((String) null); - buf.append((String) null); - buf.append((String) null); - buf.append((String) null); - buf.append((String) null); - return buf.length(); + public String toStringCharWithBool8() { + StringBuilder result = new StringBuilder(); + result.append(true); + result.append(false); + result.append(true); + result.append(true); + result.append(false); + result.append(true); + result.append(false); + result.append(false); + return result.toString(); }