/*
* Copyright ( C ) 2018 The Android Open Source Project
*
* Licensed under the Apache License , Version 2 . 0 ( the " License " ) ;
* you may not use this file except in compliance with the License .
* You may obtain a copy of the License at
*
* http : //www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing , software
* distributed under the License is distributed on an " AS IS " BASIS ,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND , either express or implied .
* See the License for the specific language governing permissions and
* limitations under the License .
*/
import static java.lang.invoke.MethodHandles.lookup;
import static java.lang.invoke.MethodType.methodType;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.VarHandle;
import java.lang.invoke.WrongMethodTypeException;
public final class Main {
static class TestSetupError extends Error {
TestSetupError(String message, Throwable cause) {
super (message, cause);
}
}
private static void failAssertion(String message) {
StringBuilder sb = new StringBuilder();
sb.append("Test failure: " );
sb.append(message);
throw new AssertionError(sb.toString());
}
private static void assertUnreachable() throws Throwable {
failAssertion("Unreachable" );
}
private static void failAssertEquals(Object expected, Object actual) {
StringBuilder sb = new StringBuilder();
sb.append(expected);
sb.append(" != " );
sb.append(actual);
failAssertion(sb.toString());
}
private static void assertEquals(boolean expected, boolean actual) {
if (expected != actual) {
failAssertEquals(expected, actual);
}
}
private static void assertEquals(int expected, int actual) {
if (expected != actual) {
failAssertEquals(expected, actual);
}
}
private static void assertEquals(long expected, long actual) {
if (expected != actual) {
failAssertEquals(expected, actual);
}
}
private static void assertEquals(float expected, float actual) {
if (expected != actual) {
failAssertEquals(expected, actual);
}
}
static class FieldVarHandleExactInvokerTest {
private static final Class <?> THIS_CLASS = FieldVarHandleExactInvokerTest.class ;
private static final VarHandle fieldVarHandle;
int field;
static {
try {
fieldVarHandle = lookup().findVarHandle(THIS_CLASS, "field" , int .class );
} catch (Exception e) {
throw new TestSetupError("Failed to lookup of field" , e);
}
}
void run() throws Throwable {
System.out.println(THIS_CLASS.getName());
MethodHandle invokerMethodHandle =
MethodHandles.varHandleExactInvoker(
VarHandle.AccessMode.GET_AND_SET,
methodType(int .class , THIS_CLASS, int .class ));
field = 3 ;
assertEquals(3 , (int ) invokerMethodHandle.invokeExact(fieldVarHandle, this , 4 ));
assertEquals(4 , field);
//
// Check invocations with MethodHandle.invokeExact()
//
try {
// Check for unboxing
int i =
(int )
invokerMethodHandle.invokeExact(
fieldVarHandle, this , Integer.valueOf(3 ));
assertUnreachable();
} catch (WrongMethodTypeException expected) {
assertEquals(4 , field);
}
try {
// Check for widening conversion
int i = (int ) invokerMethodHandle.invokeExact(fieldVarHandle, this , (short ) 3 );
assertUnreachable();
} catch (WrongMethodTypeException expected) {
assertEquals(4 , field);
}
try {
// Check for acceptance of void return type
invokerMethodHandle.invokeExact(fieldVarHandle, this , 77 );
assertUnreachable();
} catch (WrongMethodTypeException expected) {
assertEquals(4 , field);
}
try {
// Check for wider return type
long l = (long ) invokerMethodHandle.invokeExact(fieldVarHandle, this , 77 );
assertUnreachable();
} catch (WrongMethodTypeException expected) {
assertEquals(4 , field);
}
try {
// Check null VarHandle instance fails
VarHandle vhNull = null ;
int i = (int ) invokerMethodHandle.invokeExact(vhNull, this , 777 );
assertUnreachable();
} catch (NullPointerException expected) {
assertEquals(4 , field);
}
//
// Check invocations with MethodHandle.invoke()
//
// Check for unboxing
int i = (int ) invokerMethodHandle.invoke(fieldVarHandle, this , Integer.valueOf(3 ));
assertEquals(3 , field);
// Check for unboxing
i = (int ) invokerMethodHandle.invoke(fieldVarHandle, this , Short .valueOf((short ) 4 ));
assertEquals(4 , field);
// Check for widening conversion
i = (int ) invokerMethodHandle.invoke(fieldVarHandle, this , (short ) 23 );
assertEquals(23 , field);
// Check for acceptance of void return type
invokerMethodHandle.invoke(fieldVarHandle, this , 77 );
assertEquals(77 , field);
// Check for wider return type
long l = (long ) invokerMethodHandle.invoke(fieldVarHandle, this , 88 );
assertEquals(88 , field);
try {
// Check null VarHandle instance fails
VarHandle vhNull = null ;
i = (int ) invokerMethodHandle.invoke(vhNull, this , 888 );
assertUnreachable();
} catch (NullPointerException expected) {
assertEquals(88 , field);
}
}
}
static class LongFieldVarHandleExactInvokerTest {
private static final Class <?> THIS_CLASS = LongFieldVarHandleExactInvokerTest.class ;
private static final VarHandle fieldVarHandle;
private static final long CANARY = 0 x0123456789abcdefL;
long field = 0 L;
static {
try {
fieldVarHandle = lookup().findVarHandle(THIS_CLASS, "field" , long .class );
} catch (Exception e) {
throw new TestSetupError("Failed to lookup of field" , e);
}
}
void run() throws Throwable {
System.out.println(THIS_CLASS.getName());
MethodHandle invokerMethodHandle =
MethodHandles.varHandleExactInvoker(
VarHandle.AccessMode.COMPARE_AND_SET,
methodType(boolean .class , THIS_CLASS, long .class , long .class ));
checkCompareAndSet(invokerMethodHandle, 0 L, CANARY);
checkCompareAndSet(invokerMethodHandle, 1 L, 1 L);
checkCompareAndSet(invokerMethodHandle, CANARY, ~CANARY);
checkCompareAndSet(invokerMethodHandle, ~CANARY, 0 L);
}
private void checkCompareAndSet(MethodHandle compareAndSet, long oldValue, long newValue)
throws Throwable {
final boolean expectSuccess = (oldValue == field);
final long oldFieldValue = field;
assertEquals(
expectSuccess,
(boolean ) compareAndSet.invoke(fieldVarHandle, this , oldValue, newValue));
assertEquals(expectSuccess ? newValue : oldFieldValue, field);
}
}
static class FieldVarHandleInvokerTest {
private static final Class <?> THIS_CLASS = FieldVarHandleInvokerTest.class ;
private static final VarHandle fieldVarHandle;
int field;
static {
try {
fieldVarHandle = lookup().findVarHandle(THIS_CLASS, "field" , int .class );
} catch (Exception e) {
throw new TestSetupError("Failed to lookup of field" , e);
}
}
void run() throws Throwable {
System.out.println("fieldVarHandleInvokerTest" );
MethodHandle invokerMethodHandle =
MethodHandles.varHandleInvoker(
VarHandle.AccessMode.GET_AND_SET,
methodType(int .class , THIS_CLASS, int .class ));
field = 3 ;
int oldField = (int ) invokerMethodHandle.invoke(fieldVarHandle, this , 4 );
assertEquals(3 , oldField);
assertEquals(4 , field);
//
// Check invocations with MethodHandle.invoke()
//
// Check for unboxing
int i = (int ) invokerMethodHandle.invoke(fieldVarHandle, this , Integer.valueOf(3 ));
assertEquals(3 , field);
// Check for widening conversion
i = (int ) invokerMethodHandle.invoke(fieldVarHandle, this , (short ) 33 );
assertEquals(33 , field);
// Check for widening conversion
i = (int ) invokerMethodHandle.invoke(fieldVarHandle, this , Byte .valueOf((byte ) 34 ));
assertEquals(34 , field);
// Check for acceptance of void return type
invokerMethodHandle.invoke(fieldVarHandle, this , 77 );
assertEquals(77 , field);
// Check for wider return type
long l = (long ) invokerMethodHandle.invoke(fieldVarHandle, this , 88 );
assertEquals(88 , field);
try {
// Check narrowing conversion fails
i = (int ) invokerMethodHandle.invoke(fieldVarHandle, this , 3 .0 );
assertUnreachable();
} catch (WrongMethodTypeException expected) {
}
try {
// Check reference type fails
i = (int ) invokerMethodHandle.invoke(fieldVarHandle, this , "Bad" );
assertUnreachable();
} catch (WrongMethodTypeException expected) {
}
try {
// Check null VarHandle instance fails
VarHandle vhNull = null ;
i = (int ) invokerMethodHandle.invoke(vhNull, this , 888 );
assertUnreachable();
} catch (NullPointerException expected) {
assertEquals(88 , field);
}
//
// Check invocations with MethodHandle.invokeExact()
//
field = -1 ;
try {
// Check for unboxing
i = (int ) invokerMethodHandle.invokeExact(fieldVarHandle, this , Integer.valueOf(3 ));
assertUnreachable();
} catch (WrongMethodTypeException expected) {
assertEquals(-1 , field);
}
try {
// Check for widening conversion
i = (int ) invokerMethodHandle.invokeExact(fieldVarHandle, this , (short ) 33 );
assertUnreachable();
} catch (WrongMethodTypeException expected) {
assertEquals(-1 , field);
}
try {
// Check for acceptance of void return type
invokerMethodHandle.invokeExact(fieldVarHandle, this , 77 );
assertUnreachable();
} catch (WrongMethodTypeException expected) {
assertEquals(-1 , field);
}
try {
// Check for wider return type
l = (long ) invokerMethodHandle.invokeExact(fieldVarHandle, this , 78 );
assertUnreachable();
} catch (WrongMethodTypeException expected) {
assertEquals(-1 , field);
}
try {
// Check narrowing conversion fails
i = (int ) invokerMethodHandle.invokeExact(fieldVarHandle, this , 3 .0 );
assertUnreachable();
} catch (WrongMethodTypeException expected) {
}
try {
// Check reference type fails
i = (int ) invokerMethodHandle.invokeExact(fieldVarHandle, this , "Bad" );
assertUnreachable();
} catch (WrongMethodTypeException expected) {
}
try {
// Check null VarHandle instance fails
VarHandle vhNull = null ;
i = (int ) invokerMethodHandle.invokeExact(vhNull, this , 888 );
assertUnreachable();
} catch (NullPointerException expected) {
assertEquals(-1 , field);
}
}
}
static class DivergenceExactInvokerTest {
private static final VarHandle floatsArrayVarHandle;
static {
try {
floatsArrayVarHandle = MethodHandles.arrayElementVarHandle(float [].class );
} catch (Exception e) {
throw new TestSetupError("Failed to create VarHandle" , e);
}
}
void run() throws Throwable {
System.out.println("DivergenceExactInvokerTest" );
float [] floatsArray = new float [4 ];
// Exact invoker of an accessor having the form:
// float accessor(float[] values, int index, Float current, float replacement)
MethodHandle exactInvoker =
MethodHandles.varHandleExactInvoker(
VarHandle.AccessMode.COMPARE_AND_EXCHANGE,
methodType(
float .class ,
float [].class ,
int .class ,
Float .class ,
float .class ));
floatsArray[2 ] = Float .valueOf(4 .0 f);
// Callsite that is an exact match with exactInvoker.type().
try {
// exactInvoker.type() is not compatible with floatsArrayVarHandle accessor.
float old =
(float )
exactInvoker.invoke(
floatsArrayVarHandle,
floatsArray,
2 ,
Float .valueOf(4 .0 f),
8 .0 f);
assertUnreachable();
} catch (WrongMethodTypeException expected) {
assertEquals(4 .0 f, floatsArray[2 ]);
}
// Callsites that are exact matches with exactInvoker.type()
try {
// Mismatch between exactInvoker.type() and VarHandle type (Float != float)
float old =
(float )
exactInvoker.invoke(
floatsArrayVarHandle, floatsArray, 2 , 8 .0 f, 16 .0 f);
assertUnreachable();
} catch (WrongMethodTypeException expected) {
assertEquals(4 .0 f, floatsArray[2 ]);
}
try {
// short not convertible to Float
float old =
(float )
exactInvoker.invoke(
floatsArrayVarHandle, floatsArray, 2 , (short ) 4 , 13 .0 f);
assertUnreachable();
} catch (WrongMethodTypeException expected) {
assertEquals(4 .0 f, floatsArray[2 ]);
}
try {
// int not convertible to Float
float old =
(float ) exactInvoker.invoke(floatsArrayVarHandle, floatsArray, 2 , 8 , -8 .0 f);
assertUnreachable();
} catch (WrongMethodTypeException expected) {
assertEquals(4 .0 f, floatsArray[2 ]);
}
}
}
static class DivergenceInvokerTest {
private static final VarHandle floatsArrayVarHandle;
static {
try {
floatsArrayVarHandle = MethodHandles.arrayElementVarHandle(float [].class );
} catch (Exception e) {
throw new TestSetupError("Failed to create VarHandle" , e);
}
}
void run() throws Throwable {
System.out.println("DivergenceInvokerTest" );
float [] floatsArray = new float [4 ];
// Invoker of an accessor having the form:
// float accessor(float[] values, int index, Float current, float replacement)
MethodHandle invoker =
MethodHandles.varHandleInvoker(
VarHandle.AccessMode.COMPARE_AND_EXCHANGE,
methodType(
float .class ,
float [].class ,
int .class ,
Float .class ,
float .class ));
floatsArray[2 ] = Float .valueOf(4 .0 f);
// Callsite that is an exact match with invoker.type()
float old =
(float )
invoker.invoke(
floatsArrayVarHandle,
floatsArray,
2 ,
Float .valueOf(4 .0 f),
8 .0 f);
assertEquals(4 .0 f, old);
assertEquals(8 .0 f, floatsArray[2 ]);
// Callsite that is convertible match to invoker.type()
old = (float ) invoker.invoke(floatsArrayVarHandle, floatsArray, 2 , 8 .0 f, 16 .0 f);
assertEquals(8 .0 f, old);
assertEquals(16 .0 f, floatsArray[2 ]);
// Callsites that are not convertible to invoker.type().
try {
// short is not convertible to Float
old = (float ) invoker.invoke(floatsArrayVarHandle, floatsArray, 2 , (short ) 4 , 8 .0 f);
assertUnreachable();
} catch (WrongMethodTypeException expected) {
assertEquals(16 .0 f, floatsArray[2 ]);
}
try {
// int is not convertible to Float
old = (float ) invoker.invoke(floatsArrayVarHandle, floatsArray, 2 , 8 , -8 .0 f);
assertUnreachable();
} catch (WrongMethodTypeException expected) {
assertEquals(16 .0 f, floatsArray[2 ]);
}
try {
MethodHandle unsupportedInvoker =
MethodHandles.varHandleInvoker(
VarHandle.AccessMode.GET_AND_BITWISE_OR,
methodType(float .class , float [].class , int .class , float .class ));
old =
(float )
unsupportedInvoker.invoke(
floatsArrayVarHandle, floatsArray, 0 , 2 .71 f);
assertUnreachable();
} catch (UnsupportedOperationException expected) {
}
}
}
public static void main(String[] args) throws Throwable {
new FieldVarHandleExactInvokerTest().run();
new LongFieldVarHandleExactInvokerTest().run();
new FieldVarHandleInvokerTest().run();
new DivergenceExactInvokerTest().run();
new DivergenceInvokerTest().run();
}
}
Messung V0.5 in Prozent C=84 H=85 G=84
¤ Dauer der Verarbeitung: 0.10 Sekunden
(vorverarbeitet am 2026-06-29)
¤
*© Formatika GbR, Deutschland