From 6556a83739aee8cef20c5cae55bf4b7d8cd873ee Mon Sep 17 00:00:00 2001 From: Jaikiran Pai Date: Mon, 3 Feb 2025 21:26:24 +0530 Subject: [PATCH 1/2] Revert "8343650: Reuse StringLatin1::putCharsAt and StringUTF16::putCharsAt" This reverts commit 74ae3c688b37e693e20eb4e17c631897c5464400. --- .../classes/java/lang/StringConcatHelper.java | 44 +++++++++++++++---- 1 file changed, 36 insertions(+), 8 deletions(-) diff --git a/src/java.base/share/classes/java/lang/StringConcatHelper.java b/src/java.base/share/classes/java/lang/StringConcatHelper.java index 632fe0f58b58b..13ada0637bae1 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 @@ static long prepend(long indexCoder, byte[] buf, boolean value, String prefix) { 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 @@ static long prepend(long indexCoder, byte[] buf, boolean value, String prefix) { } 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 @@ static int prepend(int index, byte coder, byte[] buf, boolean value, String pref 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); From 23d01f0a20dba70484fe10a42c833432ed7f13f3 Mon Sep 17 00:00:00 2001 From: Jaikiran Pai Date: Mon, 3 Feb 2025 21:27:14 +0530 Subject: [PATCH 2/2] Revert "8333893: Optimization for StringBuilder append boolean & null" This reverts commit 5890d9438bbde88b89070052926a2eafe13d7b42. --- .../java/lang/AbstractStringBuilder.java | 26 ++++--- .../share/classes/java/lang/StringLatin1.java | 24 ------- .../share/classes/java/lang/StringUTF16.java | 36 ++++++---- .../patches/java.base/java/lang/Helper.java | 12 +--- .../bench/java/lang/StringBuilders.java | 71 +++---------------- 5 files changed, 54 insertions(+), 115 deletions(-) diff --git a/src/java.base/share/classes/java/lang/AbstractStringBuilder.java b/src/java.base/share/classes/java/lang/AbstractStringBuilder.java index fd9dcf60e540e..94c4192ff5ef7 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 @@ private AbstractStringBuilder appendNull() { 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 @@ public AbstractStringBuilder append(boolean b) { 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/StringLatin1.java b/src/java.base/share/classes/java/lang/StringLatin1.java index 264664e20e9b2..5303eefc25c0b 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.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.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 @@ static Stream lines(byte[] value) { 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 a1dcca8ffad18..99226ac1012ba 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.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 @@ public static boolean contentEquals(byte[] value, CharSequence cs, int len) { 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); - } - - 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) { + 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; + } + + 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 a60354ec2fce2..540c0774fd01b 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 static boolean contentEquals(byte[] value, CharSequence cs, int len) { } 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 f857a77d80e66..4ef60d88fbf18 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 int appendWithLongUtf16() { } @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(); }