mirror of
https://github.com/corda/corda.git
synced 2025-01-04 04:04:27 +00:00
afbd4ff303
This method ends up defering to JVM_GetClassDeclaredMethods, which creates an array of java.lang.reflect.Method instances and then calling getName on each one through the java.lang.reflect.Member interface. However, Method is a "bootstrap" class, meaning the VM has built-in knowledge of it and includes a tentative version built-in but must load the real version from the classpath at runtime before invoking methods on it. Normally this happens naturally when Method instances are created in Java code, but here we're creating them in the VM instead, which doesn't automatically cause the real class to be loaded. So we must do so explicitly.
148 lines
4.4 KiB
Java
148 lines
4.4 KiB
Java
import sun.misc.Unsafe;
|
|
|
|
public class UnsafeTest {
|
|
private static void expect(boolean v) {
|
|
if (! v) throw new RuntimeException();
|
|
}
|
|
|
|
private static void unsafeThrow(Unsafe u) {
|
|
u.throwException(new Exception());
|
|
}
|
|
|
|
private static void unsafeCatch(Unsafe u) {
|
|
boolean success = false;
|
|
try {
|
|
unsafeThrow(u);
|
|
} catch(Exception e) {
|
|
expect(e.getClass() == Exception.class);
|
|
success = true;
|
|
}
|
|
expect(success);
|
|
}
|
|
|
|
private static void unsafeMemory(Unsafe u) {
|
|
final long size = 64;
|
|
long memory = u.allocateMemory(size);
|
|
try {
|
|
for (int i = 0; i < size; ++i)
|
|
u.putByte(memory + i, (byte) 42);
|
|
|
|
for (int i = 0; i < size; ++i)
|
|
expect(u.getByte(memory + i) == 42);
|
|
|
|
for (int i = 0; i < size / 2; ++i)
|
|
u.putShort(memory + (i * 2), (short) -12345);
|
|
|
|
for (int i = 0; i < size / 2; ++i)
|
|
expect(u.getShort(memory + (i * 2)) == -12345);
|
|
|
|
for (int i = 0; i < size / 2; ++i)
|
|
u.putChar(memory + (i * 2), (char) 23456);
|
|
|
|
for (int i = 0; i < size / 2; ++i)
|
|
expect(u.getChar(memory + (i * 2)) == 23456);
|
|
|
|
for (int i = 0; i < size / 4; ++i)
|
|
u.putInt(memory + (i * 4), 0x12345678);
|
|
|
|
for (int i = 0; i < size / 4; ++i)
|
|
expect(u.getInt(memory + (i * 4)) == 0x12345678);
|
|
|
|
for (int i = 0; i < size / 4; ++i)
|
|
u.putFloat(memory + (i * 4), 1.2345678F);
|
|
|
|
for (int i = 0; i < size / 4; ++i)
|
|
expect(u.getFloat(memory + (i * 4)) == 1.2345678F);
|
|
|
|
for (int i = 0; i < size / 8; ++i)
|
|
u.putLong(memory + (i * 8), 0x1234567890ABCDEFL);
|
|
|
|
for (int i = 0; i < size / 8; ++i)
|
|
expect(u.getLong(memory + (i * 8)) == 0x1234567890ABCDEFL);
|
|
|
|
for (int i = 0; i < size / 8; ++i)
|
|
u.putDouble(memory + (i * 8), 1.23456789012345D);
|
|
|
|
for (int i = 0; i < size / 8; ++i)
|
|
expect(u.getDouble(memory + (i * 8)) == 1.23456789012345D);
|
|
|
|
for (int i = 0; i < size / 8; ++i)
|
|
u.putAddress(memory + (i * 8), 0x12345678);
|
|
|
|
for (int i = 0; i < size / 8; ++i)
|
|
expect(u.getAddress(memory + (i * 8)) == 0x12345678);
|
|
} finally {
|
|
u.freeMemory(memory);
|
|
}
|
|
}
|
|
|
|
private static void unsafeArray(Unsafe u) {
|
|
final int offset = u.arrayBaseOffset(long[].class);
|
|
final int scale = u.arrayIndexScale(long[].class);
|
|
final int size = 64;
|
|
final long[] array = new long[size];
|
|
|
|
for (int i = 0; i < size; ++i)
|
|
u.putBooleanVolatile(array, offset + (i * scale), i % 2 == 0);
|
|
|
|
for (int i = 0; i < size; ++i)
|
|
expect(u.getBooleanVolatile(array, offset + (i * scale))
|
|
== (i % 2 == 0));
|
|
|
|
for (int i = 0; i < size; ++i)
|
|
u.putByteVolatile(array, offset + (i * scale), (byte) 42);
|
|
|
|
for (int i = 0; i < size; ++i)
|
|
expect(u.getByteVolatile(array, offset + (i * scale)) == 42);
|
|
|
|
for (int i = 0; i < size; ++i)
|
|
u.putShortVolatile(array, offset + (i * scale), (short) -12345);
|
|
|
|
for (int i = 0; i < size; ++i)
|
|
expect(u.getShortVolatile(array, offset + (i * scale)) == -12345);
|
|
|
|
for (int i = 0; i < size; ++i)
|
|
u.putCharVolatile(array, offset + (i * scale), (char) 23456);
|
|
|
|
for (int i = 0; i < size; ++i)
|
|
expect(u.getCharVolatile(array, offset + (i * scale)) == 23456);
|
|
|
|
for (int i = 0; i < size; ++i)
|
|
u.putIntVolatile(array, offset + (i * scale), 0x12345678);
|
|
|
|
for (int i = 0; i < size; ++i)
|
|
expect(u.getIntVolatile(array, offset + (i * scale)) == 0x12345678);
|
|
|
|
for (int i = 0; i < size; ++i)
|
|
u.putFloatVolatile(array, offset + (i * scale), 1.2345678F);
|
|
|
|
for (int i = 0; i < size; ++i)
|
|
expect(u.getFloatVolatile(array, offset + (i * scale)) == 1.2345678F);
|
|
|
|
for (int i = 0; i < size; ++i)
|
|
u.putLongVolatile(array, offset + (i * scale), 0x1234567890ABCDEFL);
|
|
|
|
for (int i = 0; i < size; ++i)
|
|
expect(u.getLongVolatile(array, offset + (i * scale))
|
|
== 0x1234567890ABCDEFL);
|
|
|
|
for (int i = 0; i < size; ++i)
|
|
u.putDoubleVolatile(array, offset + (i * scale), 1.23456789012345D);
|
|
|
|
for (int i = 0; i < size; ++i)
|
|
expect(u.getDoubleVolatile(array, offset + (i * scale))
|
|
== 1.23456789012345D);
|
|
}
|
|
|
|
public static void main(String[] args) {
|
|
System.out.println("method count is "
|
|
+ Unsafe.class.getDeclaredMethods().length);
|
|
|
|
Unsafe u = avian.Machine.getUnsafe();
|
|
|
|
unsafeCatch(u);
|
|
unsafeMemory(u);
|
|
unsafeArray(u);
|
|
}
|
|
}
|