下面列出了java.lang.invoke.VolatileCallSite#java.lang.invoke.ConstantCallSite 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
/**
* A bootstrap method for handling string concatenation
*
* @see java.lang.invoke.StringConcatFactory#makeConcatWithConstants(MethodHandles.Lookup, java.lang.String, MethodType, java.lang.String, Object...)
*/
public static java.lang.invoke.CallSite avm_makeConcatWithConstants(
java.lang.invoke.MethodHandles.Lookup owner,
java.lang.String invokedName,
MethodType concatType,
java.lang.String recipe,
Object... constants) throws NoSuchMethodException, IllegalAccessException {
InvokeDynamicChecks.checkOwner(owner);
// Note that we currently only use the avm_makeConcatWithConstants invoked name.
RuntimeAssertionError.assertTrue("avm_makeConcatWithConstants".equals(invokedName));
final MethodType concatMethodType = MethodType.methodType(
String.class, // NOTE! First arg is return value
java.lang.String.class,
Object[].class,
Object[].class);
final MethodHandle concatMethodHandle = owner
.findStatic(StringConcatFactory.class, "avm_concat", concatMethodType)
.bindTo(recipe)
.bindTo(constants)
.asVarargsCollector(Object[].class)
.asType(concatType);
return new ConstantCallSite(concatMethodHandle);
}
private static void registerCallSitePlugins(InvocationPlugins plugins) {
InvocationPlugin plugin = new InvocationPlugin() {
@Override
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver) {
ValueNode callSite = receiver.get();
ValueNode folded = CallSiteTargetNode.tryFold(GraphUtil.originalValue(callSite), b.getMetaAccess(), b.getAssumptions());
if (folded != null) {
b.addPush(JavaKind.Object, folded);
} else {
b.addPush(JavaKind.Object, new CallSiteTargetNode(b.getInvokeKind(), targetMethod, b.bci(), b.getInvokeReturnStamp(b.getAssumptions()), callSite));
}
return true;
}
@Override
public boolean inlineOnly() {
return true;
}
};
plugins.register(plugin, ConstantCallSite.class, "getTarget", Receiver.class);
plugins.register(plugin, MutableCallSite.class, "getTarget", Receiver.class);
plugins.register(plugin, VolatileCallSite.class, "getTarget", Receiver.class);
}
public static void main(String[] args) {
ProxyFactory<IntBinaryOperator> factory = Proxy2.createAnonymousProxyFactory(IntBinaryOperator.class, new Class<?>[] { IntBinaryOperator.class },
new ProxyHandler.Default() {
@Override
public CallSite bootstrap(ProxyContext context) throws Throwable {
MethodHandle target =
methodBuilder(context.type())
.dropFirst()
.before(b -> b
.dropFirst()
.unreflect(publicLookup(), Intercept.class.getMethod("intercept", int.class, int.class)))
.unreflect(publicLookup(), context.method());
return new ConstantCallSite(target);
}
});
//IntBinaryOperator op = (a, b) -> a + b;
IntBinaryOperator op = (a, b) -> {
throw null;
};
IntBinaryOperator op2 = factory.create(op);
System.out.println(op2.applyAsInt(1, 2));
}
public static void main(String[] args) {
ProxyFactory<Delegation> factory = Proxy2.createAnonymousProxyFactory(Delegation.class, new Class<?>[] { PrintStream.class },
new ProxyHandler.Default() {
@Override
public CallSite bootstrap(ProxyContext context) throws Throwable {
MethodHandle target =
methodBuilder(context.type())
.dropFirst()
.unreflect(publicLookup(), PrintStream.class.getMethod("println", String.class));
return new ConstantCallSite(target);
}
});
Delegation hello = factory.create(System.out);
hello.println("hello proxy2");
}
public static void main(String[] args) {
ProxyFactory<Print> factory = Proxy2.createAnonymousProxyFactory(Print.class, new ProxyHandler.Default() {
@Override
public CallSite bootstrap(ProxyContext context) throws Throwable {
MethodHandle target =
methodBuilder(context.type())
.dropFirst()
.insertAt(0, PrintStream.class, System.out)
.unreflect(publicLookup(), PrintStream.class.getMethod("println", String.class));
return new ConstantCallSite(target);
}
});
Print hello = factory.create();
hello.println("hello proxy2");
}
public static void main(String[] args) {
ProxyFactory<IntBinaryOperator> factory = Proxy2.createAnonymousProxyFactory(IntBinaryOperator.class, new Class<?>[] { IntBinaryOperator.class },
new ProxyHandler.Default() {
@Override
public CallSite bootstrap(ProxyContext context) throws Throwable {
MethodHandle target =
methodBuilder(context.type())
.dropFirst()
.unreflect(publicLookup(), context.method());
return new ConstantCallSite(target);
}
});
IntBinaryOperator op = (a, b) -> a + b;
IntBinaryOperator op2 = factory.create(op);
System.out.println(op2.applyAsInt(1, 2));
}
public static void main(String[] args) {
ProxyFactory<Runnable> factory = Proxy2.createAnonymousProxyFactory(Runnable.class, new ProxyHandler.Default() {
@Override
public CallSite bootstrap(ProxyContext context) throws Throwable {
return new ConstantCallSite(
dropArguments(
insertArguments(
publicLookup().findVirtual(PrintStream.class, "println",
methodType(void.class, String.class)),
0, System.out, "hello proxy"),
0, Object.class));
}
});
Runnable runnable = factory.create();
runnable.run();
factory = null;
runnable = null;
System.gc(); // should unload the proxy class
}
public static void main(String[] args) {
ProxyFactory<IntBinaryOperator> factory = Proxy2.createAnonymousProxyFactory(IntBinaryOperator.class, new Class<?>[] { IntBinaryOperator.class },
new ProxyHandler.Default() {
@Override
public CallSite bootstrap(ProxyContext context) throws Throwable {
MethodHandle target =
methodBuilder(context.type())
.dropFirst()
.before(b -> b
.dropFirst()
.boxAll()
.unreflect(publicLookup(), Intercept2.class.getMethod("intercept", Object[].class)))
.unreflect(publicLookup(), context.method());
return new ConstantCallSite(target);
}
});
IntBinaryOperator op = (a, b) -> a + b;
IntBinaryOperator op2 = factory.create(op);
System.out.println(op2.applyAsInt(1, 2));
}
@Override
protected MethodHandle computeValue(Class<?> type) {
Lookup lookup = lookup();
return Proxy2.createAnonymousProxyFactory(publicLookup(), methodType(type), new ProxyHandler.Default() {
@Override
public CallSite bootstrap(ProxyContext context) throws Throwable {
Method method = context.method();
switch(method.getName()) {
case "create":
MethodHandle target = methodBuilder(context.type())
.dropFirst()
.insertAt(0, ClassValue.class, beanFactories)
.insertAt(1, Class.class, method.getReturnType())
.convertTo(Object.class, ClassValue.class, Class.class)
.unreflect(lookup, ORMapper.class.getDeclaredMethod("newBean", ClassValue.class, Class.class));
return new ConstantCallSite(target);
default:
throw new NoSuchMethodError(method.toString());
}
}
});
}
public static void main(String[] args) {
ProxyFactory<Hello> factory = Proxy2.createAnonymousProxyFactory(Hello.class, new ProxyHandler.Default() {
@Override
public CallSite bootstrap(ProxyContext context) throws Throwable {
System.out.println("bootstrap method " + context.method());
System.out.println("bootstrap type " + context.type());
MethodHandle target =
methodBuilder(context.type())
.dropFirst()
.unreflect(publicLookup(), String.class.getMethod("concat", String.class));
return new ConstantCallSite(target);
}
});
Hello simple = factory.create();
System.out.println(simple.message("hello ", "proxy"));
System.out.println(simple.message("hello ", "proxy 2"));
}
/**
* Reduce by functional support for int arrays.
* @param array array of items to reduce by
* @param object object that contains the reduce by function
* @param <T> the type of object
* @return the final reduction
*/
public static <T> long reduceBy( final long[] array, T object ) {
if (object.getClass().isAnonymousClass()) {
return reduceByR(array, object );
}
try {
ConstantCallSite callSite = Invoker.invokeReducerLongIntReturnLongMethodHandle(object);
MethodHandle methodHandle = callSite.dynamicInvoker();
try {
long sum = 0;
for ( long v : array ) {
sum = (long) methodHandle.invokeExact( sum, v );
}
return sum;
} catch (Throwable throwable) {
return handle(Long.class, throwable, "Unable to perform reduceBy");
}
} catch (Exception ex) {
return reduceByR(array, object);
}
}
/**
* Reduce by functional support for int arrays.
* @param array array of items to reduce by
* @param object object that contains the reduce by function
* @param <T> the type of object
* @return the final reduction
*/
public static <T> double reduceBy( final float[] array, T object ) {
if (object.getClass().isAnonymousClass()) {
return reduceByR(array, object );
}
try {
ConstantCallSite callSite = Invoker.invokeReducerLongIntReturnLongMethodHandle(object);
MethodHandle methodHandle = callSite.dynamicInvoker();
try {
double sum = 0;
for ( float v : array ) {
sum = (double) methodHandle.invokeExact( sum, v );
}
return sum;
} catch (Throwable throwable) {
return handle(Long.class, throwable, "Unable to perform reduceBy");
}
} catch (Exception ex) {
return reduceByR(array, object);
}
}
/**
* Reduce by functional support for int arrays.
* @param array array of items to reduce by
* @param object object that contains the reduce by function
* @param <T> the type of object
* @return the final reduction
*/
public static <T> long reduceBy( final int[] array, T object ) {
if (object.getClass().isAnonymousClass()) {
return reduceByR(array, object );
}
try {
ConstantCallSite callSite = Invoker.invokeReducerLongIntReturnLongMethodHandle(object);
MethodHandle methodHandle = callSite.dynamicInvoker();
try {
long sum = 0;
for ( int v : array ) {
sum = (long) methodHandle.invokeExact( sum, v );
}
return sum;
} catch (Throwable throwable) {
return handle(Long.class, throwable, "Unable to perform reduceBy");
}
} catch (Exception ex) {
return reduceByR(array, object);
}
}
/**
* Reduce by functional support for int arrays.
* @param array array of items to reduce by
* @param object object that contains the reduce by function
* @param <T> the type of object
* @return the final reduction
*/
public static <T> double reduceBy( final double[] array, T object ) {
if (object.getClass().isAnonymousClass()) {
return reduceByR(array, object );
}
try {
ConstantCallSite callSite = Invoker.invokeReducerLongIntReturnLongMethodHandle(object);
MethodHandle methodHandle = callSite.dynamicInvoker();
try {
double sum = 0;
for ( double v : array ) {
sum = (double) methodHandle.invokeExact( sum, v );
}
return sum;
} catch (Throwable throwable) {
return handle(Long.class, throwable, "Unable to perform reduceBy");
}
} catch (Exception ex) {
return reduceByR(array, object);
}
}
/**
* Returns the native call {@code CallSite} object.
*
* @param caller
* the caller lookup object
* @param name
* the native call name
* @param type
* the native call type
* @return the native call {@code CallSite} object
*/
public static CallSite bootstrapDynamic(MethodHandles.Lookup caller, String name, MethodType type) {
MethodHandle target;
try {
if (!name.startsWith("native:")) {
throw new IllegalArgumentException();
}
String methodName = name.substring("native:".length());
MethodHandle mh = nativeMethods.computeIfAbsent(methodName, NativeCalls::getNativeMethodHandle);
if (mh == null) {
return createRuntimeCallSite(methodName, type);
}
target = adaptMethodHandle(methodName, type, mh);
} catch (IllegalArgumentException e) {
target = invalidCallHandle(name, type);
}
return new ConstantCallSite(target);
}
public static CallSite bootstrap(MethodHandles.Lookup callerLookup, String name, MethodType type, long bindingId)
{
ClassLoader classLoader = callerLookup.lookupClass().getClassLoader();
checkArgument(classLoader instanceof DynamicClassLoader, "Expected %s's classloader to be of type %s", callerLookup.lookupClass().getName(), DynamicClassLoader.class.getName());
DynamicClassLoader dynamicClassLoader = (DynamicClassLoader) classLoader;
MethodHandle target = dynamicClassLoader.getCallSiteBindings().get(bindingId);
checkArgument(target != null, "Binding %s for function %s%s not found", bindingId, name, type.parameterList());
return new ConstantCallSite(target);
}
public static void main(String[] args) throws ReflectiveOperationException {
// Objects
test(new Object());
test("TEST");
test(new VMAnonymousClasses());
test(null);
// Class
test(String.class);
// Arrays
test(new boolean[0]);
test(new byte[0]);
test(new char[0]);
test(new short[0]);
test(new int[0]);
test(new long[0]);
test(new float[0]);
test(new double[0]);
test(new Object[0]);
// Multi-dimensional arrays
test(new byte[0][0]);
test(new Object[0][0]);
// MethodHandle-related
MethodType mt = MethodType.methodType(void.class, String[].class);
MethodHandle mh = MethodHandles.lookup().findStatic(VMAnonymousClasses.class, "main", mt);
test(mt);
test(mh);
test(new ConstantCallSite(mh));
test(new MutableCallSite(MethodType.methodType(void.class)));
test(new VolatileCallSite(MethodType.methodType(void.class)));
System.out.println("TEST PASSED");
}
/**
* Boostrapper for math calls that may overflow
* @param lookup lookup
* @param name name of operation
* @param type method type
* @param programPoint program point to bind to callsite
*
* @return callsite for a math intrinsic node
*/
public static CallSite mathBootstrap(final Lookup lookup, final String name, final MethodType type, final int programPoint) {
final MethodHandle mh;
switch (name) {
case "iadd":
mh = JSType.ADD_EXACT.methodHandle();
break;
case "isub":
mh = JSType.SUB_EXACT.methodHandle();
break;
case "imul":
mh = JSType.MUL_EXACT.methodHandle();
break;
case "idiv":
mh = JSType.DIV_EXACT.methodHandle();
break;
case "irem":
mh = JSType.REM_EXACT.methodHandle();
break;
case "ineg":
mh = JSType.NEGATE_EXACT.methodHandle();
break;
default:
throw new AssertionError("unsupported math intrinsic");
}
return new ConstantCallSite(MH.insertArguments(mh, mh.type().parameterCount() - 1, programPoint));
}
public static void main(String[] args) throws ReflectiveOperationException {
// Objects
test(new Object());
test("TEST");
test(new VMAnonymousClasses());
test(null);
// Class
test(String.class);
// Arrays
test(new boolean[0]);
test(new byte[0]);
test(new char[0]);
test(new short[0]);
test(new int[0]);
test(new long[0]);
test(new float[0]);
test(new double[0]);
test(new Object[0]);
// Multi-dimensional arrays
test(new byte[0][0]);
test(new Object[0][0]);
// MethodHandle-related
MethodType mt = MethodType.methodType(void.class, String[].class);
MethodHandle mh = MethodHandles.lookup().findStatic(VMAnonymousClasses.class, "main", mt);
test(mt);
test(mh);
test(new ConstantCallSite(mh));
test(new MutableCallSite(MethodType.methodType(void.class)));
test(new VolatileCallSite(MethodType.methodType(void.class)));
System.out.println("TEST PASSED");
}
public static void main(String[] args) throws ReflectiveOperationException {
// Objects
test(new Object());
test("TEST");
test(new VMAnonymousClasses());
test(null);
// Class
test(String.class);
// Arrays
test(new boolean[0]);
test(new byte[0]);
test(new char[0]);
test(new short[0]);
test(new int[0]);
test(new long[0]);
test(new float[0]);
test(new double[0]);
test(new Object[0]);
// Multi-dimensional arrays
test(new byte[0][0]);
test(new Object[0][0]);
// MethodHandle-related
MethodType mt = MethodType.methodType(void.class, String[].class);
MethodHandle mh = MethodHandles.lookup().findStatic(VMAnonymousClasses.class, "main", mt);
test(mt);
test(mh);
test(new ConstantCallSite(mh));
test(new MutableCallSite(MethodType.methodType(void.class)));
test(new VolatileCallSite(MethodType.methodType(void.class)));
System.out.println("TEST PASSED");
}
/**
* Boostrapper for math calls that may overflow
* @param lookup lookup
* @param name name of operation
* @param type method type
* @param programPoint program point to bind to callsite
*
* @return callsite for a math intrinsic node
*/
public static CallSite mathBootstrap(final Lookup lookup, final String name, final MethodType type, final int programPoint) {
final MethodHandle mh;
switch (name) {
case "iadd":
mh = JSType.ADD_EXACT.methodHandle();
break;
case "isub":
mh = JSType.SUB_EXACT.methodHandle();
break;
case "imul":
mh = JSType.MUL_EXACT.methodHandle();
break;
case "idiv":
mh = JSType.DIV_EXACT.methodHandle();
break;
case "irem":
mh = JSType.REM_EXACT.methodHandle();
break;
case "ineg":
mh = JSType.NEGATE_EXACT.methodHandle();
break;
default:
throw new AssertionError("unsupported math intrinsic");
}
return new ConstantCallSite(MH.insertArguments(mh, mh.type().parameterCount() - 1, programPoint));
}
public static void main(String[] args) throws ReflectiveOperationException {
// Objects
test(new Object());
test("TEST");
test(new VMAnonymousClasses());
test(null);
// Class
test(String.class);
// Arrays
test(new boolean[0]);
test(new byte[0]);
test(new char[0]);
test(new short[0]);
test(new int[0]);
test(new long[0]);
test(new float[0]);
test(new double[0]);
test(new Object[0]);
// Multi-dimensional arrays
test(new byte[0][0]);
test(new Object[0][0]);
// MethodHandle-related
MethodType mt = MethodType.methodType(void.class, String[].class);
MethodHandle mh = MethodHandles.lookup().findStatic(VMAnonymousClasses.class, "main", mt);
test(mt);
test(mh);
test(new ConstantCallSite(mh));
test(new MutableCallSite(MethodType.methodType(void.class)));
test(new VolatileCallSite(MethodType.methodType(void.class)));
System.out.println("TEST PASSED");
}
/**
* Boostrapper for math calls that may overflow
* @param lookup lookup
* @param name name of operation
* @param type method type
* @param programPoint program point to bind to callsite
*
* @return callsite for a math intrinsic node
*/
public static CallSite mathBootstrap(final Lookup lookup, final String name, final MethodType type, final int programPoint) {
final MethodHandle mh;
switch (name) {
case "iadd":
mh = JSType.ADD_EXACT.methodHandle();
break;
case "isub":
mh = JSType.SUB_EXACT.methodHandle();
break;
case "imul":
mh = JSType.MUL_EXACT.methodHandle();
break;
case "idiv":
mh = JSType.DIV_EXACT.methodHandle();
break;
case "irem":
mh = JSType.REM_EXACT.methodHandle();
break;
case "ineg":
mh = JSType.NEGATE_EXACT.methodHandle();
break;
default:
throw new AssertionError("unsupported math intrinsic");
}
return new ConstantCallSite(MH.insertArguments(mh, mh.type().parameterCount() - 1, programPoint));
}
public static String testCallSiteGetTargetSnippet(int i) throws Exception {
ConstantCallSite site;
MethodHandles.Lookup lookup = MethodHandles.lookup();
switch (i) {
case 1:
site = GraalDirectives.opaque(new ConstantCallSite(lookup.findVirtual(String.class, "replace", MethodType.methodType(String.class, char.class, char.class))));
break;
default:
site = GraalDirectives.opaque(new ConstantCallSite(lookup.findStatic(java.util.Arrays.class, "asList", MethodType.methodType(java.util.List.class, Object[].class))));
}
return site.getTarget().toString();
}
public JavaConstant getCallSiteTarget(Assumptions assumptions) {
if (object instanceof CallSite) {
CallSite callSite = (CallSite) object;
MethodHandle target = callSite.getTarget();
if (!(callSite instanceof ConstantCallSite)) {
if (assumptions == null) {
return null;
}
assumptions.record(new Assumptions.CallSiteTargetValue(callSite, target));
}
return HotSpotObjectConstantImpl.forObject(target);
}
return null;
}
public static CallSite getCallSite() {
try {
MethodHandle mh = MethodHandles.lookup().findStatic(
BootstrapMethodErrorTest.class,
"target",
MethodType.methodType(Object.class, Object.class));
return new ConstantCallSite(mh);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public static void main(String[] args) throws ReflectiveOperationException {
// Objects
test(new Object());
test("TEST");
test(new VMAnonymousClasses());
test(null);
// Class
test(String.class);
// Arrays
test(new boolean[0]);
test(new byte[0]);
test(new char[0]);
test(new short[0]);
test(new int[0]);
test(new long[0]);
test(new float[0]);
test(new double[0]);
test(new Object[0]);
// Multi-dimensional arrays
test(new byte[0][0]);
test(new Object[0][0]);
// MethodHandle-related
MethodType mt = MethodType.methodType(void.class, String[].class);
MethodHandle mh = MethodHandles.lookup().findStatic(VMAnonymousClasses.class, "main", mt);
test(mt);
test(mh);
test(new ConstantCallSite(mh));
test(new MutableCallSite(MethodType.methodType(void.class)));
test(new VolatileCallSite(MethodType.methodType(void.class)));
System.out.println("TEST PASSED");
}
/**
* A bootstrap method for invokedynamic
* @param lookup a lookup object
* @param methodName methodName
* @param type method type
* @return CallSite for method
*/
public static CallSite bootstrapMethod(MethodHandles.Lookup lookup,
String methodName, MethodType type) throws IllegalAccessException,
NoSuchMethodException {
MethodType mtype = MethodType.methodType(boolean.class,
new Class<?>[]{int.class, long.class, float.class,
double.class, String.class});
return new ConstantCallSite(lookup.findVirtual(lookup.lookupClass(),
methodName, mtype));
}
public static void main(String[] args) throws ReflectiveOperationException {
// Objects
test(new Object());
test("TEST");
test(new VMAnonymousClasses());
test(null);
// Class
test(String.class);
// Arrays
test(new boolean[0]);
test(new byte[0]);
test(new char[0]);
test(new short[0]);
test(new int[0]);
test(new long[0]);
test(new float[0]);
test(new double[0]);
test(new Object[0]);
// Multi-dimensional arrays
test(new byte[0][0]);
test(new Object[0][0]);
// MethodHandle-related
MethodType mt = MethodType.methodType(void.class, String[].class);
MethodHandle mh = MethodHandles.lookup().findStatic(VMAnonymousClasses.class, "main", mt);
test(mt);
test(mh);
test(new ConstantCallSite(mh));
test(new MutableCallSite(MethodType.methodType(void.class)));
test(new VolatileCallSite(MethodType.methodType(void.class)));
System.out.println("TEST PASSED");
}
/**
* Boostrapper for math calls that may overflow
* @param lookup lookup
* @param name name of operation
* @param type method type
* @param programPoint program point to bind to callsite
*
* @return callsite for a math intrinsic node
*/
public static CallSite mathBootstrap(final Lookup lookup, final String name, final MethodType type, final int programPoint) {
final MethodHandle mh;
switch (name) {
case "iadd":
mh = JSType.ADD_EXACT.methodHandle();
break;
case "isub":
mh = JSType.SUB_EXACT.methodHandle();
break;
case "imul":
mh = JSType.MUL_EXACT.methodHandle();
break;
case "idiv":
mh = JSType.DIV_EXACT.methodHandle();
break;
case "irem":
mh = JSType.REM_EXACT.methodHandle();
break;
case "ineg":
mh = JSType.NEGATE_EXACT.methodHandle();
break;
default:
throw new AssertionError("unsupported math intrinsic");
}
return new ConstantCallSite(MH.insertArguments(mh, mh.type().parameterCount() - 1, programPoint));
}