in servicetalk-utils-internal/src/main/java/io/servicetalk/utils/internal/PlatformDependent0.java [78:184]
static {
Unsafe unsafe;
if (IS_EXPLICIT_NO_UNSAFE) {
unsafe = null;
} else {
// attempt to access field Unsafe#theUnsafe
final Object maybeUnsafe = AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
try {
final Field unsafeField = Unsafe.class.getDeclaredField("theUnsafe");
final Throwable cause = ReflectionUtils.trySetAccessible(unsafeField, false);
if (cause != null) {
return cause;
}
// the unsafe instance
return unsafeField.get(null);
} catch (NoSuchFieldException | SecurityException | IllegalAccessException e) {
return e;
}
});
// the conditional check here can not be replaced with checking that maybeUnsafe
// is an instanceof Unsafe and reversing the if and else blocks; this is because an
// instanceof check against Unsafe will trigger a class load and we might not have
// the runtime permission accessClassInPackage.sun.misc
if (maybeUnsafe instanceof Exception) {
unsafe = null;
LOGGER.debug("sun.misc.Unsafe.theUnsafe: unavailable", (Exception) maybeUnsafe);
} else {
unsafe = (Unsafe) maybeUnsafe;
LOGGER.debug("sun.misc.Unsafe.theUnsafe: available");
}
}
UNSAFE = unsafe;
final ByteBuffer direct;
final MethodHandles.Lookup lookup;
// Define DIRECT_BUFFER_CONSTRUCTOR:
if (UNSAFE == null) {
direct = null;
lookup = null;
DIRECT_BUFFER_CONSTRUCTOR = null;
} else {
direct = ByteBuffer.allocateDirect(1);
lookup = MethodHandles.lookup();
DIRECT_BUFFER_CONSTRUCTOR = lookupAccessibleObject(() -> direct.getClass().getDeclaredConstructor(
int.class, long.class, FileDescriptor.class, Runnable.class), Constructor.class, constructor -> {
long address = 0L;
try {
final MethodHandle methodHandle = lookup.unreflectConstructor(constructor);
address = allocateMemory(1);
if (methodHandle.invoke(1, address, null, (Runnable) () -> { /* NOOP */ }) instanceof ByteBuffer) {
return methodHandle;
}
return null;
} finally {
if (address != 0L) {
freeMemory(address);
}
}
});
}
LOGGER.debug("java.nio.DirectByteBuffer.<init>(int, long, FileDescriptor, Runnable): {}",
DIRECT_BUFFER_CONSTRUCTOR != null ? "available" : "unavailable");
// Define DEALLOCATOR_CONSTRUCTOR:
if (UNSAFE == null || DIRECT_BUFFER_CONSTRUCTOR == null) {
DEALLOCATOR_CONSTRUCTOR = null;
} else {
DEALLOCATOR_CONSTRUCTOR = lookupAccessibleObject(() -> {
for (Class<?> innerClass : direct.getClass().getDeclaredClasses()) {
if (DEALLOCATOR_CLASS_NAME.equals(innerClass.getName())) {
return innerClass.getDeclaredConstructor(long.class, long.class, int.class);
}
}
return null;
}, Constructor.class, constructor -> {
final MethodHandle methodHandle = lookup.unreflectConstructor(constructor);
if (methodHandle.invoke(0L, 0L, 0) instanceof Runnable) {
return methodHandle;
}
return null;
});
}
LOGGER.debug("java.nio.DirectByteBuffer$Deallocator.<init>(long, long, int): {}",
DIRECT_BUFFER_CONSTRUCTOR != null ? "available" : "unavailable");
// Define RESERVE_MEMORY and UNRESERVE_MEMORY:
if (UNSAFE == null || DIRECT_BUFFER_CONSTRUCTOR == null || DEALLOCATOR_CONSTRUCTOR == null) {
RESERVE_MEMORY = null;
UNRESERVE_MEMORY = null;
} else {
RESERVE_MEMORY = extractNioBitsMethod("reserveMemory", lookup);
UNRESERVE_MEMORY = extractNioBitsMethod("unreserveMemory", lookup);
}
LOGGER.debug("java.nio.Bits.reserveMemory(long, int): {}",
RESERVE_MEMORY != null ? "available" : "unavailable");
LOGGER.debug("java.nio.Bits.unreserveMemory(long, int): {}",
UNRESERVE_MEMORY != null ? "available" : "unavailable");
// Define USE_DIRECT_BUFFER_WITHOUT_ZEROING:
USE_DIRECT_BUFFER_WITHOUT_ZEROING = UNSAFE != null && DIRECT_BUFFER_CONSTRUCTOR != null &&
DEALLOCATOR_CONSTRUCTOR != null && RESERVE_MEMORY != null && UNRESERVE_MEMORY != null;
LOGGER.debug("Allocation of DirectByteBuffer without zeroing memory: {}",
USE_DIRECT_BUFFER_WITHOUT_ZEROING ? "available" : "unavailable");
}