Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Re-enable toLowerCase/toUpperCase acceleration #2318

Merged
merged 2 commits into from
Jul 5, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
94 changes: 94 additions & 0 deletions jcl/src/java.base/share/classes/com/ibm/jit/JITHelpers.java
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,100 @@ public int getJ9ClassFromObject32(Object obj) {
}


/*
* To be recognized by the JIT and returns true if the hardware supports SIMD case conversion.
*/
public boolean supportsIntrinsicCaseConversion() {
return false;
}

/**
* To be used by the JIT when performing SIMD upper case conversion with Latin 1 strings.
* @param value the underlying array for the source string.
* @param output a new array which will be used for the converted string.
* @param length the number of bytes used to represent the string.
* @return True if intrinsic conversion was successful, false if fallback conversion must be used.
*/
public boolean toUpperIntrinsicLatin1(byte[] value, byte[] output, int length) {
return false;
}

/**
* To be used by the JIT when performing SIMD lower case conversion with Latin 1 strings.
* @param value the underlying array for the source string.
* @param output a new array which will be used for the converted string.
* @param length the number of bytes used to represent the string.
* @return True if intrinsic conversion was successful, false if fallback conversion must be used.
*/
public boolean toLowerIntrinsicLatin1(byte[] value, byte[] output, int length) {
return false;
}

/**
* To be used by the JIT when performing SIMD upper case conversion with UTF16 strings.
* @param value the underlying array for the source string.
* @param output a new array which will be used for the converted string.
* @param length the number of bytes used to represent the string.
* @return True if intrinsic conversion was successful, false if fallback conversion must be used.
*/
public boolean toUpperIntrinsicUTF16(byte[] value, byte[] output, int length) {
return false;
}

/**
* To be used by the JIT when performing SIMD lower case conversion with UTF16 strings.
* @param value the underlying array for the source string.
* @param output a new array which will be used for the converted string.
* @param length the number of bytes used to represent the string.
* @return True if intrinsic conversion was successful, false if fallback conversion must be used.
*/
public boolean toLowerIntrinsicUTF16(byte[] value, byte[] output, int length) {
return false;
}
/**
* To be used by the JIT when performing SIMD upper case conversion with Latin 1 strings.
* @param value the underlying array for the source string.
* @param output a new array which will be used for the converted string.
* @param length the number of bytes used to represent the string.
* @return True if intrinsic conversion was successful, false if fallback conversion must be used.
*/
public boolean toUpperIntrinsicLatin1(char[] value, char[] output, int length) {
return false;
}

/**
* To be used by the JIT when performing SIMD lower case conversion with Latin 1 strings.
* @param value the underlying array for the source string.
* @param output a new array which will be used for the converted string.
* @param length the number of bytes used to represent the string.
* @return True if intrinsic conversion was successful, false if fallback conversion must be used.
*/
public boolean toLowerIntrinsicLatin1(char[] value, char[] output, int length) {
return false;
}

/**
* To be used by the JIT when performing SIMD upper case conversion with UTF16 strings.
* @param value the underlying array for the source string.
* @param output a new array which will be used for the converted string.
* @param length the number of bytes used to represent the string.
* @return True if intrinsic conversion was successful, false if fallback conversion must be used.
*/
public boolean toUpperIntrinsicUTF16(char[] value, char[] output, int length) {
return false;
}

/**
* To be used by the JIT when performing SIMD lower case conversion with UTF16 strings.
* @param value the underlying array for the source string.
* @param output a new array which will be used for the converted string.
* @param length the number of bytes used to represent the string.
* @return True if intrinsic conversion was successful, false if fallback conversion must be used.
*/
public boolean toLowerIntrinsicUTF16(char[] value, char[] output, int length) {
return false;
}

/*
* sun.misc.Unsafe.get* and put* have to generate internal control flow for correctness due to different object shapes. The JIT emitted sequences
* checks for and handles: 1) standard fields in normal objects 2) static fields from classes 3) entries from arrays This sequence is branchy and
Expand Down
161 changes: 60 additions & 101 deletions jcl/src/java.base/share/classes/java/lang/String.java
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,6 @@ private void checkLastChar(char lastChar) {
/*[IF Sidecar19-SE]*/
// DO NOT CHANGE OR MOVE THIS LINE
// IT MUST BE THE FIRST THING IN THE INITIALIZATION
private static final boolean STRING_OPT_IN_HW = StrCheckHWAvailable();
private static final long serialVersionUID = -6849794470754667710L;

/**
Expand Down Expand Up @@ -878,17 +877,6 @@ public String(String string) {
hashCode = string.hashCode;
}

/**
* Creates a new string from the with specified length
*
* @param numChars
* length of new string
*/
private String(int numChars) {
value = new byte[numChars * 2];
coder = UTF16;
}

