--- a/jdk/src/java.base/share/classes/java/lang/invoke/CallSite.java Wed Oct 26 15:08:29 2016 +0530
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/CallSite.java Fri Oct 14 14:47:27 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2016, 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
@@ -272,7 +272,7 @@
MethodHandleNatives.setCallSiteTargetVolatile(this, newTarget);
}
- // this implements the upcall from the JVM, MethodHandleNatives.makeDynamicCallSite:
+ // this implements the upcall from the JVM, MethodHandleNatives.linkCallSite:
static CallSite makeSite(MethodHandle bootstrapMethod,
// Callee information:
String name, MethodType type,
@@ -293,59 +293,72 @@
Object[] argv = (Object[]) info;
maybeReBoxElements(argv);
switch (argv.length) {
- case 0:
- binding = bootstrapMethod.invoke(caller, name, type);
- break;
- case 1:
- binding = bootstrapMethod.invoke(caller, name, type,
- argv[0]);
- break;
- case 2:
- binding = bootstrapMethod.invoke(caller, name, type,
- argv[0], argv[1]);
- break;
- case 3:
- binding = bootstrapMethod.invoke(caller, name, type,
- argv[0], argv[1], argv[2]);
- break;
- case 4:
- binding = bootstrapMethod.invoke(caller, name, type,
- argv[0], argv[1], argv[2], argv[3]);
- break;
- case 5:
- binding = bootstrapMethod.invoke(caller, name, type,
- argv[0], argv[1], argv[2], argv[3], argv[4]);
- break;
- case 6:
- binding = bootstrapMethod.invoke(caller, name, type,
- argv[0], argv[1], argv[2], argv[3], argv[4], argv[5]);
- break;
- default:
- final int NON_SPREAD_ARG_COUNT = 3; // (caller, name, type)
- if (NON_SPREAD_ARG_COUNT + argv.length > MethodType.MAX_MH_ARITY)
- throw new BootstrapMethodError("too many bootstrap method arguments");
- MethodType bsmType = bootstrapMethod.type();
- MethodType invocationType = MethodType.genericMethodType(NON_SPREAD_ARG_COUNT + argv.length);
- MethodHandle typedBSM = bootstrapMethod.asType(invocationType);
- MethodHandle spreader = invocationType.invokers().spreadInvoker(NON_SPREAD_ARG_COUNT);
- binding = spreader.invokeExact(typedBSM, (Object)caller, (Object)name, (Object)type, argv);
+ case 0:
+ binding = bootstrapMethod.invoke(caller, name, type);
+ break;
+ case 1:
+ binding = bootstrapMethod.invoke(caller, name, type,
+ argv[0]);
+ break;
+ case 2:
+ binding = bootstrapMethod.invoke(caller, name, type,
+ argv[0], argv[1]);
+ break;
+ case 3:
+ binding = bootstrapMethod.invoke(caller, name, type,
+ argv[0], argv[1], argv[2]);
+ break;
+ case 4:
+ binding = bootstrapMethod.invoke(caller, name, type,
+ argv[0], argv[1], argv[2], argv[3]);
+ break;
+ case 5:
+ binding = bootstrapMethod.invoke(caller, name, type,
+ argv[0], argv[1], argv[2], argv[3], argv[4]);
+ break;
+ case 6:
+ binding = bootstrapMethod.invoke(caller, name, type,
+ argv[0], argv[1], argv[2], argv[3], argv[4], argv[5]);
+ break;
+ default:
+ final int NON_SPREAD_ARG_COUNT = 3; // (caller, name, type)
+ if (NON_SPREAD_ARG_COUNT + argv.length > MethodType.MAX_MH_ARITY)
+ throw new BootstrapMethodError("too many bootstrap method arguments");
+ MethodType bsmType = bootstrapMethod.type();
+ MethodType invocationType = MethodType.genericMethodType(NON_SPREAD_ARG_COUNT + argv.length);
+ MethodHandle typedBSM = bootstrapMethod.asType(invocationType);
+ MethodHandle spreader = invocationType.invokers().spreadInvoker(NON_SPREAD_ARG_COUNT);
+ binding = spreader.invokeExact(typedBSM, (Object) caller, (Object) name, (Object) type, argv);
}
}
- //System.out.println("BSM for "+name+type+" => "+binding);
if (binding instanceof CallSite) {
site = (CallSite) binding;
- } else {
+ } else {
+ // See the "Linking Exceptions" section for the invokedynamic
+ // instruction in JVMS 6.5.
+ // Throws a runtime exception defining the cause that is then
+ // in the "catch (Throwable ex)" a few lines below wrapped in
+ // BootstrapMethodError
throw new ClassCastException("bootstrap method failed to produce a CallSite");
}
- if (!site.getTarget().type().equals(type))
+ if (!site.getTarget().type().equals(type)) {
+ // See the "Linking Exceptions" section for the invokedynamic
+ // instruction in JVMS 6.5.
+ // Throws a runtime exception defining the cause that is then
+ // in the "catch (Throwable ex)" a few lines below wrapped in
+ // BootstrapMethodError
throw wrongTargetType(site.getTarget(), type);
+ }
+ } catch (Error e) {
+ // Pass through an Error, including BootstrapMethodError, any other
+ // form of linkage error, such as IllegalAccessError if the bootstrap
+ // method is inaccessible, or say ThreadDeath/OutOfMemoryError
+ // See the "Linking Exceptions" section for the invokedynamic
+ // instruction in JVMS 6.5.
+ throw e;
} catch (Throwable ex) {
- BootstrapMethodError bex;
- if (ex instanceof BootstrapMethodError)
- bex = (BootstrapMethodError) ex;
- else
- bex = new BootstrapMethodError("call site initialization exception", ex);
- throw bex;
+ // Wrap anything else in BootstrapMethodError
+ throw new BootstrapMethodError("call site initialization exception", ex);
}
return site;
}
--- a/jdk/src/java.base/share/classes/java/lang/invoke/package-info.java Wed Oct 26 15:08:29 2016 +0530
+++ b/jdk/src/java.base/share/classes/java/lang/invoke/package-info.java Fri Oct 14 14:47:27 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2016, 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
@@ -84,20 +84,21 @@
* </ul>
* Invocation is as if by
* {@link java.lang.invoke.MethodHandle#invoke MethodHandle.invoke}.
- * The returned result must be a {@link java.lang.invoke.CallSite CallSite} (or a subclass).
+ * The returned result must be a {@link java.lang.invoke.CallSite CallSite}
+ * (or a subclass), otherwise a
+ * {@link java.lang.BootstrapMethodError BootstrapMethodError} is thrown.
* The type of the call site's target must be exactly equal to the type
* derived from the dynamic call site's type descriptor and passed to
- * the bootstrap method.
- * The call site then becomes permanently linked to the dynamic call site.
+ * the bootstrap method, otherwise a {@code BootstrapMethodError} is thrown.
+ * On success the call site then becomes permanently linked to the dynamic call
+ * site.
* <p>
- * As documented in the JVM specification, all failures arising from
- * the linkage of a dynamic call site are reported
- * by a {@link java.lang.BootstrapMethodError BootstrapMethodError},
- * which is thrown as the abnormal termination of the dynamic call
- * site execution.
- * If this happens, the same error will the thrown for all subsequent
- * attempts to execute the dynamic call site.
- *
+ * If an exception, {@code E} say, occurs when linking the call site then the
+ * linkage fails and terminates abnormally. {@code E} is rethrown if the type of
+ * {@code E} is {@code Error} or a subclass, otherwise a
+ * {@code BootstrapMethodError} that wraps {@code E} is thrown.
+ * If this happens, the same {@code Error} or subclass will the thrown for all
+ * subsequent attempts to execute the dynamic call site.
* <h2>timing of linkage</h2>
* A dynamic call site is linked just before its first execution.
* The bootstrap method call implementing the linkage occurs within
--- a/jdk/test/java/lang/invoke/8022701/InvokeSeveralWays.java Wed Oct 26 15:08:29 2016 +0530
+++ b/jdk/test/java/lang/invoke/8022701/InvokeSeveralWays.java Fri Oct 14 14:47:27 2016 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2016, 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
@@ -37,18 +37,11 @@
failures++;
} catch (InvocationTargetException e) {
Throwable c = e.getCause();
- if (BootstrapMethodError.class.isInstance(c)) {
- c = c.getCause();
- if (expected.isInstance(c))
- System.out.println("EXPECTED: " + expected.getName() + ", "+ c);
- else {
- failures++;
- System.out.println("FAIL: Unexpected wrapped exception " + c);
- e.printStackTrace(System.out);
- }
- } else {
+ if (expected.isInstance(c))
+ System.out.println("EXPECTED: " + expected.getName() + ", "+ c);
+ else {
failures++;
- System.out.println("FAIL: Exception from MethodHandle invocation not wrapped in BootstrapMethodError " + c);
+ System.out.println("FAIL: Unexpected wrapped exception " + c);
e.printStackTrace(System.out);
}
} catch (Throwable e) {
@@ -80,19 +73,14 @@
Invoker.invoke();
System.out.println("FAIL: No exception throw, probably failed to load modified bytecodes for MethodSupplier");
failures++;
- } catch (BootstrapMethodError e) {
- Throwable c = e.getCause();
- if (expected.isInstance(c))
- System.out.println("EXPECTED: " + expected.getName() + ", "+ c);
+ } catch (Throwable e) {
+ if (expected.isInstance(e))
+ System.out.println("EXPECTED: " + expected.getName() + ", "+ e);
else {
failures++;
- System.out.println("FAIL: Unexpected exception has been caught " + c);
+ System.out.println("FAIL: Unexpected exception has been caught " + e);
e.printStackTrace(System.out);
}
- } catch (Throwable e) {
- failures++;
- System.out.println("FAIL: Exception from MethodHandle invocation not wrapped in BootstrapMethodError " + e);
- e.printStackTrace(System.out);
}
System.out.println();
try {