PlatformDependent String char[] optimization
Motivation: PlatformDependent0 has an optimization which grabs the char[] from a String. Since this code was introduced http://openjdk.java.net/jeps/254 has been gaining momentum in JDK 9. This JEP changes the internal storage from char[] to byte[], and thus the existing char[] only based optimizations will not work. Modifications: - The ASCII encoding char[] String optimizations should also work for byte[]. Result: ASCII encoding char[] String optimizations don't break if the underlying storage in String is byte[].
This commit is contained in:
parent
d4a1665941
commit
ca305d86fb
@ -541,12 +541,14 @@ public final class PlatformDependent {
|
||||
* The resulting hash code will be case insensitive.
|
||||
*/
|
||||
public static int hashCodeAscii(CharSequence bytes) {
|
||||
char[] array;
|
||||
if (!hasUnsafe() || !PlatformDependent0.unalignedAccess() ||
|
||||
(array = PlatformDependent0.array(bytes)) == null) {
|
||||
if (!hasUnsafe() || !PlatformDependent0.unalignedAccess()) {
|
||||
return hashCodeAsciiSafe(bytes);
|
||||
} else if (PlatformDependent0.hasCharArray(bytes)) {
|
||||
return PlatformDependent0.hashCodeAscii(PlatformDependent0.charArray(bytes));
|
||||
} else if (PlatformDependent0.hasByteArray(bytes)) {
|
||||
return PlatformDependent0.hashCodeAscii(PlatformDependent0.byteArray(bytes));
|
||||
}
|
||||
return PlatformDependent0.hashCodeAscii(array);
|
||||
return hashCodeAsciiSafe(bytes);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -42,7 +42,8 @@ final class PlatformDependent0 {
|
||||
private static final long BYTE_ARRAY_BASE_OFFSET;
|
||||
private static final long CHAR_ARRAY_BASE_OFFSET;
|
||||
private static final long CHAR_ARRAY_INDEX_SCALE;
|
||||
private static final long STRING_VALUE_FIELD_OFFSET;
|
||||
private static final long STRING_CHAR_VALUE_FIELD_OFFSET;
|
||||
private static final long STRING_BYTE_VALUE_FIELD_OFFSET;
|
||||
static final int HASH_CODE_ASCII_SEED = 0xc2b2ae35; // constant borrowed from murmur3
|
||||
|
||||
/**
|
||||
@ -114,7 +115,7 @@ final class PlatformDependent0 {
|
||||
ADDRESS_FIELD_OFFSET = -1;
|
||||
BYTE_ARRAY_BASE_OFFSET = CHAR_ARRAY_BASE_OFFSET = CHAR_ARRAY_INDEX_SCALE = -1;
|
||||
UNALIGNED = false;
|
||||
STRING_VALUE_FIELD_OFFSET = -1;
|
||||
STRING_CHAR_VALUE_FIELD_OFFSET = STRING_BYTE_VALUE_FIELD_OFFSET = -1;
|
||||
} else {
|
||||
ADDRESS_FIELD_OFFSET = objectFieldOffset(addressField);
|
||||
BYTE_ARRAY_BASE_OFFSET = UNSAFE.arrayBaseOffset(byte[].class);
|
||||
@ -159,8 +160,24 @@ final class PlatformDependent0 {
|
||||
logger.debug("AccessController.doPrivileged failed to get String value array." +
|
||||
"String hash code optimizations are disabled.", t);
|
||||
}
|
||||
STRING_VALUE_FIELD_OFFSET = stringValueField == null ?
|
||||
-1 : UNSAFE.objectFieldOffset(stringValueField);
|
||||
|
||||
if (stringValueField == null) {
|
||||
STRING_CHAR_VALUE_FIELD_OFFSET = STRING_BYTE_VALUE_FIELD_OFFSET = -1;
|
||||
} else {
|
||||
long stringValueFieldOffset = UNSAFE.objectFieldOffset(stringValueField);
|
||||
Object o = UNSAFE.getObject("", stringValueFieldOffset);
|
||||
if (char[].class.isInstance(o)) {
|
||||
STRING_CHAR_VALUE_FIELD_OFFSET = stringValueFieldOffset;
|
||||
STRING_BYTE_VALUE_FIELD_OFFSET = -1;
|
||||
} else if (byte[].class.isInstance(o)) {
|
||||
STRING_CHAR_VALUE_FIELD_OFFSET = -1;
|
||||
STRING_BYTE_VALUE_FIELD_OFFSET = stringValueFieldOffset;
|
||||
} else {
|
||||
STRING_CHAR_VALUE_FIELD_OFFSET = STRING_BYTE_VALUE_FIELD_OFFSET = -1;
|
||||
logger.info("Unexpected type [" + o.getClass() + "] for String value array." +
|
||||
"String hash code optimizations are disabled.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -343,6 +360,10 @@ final class PlatformDependent0 {
|
||||
}
|
||||
}
|
||||
|
||||
static int hashCodeAscii(byte[] bytes) {
|
||||
return hashCodeAscii(bytes, 0, bytes.length);
|
||||
}
|
||||
|
||||
/**
|
||||
* This must remain consistent with {@link #hashCodeAscii(char[])}.
|
||||
*/
|
||||
@ -433,9 +454,26 @@ final class PlatformDependent0 {
|
||||
}
|
||||
}
|
||||
|
||||
static char[] array(CharSequence data) {
|
||||
return (STRING_VALUE_FIELD_OFFSET != -1 && data.getClass() == String.class) ?
|
||||
(char[]) UNSAFE.getObject(data, STRING_VALUE_FIELD_OFFSET) : null;
|
||||
static boolean hasCharArray(CharSequence data) {
|
||||
return STRING_CHAR_VALUE_FIELD_OFFSET != -1 && data.getClass() == String.class;
|
||||
}
|
||||
|
||||
static boolean hasByteArray(CharSequence data) {
|
||||
return STRING_BYTE_VALUE_FIELD_OFFSET != -1 && data.getClass() == String.class;
|
||||
}
|
||||
|
||||
/**
|
||||
* Callers are expected to call {@link #hasCharArray(CharSequence)} before calling this method.
|
||||
*/
|
||||
static char[] charArray(CharSequence data) {
|
||||
return (char[]) UNSAFE.getObject(data, STRING_CHAR_VALUE_FIELD_OFFSET);
|
||||
}
|
||||
|
||||
/**
|
||||
* Callers are expected to call {@link #hasByteArray(CharSequence)} before calling this method.
|
||||
*/
|
||||
static byte[] byteArray(CharSequence data) {
|
||||
return (byte[]) UNSAFE.getObject(data, STRING_BYTE_VALUE_FIELD_OFFSET);
|
||||
}
|
||||
|
||||
static int hashCodeAsciiCompute(long value, int hash) {
|
||||
|
Loading…
Reference in New Issue
Block a user