/**
* Creates a string from the contents of a StringBuffer.
*
Expand Down Expand Up @@ -2709,15 +2697,26 @@ public String toLowerCase(Locale locale) {
return this;
}

if (StrHWAvailable() && language == "en") { //$NON-NLS-1$
String output = new String(lengthInternal());
if (toLowerHWOptimized(output))
return output;
}
int sLength = lengthInternal();

if (enableCompression && (null == compressionFlag || coder == LATIN1)) {

if (helpers.supportsIntrinsicCaseConversion() && language == "en") { //$NON-NLS-1$
byte[] output = new byte[sLength << coder];

if (helpers.toLowerIntrinsicLatin1(value, output, sLength)) {
return new String(output, LATIN1);
}
}
return StringLatin1.toLowerCase(this, value, locale);
} else {
if (helpers.supportsIntrinsicCaseConversion() && language == "en") { //$NON-NLS-1$
byte[] output = new byte[sLength << coder];

if (helpers.toLowerIntrinsicUTF16(value, output, sLength * 2)) {
return new String(output, UTF16);
}
}
return StringUTF16.toLowerCase(this, value, locale);
}
}
Expand Down Expand Up @@ -2755,15 +2754,26 @@ public String toUpperCase(Locale locale) {
return this;
}

if (StrHWAvailable() && language == "en") { //$NON-NLS-1$
String output = new String(lengthInternal());
if (toUpperHWOptimized(output))
return output;
}
int sLength = lengthInternal();

if (enableCompression && (null == compressionFlag || coder == LATIN1)) {

if (helpers.supportsIntrinsicCaseConversion() && language == "en") { //$NON-NLS-1$
byte[] output = new byte[sLength << coder];

if (helpers.toUpperIntrinsicLatin1(value, output, sLength)) {
return new String(output, LATIN1);
}
}
return StringLatin1.toUpperCase(this, value, locale);
} else {
if (helpers.supportsIntrinsicCaseConversion() && language == "en") { //$NON-NLS-1$
byte[] output = new byte[sLength << coder];

if (helpers.toUpperIntrinsicUTF16(value, output, sLength * 2)) {
return new String(output, UTF16);
}
}
return StringUTF16.toUpperCase(this, value, locale);
}
}
Expand Down Expand Up @@ -3811,33 +3821,6 @@ public static String join(CharSequence delimiter, Iterable<? extends CharSequenc
return stringJoiner.toString();
}

// DO NOT MODIFY THIS METHOD
/*
* The method is only called once to setup the flag DFP_HW_AVAILABLE Return value true - when JIT compiled this method, replaces it with loadconst
* 1 if -Xjit:disableHWAcceleratedStringCaseConv hasn't been supplied false - if still interpreting this method or disabled by VM option
*/
private final static boolean StrCheckHWAvailable() {
return false;
}

// DO NOT MODIFY THIS METHOD
/*
* Return value true - when JIT compiled this method, replaces it with loadconst 1 if -Xjit:disableHWAcceleratedStringCaseConv hasn't been supplied
* false - if still interpreting this method or disabled by VM option
*/
private final static boolean StrHWAvailable() {
return STRING_OPT_IN_HW;
}

// DO NOT CHANGE CONTENTS OF THESE METHODS
private final boolean toUpperHWOptimized(String input) {
return false;
}

private final boolean toLowerHWOptimized(String input) {
return false;
}

