8331670: Deprecate the Memory-Access Methods in sun.misc.Unsafe for Removal
Reviewed-by: mcimadamore, jpai, pminborg
This commit is contained in:
parent
51ae08f72b
commit
0f3e2cc334
@ -94,7 +94,7 @@ $(eval $(call SetupJavaCompilation, BUILD_JDK_MICROBENCHMARK, \
|
||||
TARGET_RELEASE := $(TARGET_RELEASE_NEWJDK_UPGRADED), \
|
||||
SMALL_JAVA := false, \
|
||||
CLASSPATH := $(JMH_COMPILE_JARS), \
|
||||
DISABLED_WARNINGS := restricted this-escape processing rawtypes cast \
|
||||
DISABLED_WARNINGS := restricted this-escape processing rawtypes removal cast \
|
||||
serial preview dangling-doc-comments, \
|
||||
SRC := $(MICROBENCHMARK_SRC), \
|
||||
BIN := $(MICROBENCHMARK_CLASSES), \
|
||||
|
@ -2282,6 +2282,15 @@ jint Arguments::parse_each_vm_init_arg(const JavaVMInitArgs* args, bool* patch_m
|
||||
if (res != JNI_OK) {
|
||||
return res;
|
||||
}
|
||||
} else if (match_option(option, "--sun-misc-unsafe-memory-access=", &tail)) {
|
||||
if (strcmp(tail, "allow") == 0 || strcmp(tail, "warn") == 0 || strcmp(tail, "debug") == 0 || strcmp(tail, "deny") == 0) {
|
||||
PropertyList_unique_add(&_system_properties, "sun.misc.unsafe.memory.access", tail,
|
||||
AddProperty, WriteableProperty, InternalProperty);
|
||||
} else {
|
||||
jio_fprintf(defaultStream::error_stream(),
|
||||
"Value specified to --sun-misc-unsafe-memory-access not recognized: '%s'\n", tail);
|
||||
return JNI_ERR;
|
||||
}
|
||||
} else if (match_option(option, "--illegal-access=", &tail)) {
|
||||
char version[256];
|
||||
JDK_Version::jdk(17).to_string(version, sizeof(version));
|
||||
|
@ -212,7 +212,11 @@ java.launcher.X.usage=\n\
|
||||
\ --finalization=<value>\n\
|
||||
\ controls whether the JVM performs finalization of objects,\n\
|
||||
\ where <value> is one of "enabled" or "disabled".\n\
|
||||
\ Finalization is enabled by default.\n\n\
|
||||
\ Finalization is enabled by default.\n\
|
||||
\ --sun-misc-unsafe-memory-access=<value>\n\
|
||||
\ allow or deny usage of unsupported API sun.misc.Unsafe\n\
|
||||
\ <value> is one of "allow", "warn", "debug", or "deny".\n\
|
||||
\ The default value is "allow".\n\n\
|
||||
These extra options are subject to change without notice.\n
|
||||
|
||||
# Translators please note do not translate the options themselves
|
||||
|
@ -1194,6 +1194,30 @@ or directories.
|
||||
.TP
|
||||
\f[V]--source\f[R] \f[I]version\f[R]
|
||||
Sets the version of the source in source-file mode.
|
||||
.TP
|
||||
\f[V]--sun-misc-unsafe-memory-acces=\f[R] \f[I]value\f[R]
|
||||
Allow or deny usage of unsupported API \f[V]sun.misc.Unsafe\f[R].
|
||||
\f[I]value\f[R] is one of:
|
||||
.RS
|
||||
.TP
|
||||
\f[V]allow\f[R]
|
||||
Allow use of the memory-access methods with no warnings at run time.
|
||||
.TP
|
||||
\f[V]warn\f[R]
|
||||
Allow use of the memory-access methods, but issues a warning on the
|
||||
first occasion that any memory-access method is used.
|
||||
At most one warning is issued.
|
||||
.TP
|
||||
\f[V]debug\f[R]
|
||||
Allow use of the memory-access methods, but issue a one-line warning and
|
||||
a stack trace when any memory-access method is used.
|
||||
.TP
|
||||
\f[V]deny\f[R]
|
||||
Disallow use of the memory-access methods by throwing an
|
||||
\f[V]UnsupportedOperationException\f[R] on every usage.
|
||||
.PP
|
||||
The default value when the option is not specified is \f[V]allow\f[R].
|
||||
.RE
|
||||
.SH EXTRA OPTIONS FOR MACOS
|
||||
.PP
|
||||
The following extra options are macOS specific.
|
||||
|
File diff suppressed because it is too large
Load Diff
136
test/jdk/sun/misc/TryUnsafeMemoryAccess.java
Normal file
136
test/jdk/sun/misc/TryUnsafeMemoryAccess.java
Normal file
@ -0,0 +1,136 @@
|
||||
/*
|
||||
* Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.nio.ByteBuffer;
|
||||
import sun.misc.Unsafe;
|
||||
|
||||
/**
|
||||
* Launched by UnsafeMemoryAccessWarnings with a '+' delimited list of methods to invoke.
|
||||
*/
|
||||
@SuppressWarnings("removal")
|
||||
public class TryUnsafeMemoryAccess {
|
||||
private static final Unsafe UNSAFE;
|
||||
static {
|
||||
try {
|
||||
Field f = Unsafe.class.getDeclaredField("theUnsafe");
|
||||
f.setAccessible(true);
|
||||
UNSAFE = (Unsafe) f.get(null);
|
||||
} catch (Exception e) {
|
||||
throw new ExceptionInInitializerError(e);
|
||||
}
|
||||
}
|
||||
private static long address;
|
||||
private static long offset;
|
||||
|
||||
static class TestClass {
|
||||
long value;
|
||||
TestClass(long value) {
|
||||
this.value = value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The argument is a list of names of no-arg static methods in this class to invoke.
|
||||
* The names are separated with a '+'.
|
||||
*/
|
||||
public static void main(String[] args) throws Exception {
|
||||
String[] methodNames = args[0].split("\\+");
|
||||
for (String methodName : methodNames) {
|
||||
Method m = TryUnsafeMemoryAccess.class.getDeclaredMethod(methodName);
|
||||
try {
|
||||
m.invoke(null);
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// a selection of Unsafe memory access methods to test
|
||||
|
||||
static void allocateMemory() {
|
||||
address = UNSAFE.allocateMemory(100);
|
||||
}
|
||||
|
||||
static void freeMemory() {
|
||||
if (address == 0)
|
||||
throw new RuntimeException("allocateMemory not called");
|
||||
UNSAFE.freeMemory(address);
|
||||
}
|
||||
|
||||
static void objectFieldOffset() throws Exception {
|
||||
Field f = TestClass.class.getDeclaredField("value");
|
||||
offset = UNSAFE.objectFieldOffset(f);
|
||||
}
|
||||
|
||||
static void getLong() {
|
||||
if (offset == 0)
|
||||
throw new RuntimeException("objectFieldOffset not called");
|
||||
var obj = new TestClass(99);
|
||||
long value = UNSAFE.getLong(obj, offset);
|
||||
if (value != 99) {
|
||||
throw new RuntimeException();
|
||||
}
|
||||
}
|
||||
|
||||
static void putLong() {
|
||||
if (offset == 0)
|
||||
throw new RuntimeException("objectFieldOffset not called");
|
||||
var obj = new TestClass(0);
|
||||
UNSAFE.putLong(obj, offset, 99);
|
||||
if (obj.value != 99) {
|
||||
throw new RuntimeException();
|
||||
}
|
||||
}
|
||||
|
||||
static void invokeCleaner() {
|
||||
var dbb = ByteBuffer.allocateDirect(1000);
|
||||
UNSAFE.invokeCleaner(dbb);
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoke Unsafe.allocateMemory reflectively.
|
||||
*/
|
||||
static void reflectivelyAllocateMemory() throws Exception {
|
||||
Method allocateMemory = Unsafe.class.getMethod("allocateMemory", long.class);
|
||||
address = (long) allocateMemory.invoke(UNSAFE, 100);
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoke Unsafe.freeMemory reflectively.
|
||||
*/
|
||||
static void reflectivelyFreeMemory() throws Exception {
|
||||
if (address == 0)
|
||||
throw new RuntimeException("allocateMemory not called");
|
||||
Method freeMemory = Unsafe.class.getMethod("freeMemory", long.class);
|
||||
freeMemory.invoke(UNSAFE, address);
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to test that the property value from startup is used.
|
||||
*/
|
||||
static void setSystemPropertyToAllow() {
|
||||
System.setProperty("sun.misc.unsafe.memory.access", "allow");
|
||||
}
|
||||
}
|
212
test/jdk/sun/misc/UnsafeMemoryAccessWarnings.java
Normal file
212
test/jdk/sun/misc/UnsafeMemoryAccessWarnings.java
Normal file
@ -0,0 +1,212 @@
|
||||
/*
|
||||
* Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8331670
|
||||
* @summary Basic test for --sun-misc-unsafe-memory-access=<value>
|
||||
* @library /test/lib
|
||||
* @compile TryUnsafeMemoryAccess.java
|
||||
* @run junit UnsafeMemoryAccessWarnings
|
||||
*/
|
||||
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.ValueSource;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
import jdk.test.lib.process.ProcessTools;
|
||||
import jdk.test.lib.process.OutputAnalyzer;
|
||||
|
||||
class UnsafeMemoryAccessWarnings {
|
||||
|
||||
/**
|
||||
* Test default is "allow"
|
||||
*/
|
||||
@Test
|
||||
void testDefault() throws Exception {
|
||||
test("allocateMemory+freeMemory+objectFieldOffset+putLong+getLong+invokeCleaner")
|
||||
.shouldHaveExitValue(0)
|
||||
.shouldNotContain("WARNING: A terminally deprecated method in sun.misc.Unsafe has been called")
|
||||
.shouldNotContain("WARNING: sun.misc.Unsafe::allocateMemory")
|
||||
.shouldNotContain("WARNING: sun.misc.Unsafe::freeMemory")
|
||||
.shouldNotContain("WARNING: sun.misc.Unsafe::objectFieldOffset")
|
||||
.shouldNotContain("WARNING: sun.misc.Unsafe::putLong")
|
||||
.shouldNotContain("WARNING: sun.misc.Unsafe::getLong")
|
||||
.shouldNotContain("WARNING: sun.misc.Unsafe::invokeCleaner");
|
||||
}
|
||||
|
||||
/**
|
||||
* Test --sun-misc-unsafe-memory-access=allow
|
||||
*/
|
||||
@Test
|
||||
void testAllow() throws Exception {
|
||||
test("allocateMemory+freeMemory+objectFieldOffset+putLong+getLong+invokeCleaner",
|
||||
"--sun-misc-unsafe-memory-access=allow")
|
||||
.shouldHaveExitValue(0)
|
||||
.shouldNotContain("WARNING: A terminally deprecated method in sun.misc.Unsafe has been called")
|
||||
.shouldNotContain("WARNING: sun.misc.Unsafe::allocateMemory")
|
||||
.shouldNotContain("WARNING: sun.misc.Unsafe::freeMemory")
|
||||
.shouldNotContain("WARNING: sun.misc.Unsafe::objectFieldOffset")
|
||||
.shouldNotContain("WARNING: sun.misc.Unsafe::putLong")
|
||||
.shouldNotContain("WARNING: sun.misc.Unsafe::getLong")
|
||||
.shouldNotContain("WARNING: sun.misc.Unsafe::invokeCleaner");
|
||||
}
|
||||
|
||||
/**
|
||||
* Test --sun-misc-unsafe-memory-access=warn
|
||||
*/
|
||||
@ParameterizedTest
|
||||
@ValueSource(strings = {
|
||||
"allocateMemory+freeMemory",
|
||||
"objectFieldOffset+putLong+getLong",
|
||||
"invokeCleaner"
|
||||
})
|
||||
void testWarn(String input) throws Exception {
|
||||
var output = test(input, "--sun-misc-unsafe-memory-access=warn").shouldHaveExitValue(0);
|
||||
|
||||
// should be warning printed for the first memory access method
|
||||
String[] methodNames = input.split("\\+");
|
||||
String firstMethodName = methodNames[0];
|
||||
output.shouldContain("WARNING: A terminally deprecated method in sun.misc.Unsafe has been called")
|
||||
.shouldContain("WARNING: sun.misc.Unsafe::" + firstMethodName + " has been called by")
|
||||
.shouldContain("WARNING: Please consider reporting this to the maintainers of")
|
||||
.shouldContain("WARNING: sun.misc.Unsafe::" + firstMethodName + " will be removed in a future release");
|
||||
|
||||
// should be no warning for the second/subsequent memory access methods
|
||||
int index = 1;
|
||||
while (index < methodNames.length) {
|
||||
String methodName = methodNames[index++];
|
||||
output.shouldNotContain("WARNING: sun.misc.Unsafe::" + methodName);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test --sun-misc-unsafe-memory-access=debug
|
||||
*/
|
||||
@Test
|
||||
void testDebug() throws Exception {
|
||||
test("allocateMemory+freeMemory+objectFieldOffset+putLong+getLong+invokeCleaner",
|
||||
"--sun-misc-unsafe-memory-access=debug")
|
||||
.shouldHaveExitValue(0)
|
||||
.shouldContain("WARNING: sun.misc.Unsafe::allocateMemory called")
|
||||
.shouldContain("WARNING: sun.misc.Unsafe::freeMemory called")
|
||||
.shouldContain("WARNING: sun.misc.Unsafe::objectFieldOffset called")
|
||||
.shouldContain("WARNING: sun.misc.Unsafe::putLong called")
|
||||
.shouldContain("WARNING: sun.misc.Unsafe::getLong called")
|
||||
.shouldContain("WARNING: sun.misc.Unsafe::invokeCleaner called");
|
||||
}
|
||||
|
||||
/**
|
||||
* Test --sun-misc-unsafe-memory-access=deny
|
||||
*/
|
||||
@Test
|
||||
void testDeny() throws Exception {
|
||||
test("allocateMemory+objectFieldOffset+invokeCleaner", "--sun-misc-unsafe-memory-access=deny")
|
||||
.shouldHaveExitValue(0)
|
||||
.shouldContain("java.lang.UnsupportedOperationException: allocateMemory")
|
||||
.shouldContain("java.lang.UnsupportedOperationException: objectFieldOffset")
|
||||
.shouldContain("java.lang.UnsupportedOperationException: invokeCleaner");
|
||||
}
|
||||
|
||||
/**
|
||||
* Test invoking Unsafe methods with core reflection.
|
||||
*/
|
||||
@Test
|
||||
void testInvokeReflectively() throws Exception {
|
||||
test("reflectivelyAllocateMemory+reflectivelyFreeMemory", "--sun-misc-unsafe-memory-access=allow")
|
||||
.shouldHaveExitValue(0)
|
||||
.shouldNotContain("WARNING: A terminally deprecated method in sun.misc.Unsafe has been called")
|
||||
.shouldNotContain("WARNING: sun.misc.Unsafe::allocateMemory")
|
||||
.shouldNotContain("WARNING: sun.misc.Unsafe::freeMemory");
|
||||
|
||||
test("reflectivelyAllocateMemory+reflectivelyFreeMemory", "--sun-misc-unsafe-memory-access=warn")
|
||||
.shouldHaveExitValue(0)
|
||||
.shouldContain("WARNING: A terminally deprecated method in sun.misc.Unsafe has been called")
|
||||
.shouldContain("WARNING: sun.misc.Unsafe::allocateMemory has been called by")
|
||||
.shouldContain("WARNING: Please consider reporting this to the maintainers of")
|
||||
.shouldContain("WARNING: sun.misc.Unsafe::allocateMemory will be removed in a future release")
|
||||
.shouldNotContain("WARNING: sun.misc.Unsafe::freeMemory");
|
||||
|
||||
test("reflectivelyAllocateMemory+reflectivelyFreeMemory", "--sun-misc-unsafe-memory-access=debug")
|
||||
.shouldHaveExitValue(0)
|
||||
.shouldContain("WARNING: sun.misc.Unsafe::allocateMemory called")
|
||||
.shouldContain("WARNING: sun.misc.Unsafe::freeMemory called");
|
||||
|
||||
test("reflectivelyAllocateMemory", "--sun-misc-unsafe-memory-access=deny")
|
||||
.shouldHaveExitValue(0)
|
||||
.shouldContain("java.lang.UnsupportedOperationException: allocateMemory");
|
||||
}
|
||||
|
||||
/**
|
||||
* If --sun-misc-unsafe-memory-access specified more than once then last one wins.
|
||||
*/
|
||||
@Test
|
||||
void testLastOneWins() throws Exception {
|
||||
test("allocateMemory+objectFieldOffset+invokeCleaner",
|
||||
"--sun-misc-unsafe-memory-access=allow",
|
||||
"--sun-misc-unsafe-memory-access=deny")
|
||||
.shouldHaveExitValue(0)
|
||||
.shouldContain("java.lang.UnsupportedOperationException: allocateMemory")
|
||||
.shouldContain("java.lang.UnsupportedOperationException: objectFieldOffset")
|
||||
.shouldContain("java.lang.UnsupportedOperationException: invokeCleaner");
|
||||
}
|
||||
|
||||
/**
|
||||
* Test --sun-misc-unsafe-memory-access with invalid values.
|
||||
*/
|
||||
@ParameterizedTest
|
||||
@ValueSource(strings = { "", "bad" })
|
||||
void testInvalidValues(String value) throws Exception {
|
||||
test("allocateMemory", "--sun-misc-unsafe-memory-access=" + value)
|
||||
.shouldNotHaveExitValue(0)
|
||||
.shouldContain("Value specified to --sun-misc-unsafe-memory-access not recognized: '" + value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test System.setProperty("sun.misc.unsafe.memory.access", "allow")
|
||||
* The saved value from startup should be used, not the system property set at run-time.
|
||||
*/
|
||||
@Test
|
||||
void testSetPropertyToAllow() throws Exception {
|
||||
test("setSystemPropertyToAllow+objectFieldOffset", "--sun-misc-unsafe-memory-access=deny")
|
||||
.shouldHaveExitValue(0)
|
||||
.shouldContain("java.lang.UnsupportedOperationException: objectFieldOffset");
|
||||
}
|
||||
|
||||
/**
|
||||
* Launch TryUnsafeMemoryAccess with the given arguments and VM options.
|
||||
*/
|
||||
private OutputAnalyzer test(String action, String... vmopts) throws Exception {
|
||||
Stream<String> s1 = Stream.of(vmopts);
|
||||
Stream<String> s2 = Stream.of("TryUnsafeMemoryAccess", action);
|
||||
String[] opts = Stream.concat(s1, s2).toArray(String[]::new);
|
||||
var outputAnalyzer = ProcessTools
|
||||
.executeTestJava(opts)
|
||||
.outputTo(System.err)
|
||||
.errorTo(System.err);
|
||||
return outputAnalyzer;
|
||||
}
|
||||
}
|
89
test/micro/org/openjdk/bench/sun/misc/UnsafeOps.java
Normal file
89
test/micro/org/openjdk/bench/sun/misc/UnsafeOps.java
Normal file
@ -0,0 +1,89 @@
|
||||
/*
|
||||
* Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
package org.openjdk.bench.sun.misc;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import sun.misc.Unsafe;
|
||||
import org.openjdk.jmh.annotations.*;
|
||||
|
||||
@BenchmarkMode(Mode.AverageTime)
|
||||
@Warmup(iterations = 5, time = 500, timeUnit = TimeUnit.MILLISECONDS)
|
||||
@Measurement(iterations = 10, time = 500, timeUnit = TimeUnit.MILLISECONDS)
|
||||
@State(org.openjdk.jmh.annotations.Scope.Thread)
|
||||
@OutputTimeUnit(TimeUnit.NANOSECONDS)
|
||||
@SuppressWarnings("removal")
|
||||
public class UnsafeOps {
|
||||
static final Unsafe U;
|
||||
static {
|
||||
try {
|
||||
Field f = Unsafe.class.getDeclaredField("theUnsafe");
|
||||
f.setAccessible(true);
|
||||
U = (Unsafe) f.get(null);
|
||||
} catch (ReflectiveOperationException ex) {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
}
|
||||
|
||||
private static class TestClass {
|
||||
long value;
|
||||
}
|
||||
|
||||
private Object object;
|
||||
private long valueOffset;
|
||||
private long address;
|
||||
|
||||
@Setup
|
||||
public void setup() throws Exception {
|
||||
object = new TestClass();
|
||||
Field f = TestClass.class.getDeclaredField("value");
|
||||
valueOffset = U.objectFieldOffset(f);
|
||||
|
||||
address = U.allocateMemory(1000);
|
||||
}
|
||||
|
||||
@TearDown
|
||||
public void finish() {
|
||||
U.freeMemory(address);
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void putLongOnHeap() {
|
||||
U.putLong(object, 0, 99);
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public long getLongOnHeap() {
|
||||
return U.getLong(object, 0);
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public void putLongOffHeap() {
|
||||
U.putLong(null, address, 99);
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
public long getLongOffHeap() {
|
||||
return U.getLong(null, address);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user