PlatformDependent0 should be able to better detect if unaligned access is supported on java9 and later. (#8255)
Motivation: In Java8 and earlier we used reflection to detect if unaligned access is supported. This fails in Java9 and later as we would need to change the accessible level of the method. Lucky enough we can use Unsafe directly to read the content of the static field here. Modifications: Add special handling for detecting if unaligned access is supported on Java9 and later which does not fail due jigsaw. Result: Better and more correct detection on Java9 and later.
This commit is contained in:
parent
dc1b511fcf
commit
ade60c11e1
@ -262,13 +262,32 @@ final class PlatformDependent0 {
|
|||||||
DIRECT_BUFFER_CONSTRUCTOR = directBufferConstructor;
|
DIRECT_BUFFER_CONSTRUCTOR = directBufferConstructor;
|
||||||
ADDRESS_FIELD_OFFSET = objectFieldOffset(addressField);
|
ADDRESS_FIELD_OFFSET = objectFieldOffset(addressField);
|
||||||
BYTE_ARRAY_BASE_OFFSET = UNSAFE.arrayBaseOffset(byte[].class);
|
BYTE_ARRAY_BASE_OFFSET = UNSAFE.arrayBaseOffset(byte[].class);
|
||||||
boolean unaligned;
|
final boolean unaligned;
|
||||||
Object maybeUnaligned = AccessController.doPrivileged(new PrivilegedAction<Object>() {
|
Object maybeUnaligned = AccessController.doPrivileged(new PrivilegedAction<Object>() {
|
||||||
@Override
|
@Override
|
||||||
public Object run() {
|
public Object run() {
|
||||||
try {
|
try {
|
||||||
Class<?> bitsClass =
|
Class<?> bitsClass =
|
||||||
Class.forName("java.nio.Bits", false, getSystemClassLoader());
|
Class.forName("java.nio.Bits", false, getSystemClassLoader());
|
||||||
|
int version = javaVersion();
|
||||||
|
if (version >= 9) {
|
||||||
|
// Java9/10 use all lowercase and later versions all uppercase.
|
||||||
|
String fieldName = version >= 11 ? "UNALIGNED" : "unaligned";
|
||||||
|
// On Java9 and later we try to directly access the field as we can do this without
|
||||||
|
// adjust the accessible levels.
|
||||||
|
try {
|
||||||
|
Field unalignedField = bitsClass.getDeclaredField(fieldName);
|
||||||
|
if (unalignedField.getType() == boolean.class) {
|
||||||
|
long offset = UNSAFE.staticFieldOffset(unalignedField);
|
||||||
|
Object object = UNSAFE.staticFieldBase(unalignedField);
|
||||||
|
return UNSAFE.getBoolean(object, offset);
|
||||||
|
}
|
||||||
|
// There is something unexpected stored in the field,
|
||||||
|
// let us fall-back and try to use a reflective method call as last resort.
|
||||||
|
} catch (NoSuchFieldException ignore) {
|
||||||
|
// We did not find the field we expected, move on.
|
||||||
|
}
|
||||||
|
}
|
||||||
Method unalignedMethod = bitsClass.getDeclaredMethod("unaligned");
|
Method unalignedMethod = bitsClass.getDeclaredMethod("unaligned");
|
||||||
Throwable cause = ReflectionUtil.trySetAccessible(unalignedMethod, true);
|
Throwable cause = ReflectionUtil.trySetAccessible(unalignedMethod, true);
|
||||||
if (cause != null) {
|
if (cause != null) {
|
||||||
|
Loading…
Reference in New Issue
Block a user