Skip to content

Commit

Permalink
Merge pull request #2098 from dhong44/caseConversion
Browse files Browse the repository at this point in the history
WIP: Re-enable toLowerCase/toUpperCase acceleration
  • Loading branch information
fjeremic authored Jul 4, 2018
2 parents 15b1bd9 + 635a9ad commit 15e283c
Show file tree
Hide file tree
Showing 18 changed files with 685 additions and 647 deletions.
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

0 comments on commit 15e283c

Please sign in to comment.