bd-jb/src/com/bdjb/UnsafeJdkImpl.java

114 lines
3.1 KiB
Java

/*
* Copyright (C) 2021 Andy Nguyen
*
* This software may be modified and distributed under the terms
* of the MIT license. See the LICENSE file for details.
*/
package com.bdjb;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import jdk.internal.misc.Unsafe;
class UnsafeJdkImpl implements UnsafeInterface {
private static final String GET_MODULE_METHOD_NAME = "getModule";
private static final String MODULE_CLASS_NAME = "java.lang.Module";
private static final String IMPL_ADD_OPENS_TO_ALL_UNNAMED_METHOD_NAME =
"implAddOpensToAllUnnamed";
private static final String UNSAFE_CLASS_NAME = "jdk.internal.misc.Unsafe";
private static final String THE_UNSAFE_FIELD_NAME = "theUnsafe";
private final Unsafe unsafe;
UnsafeJdkImpl() throws Exception {
// Throw exception if class does not exist.
Class.forName(UNSAFE_CLASS_NAME);
// Get unsafe module.
Method getModuleMethod = Class.class.getDeclaredMethod(GET_MODULE_METHOD_NAME, null);
getModuleMethod.setAccessible(true);
Object unsafeModule = getModuleMethod.invoke(Unsafe.class, null);
// Open unsafe package.
Method implAddOpensToAllUnnamedMethod =
Class.forName(MODULE_CLASS_NAME)
.getDeclaredMethod(
IMPL_ADD_OPENS_TO_ALL_UNNAMED_METHOD_NAME, new Class[] {String.class});
implAddOpensToAllUnnamedMethod.setAccessible(true);
implAddOpensToAllUnnamedMethod.invoke(
unsafeModule, new Object[] {Unsafe.class.getPackage().getName()});
// Get unsafe instance.
Field theUnsafeField = Unsafe.class.getDeclaredField(THE_UNSAFE_FIELD_NAME);
theUnsafeField.setAccessible(true);
unsafe = (Unsafe) theUnsafeField.get(null);
}
public byte getByte(long address) {
return unsafe.getByte(address);
}
public short getShort(long address) {
return unsafe.getShort(address);
}
public int getInt(long address) {
return unsafe.getInt(address);
}
public long getLong(long address) {
return unsafe.getLong(address);
}
public long getLong(Object o, long offset) {
return unsafe.getLong(o, offset);
}
public void putByte(long address, byte x) {
unsafe.putByte(address, x);
}
public void putShort(long address, short x) {
unsafe.putShort(address, x);
}
public void putInt(long address, int x) {
unsafe.putInt(address, x);
}
public void putLong(long address, long x) {
unsafe.putLong(address, x);
}
public void putObject(Object o, long offset, Object x) {
unsafe.putObject(o, offset, x);
}
public long objectFieldOffset(Field f) {
return unsafe.objectFieldOffset(f);
}
public long allocateMemory(long bytes) {
return unsafe.allocateMemory(bytes);
}
public long reallocateMemory(long address, long bytes) {
return unsafe.reallocateMemory(address, bytes);
}
public void freeMemory(long address) {
unsafe.freeMemory(address);
}
public void setMemory(long address, long bytes, byte value) {
unsafe.setMemory(address, bytes, value);
}
public void copyMemory(long srcAddress, long destAddress, long bytes) {
unsafe.copyMemory(srcAddress, destAddress, bytes);
}
}