static void checkBoundsBeginEnd(int begin, int end, int length) {
if ((begin >= 0) && (begin <= end) && (end <= length)) {
return;
Expand Down Expand Up @@ -3946,7 +3929,6 @@ public String repeat(int count) {
/*[ELSE] Sidecar19-SE*/
// DO NOT CHANGE OR MOVE THIS LINE
// IT MUST BE THE FIRST THING IN THE INITIALIZATION
private static final boolean STRING_OPT_IN_HW = StrCheckHWAvailable();
private static final long serialVersionUID = -6849794470754667710L;

/**
Expand Down Expand Up @@ -4728,22 +4710,6 @@ public String(String string) {
hashCode = string.hashCode;
}

/**
* Creates a new string from the with specified length
*
* @param numChars
* length of new string
*/
private String(int numChars) {
if (enableCompression) {
value = new char[numChars];
count = numChars | uncompressedBit;
} else {
value = new char[numChars];
count = numChars;
}
}

/**
* Creates a string from the contents of a StringBuffer.
*
Expand Down Expand Up @@ -6745,10 +6711,20 @@ public String toLowerCase(Locale locale) {
return this;
}

if (StrHWAvailable() && language == "en") { //$NON-NLS-1$
String output = new String(lengthInternal());
if (toLowerHWOptimized(output))
return output;
if (helpers.supportsIntrinsicCaseConversion() && language == "en") { //$NON-NLS-1$
int sLength = lengthInternal();

if (enableCompression && (null == compressionFlag || count >= 0)) {
char[] output = new char[(sLength + 1) / 2];
if (helpers.toLowerIntrinsicLatin1(value, output, sLength)) {
return new String(output, 0, sLength, true);
}
} else {
char[] output = new char[sLength];
if (helpers.toLowerIntrinsicUTF16(value, output, sLength * 2)) {
return new String(output, 0, sLength, false);
}
}
}

return toLowerCaseCore(language);
Expand Down Expand Up @@ -7070,10 +7046,20 @@ public String toUpperCase(Locale locale) {
return this;
}

if (StrHWAvailable() && language == "en") { //$NON-NLS-1$
String output = new String(lengthInternal());
if (toUpperHWOptimized(output))
return output;
if (helpers.supportsIntrinsicCaseConversion() && language == "en") { //$NON-NLS-1$
int sLength = lengthInternal();

if (enableCompression && (null == compressionFlag || count >= 0)) {
char[] output = new char[(sLength + 1) / 2];
if (helpers.toUpperIntrinsicLatin1(value, output, sLength)){
return new String(output, 0, sLength, true);
}
} else {
char[] output = new char[sLength];
if (helpers.toUpperIntrinsicUTF16(value, output, sLength * 2)){
return new String(output, 0, sLength, false);
}
}
}

return toUpperCaseCore(language);
Expand Down Expand Up @@ -8270,32 +8256,5 @@ public static String join(CharSequence delimiter, Iterable<? extends CharSequenc
return stringJoiner.toString();
}

// DO NOT MODIFY THIS METHOD
/*
* The method is only called once to setup the flag DFP_HW_AVAILABLE Return value true - when JIT compiled this method, replaces it with loadconst
* 1 if -Xjit:disableHWAcceleratedStringCaseConv hasn't been supplied false - if still interpreting this method or disabled by VM option
*/
private final static boolean StrCheckHWAvailable() {
return false;
}

// DO NOT MODIFY THIS METHOD
/*
* Return value true - when JIT compiled this method, replaces it with loadconst 1 if -Xjit:disableHWAcceleratedStringCaseConv hasn't been supplied
* false - if still interpreting this method or disabled by VM option
*/
private final static boolean StrHWAvailable() {
return STRING_OPT_IN_HW;
}

// DO NOT CHANGE CONTENTS OF THESE METHODS
private final boolean toUpperHWOptimized(String input) {
return false;
}

private final boolean toLowerHWOptimized(String input) {
return false;
}

/*[ENDIF] Sidecar19-SE*/
}
13 changes: 5 additions & 8 deletions runtime/compiler/codegen/J9RecognizedMethodsEnum.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1122,15 +1122,12 @@
com_ibm_gpu_Kernel_syncThreads,

// Vectorized toUpper and toLowerCase from j.l.String
// Current only supported on z
// toUpper method for prototype so j.l.S.toUpper doesn't get messed up
java_lang_String_StrHWAvailable,
java_lang_String_toUpperHWOptimizedCompressed,
java_lang_String_toUpperHWOptimizedDecompressed,
java_lang_String_toUpperHWOptimized,
java_lang_String_toLowerHWOptimizedCompressed,
java_lang_String_toLowerHWOptimizedDecompressed,
java_lang_String_toLowerHWOptimized,
com_ibm_jit_JITHelpers_supportsIntrinsicCaseConversion,
com_ibm_jit_JITHelpers_toUpperIntrinsicLatin1,
com_ibm_jit_JITHelpers_toUpperIntrinsicUTF16,
com_ibm_jit_JITHelpers_toLowerIntrinsicLatin1,
com_ibm_jit_JITHelpers_toLowerIntrinsicUTF16,

// SIMD intrinsics built-in methods
com_ibm_simd_VectorBase_vectorHWAvailable,
Expand Down
4 changes: 0 additions & 4 deletions runtime/compiler/control/J9Options.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1922,10 +1922,6 @@ J9::Options::fePreProcess(void * base)
self()->setMaxOnsiteCacheSlotForInstanceOf(4);
#endif

// TODO: Disable string case conversion acceleration temporarily as the code generators need to be updated to
// support the new String object layout
self()->setOption(TR_DisableSIMDStringCaseConv);

// Process the deterministic mode
if (TR::Options::_deterministicMode == -1) // not yet set
{
Expand Down
Loading