--- a/jdk/src/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java Thu Dec 20 09:18:20 2012 -0800
+++ b/jdk/src/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java Fri Dec 21 10:27:22 2012 -0800
@@ -295,9 +295,6 @@
String invokerDesc = invokerType.toMethodDescriptorString();
mv = cw.visitMethod(Opcodes.ACC_STATIC, invokerName, invokerDesc, null, null);
-
- // Force inlining of this invoker method.
- mv.visitAnnotation("Ljava/lang/invoke/ForceInline;", true);
}
/**
@@ -524,6 +521,9 @@
// Mark this method as a compiled LambdaForm
mv.visitAnnotation("Ljava/lang/invoke/LambdaForm$Compiled;", true);
+ // Force inlining of this invoker method.
+ mv.visitAnnotation("Ljava/lang/invoke/ForceInline;", true);
+
// iterate over the form's names, generating bytecode instructions for each
// start iterating at the first name following the arguments
for (int i = lambdaForm.arity; i < lambdaForm.names.length; i++) {
@@ -943,6 +943,9 @@
// Suppress this method in backtraces displayed to the user.
mv.visitAnnotation("Ljava/lang/invoke/LambdaForm$Hidden;", true);
+ // Don't inline the interpreter entry.
+ mv.visitAnnotation("Ljava/lang/invoke/DontInline;", true);
+
// create parameter array
emitIconstInsn(invokerType.parameterCount());
mv.visitTypeInsn(Opcodes.ANEWARRAY, "java/lang/Object");
@@ -1005,6 +1008,9 @@
// Suppress this method in backtraces displayed to the user.
mv.visitAnnotation("Ljava/lang/invoke/LambdaForm$Hidden;", true);
+ // Force inlining of this invoker method.
+ mv.visitAnnotation("Ljava/lang/invoke/ForceInline;", true);
+
// Load receiver
emitAloadInsn(0);
--- a/jdk/src/share/classes/java/lang/invoke/LambdaForm.java Thu Dec 20 09:18:20 2012 -0800
+++ b/jdk/src/share/classes/java/lang/invoke/LambdaForm.java Fri Dec 21 10:27:22 2012 -0800
@@ -592,6 +592,7 @@
private int invocationCounter = 0;
@Hidden
+ @DontInline
/** Interpretively invoke this form on the given arguments. */
Object interpretWithArguments(Object... argumentValues) throws Throwable {
if (TRACE_INTERPRETER)
@@ -606,6 +607,7 @@
}
@Hidden
+ @DontInline
/** Evaluate a single Name within this form, applying its function to its arguments. */
Object interpretName(Name name, Object[] values) throws Throwable {
if (TRACE_INTERPRETER)
--- a/jdk/src/share/classes/java/lang/invoke/MethodHandleImpl.java Thu Dec 20 09:18:20 2012 -0800
+++ b/jdk/src/share/classes/java/lang/invoke/MethodHandleImpl.java Fri Dec 21 10:27:22 2012 -0800
@@ -310,9 +310,9 @@
}
static class AsVarargsCollector extends MethodHandle {
- MethodHandle target;
- final Class<?> arrayType;
- MethodHandle cache;
+ private final MethodHandle target;
+ private final Class<?> arrayType;
+ private MethodHandle cache;
AsVarargsCollector(MethodHandle target, MethodType type, Class<?> arrayType) {
super(type, reinvokerForm(type));
--- a/jdk/src/share/classes/sun/invoke/util/ValueConversions.java Thu Dec 20 09:18:20 2012 -0800
+++ b/jdk/src/share/classes/sun/invoke/util/ValueConversions.java Fri Dec 21 10:27:22 2012 -0800
@@ -449,8 +449,16 @@
* @param x an arbitrary reference value
* @return the same value x
*/
+ @SuppressWarnings("unchecked")
static <T,U> T castReference(Class<? extends T> t, U x) {
- return t.cast(x);
+ // inlined Class.cast because we can't ForceInline it
+ if (x != null && !t.isInstance(x))
+ throw newClassCastException(t, x);
+ return (T) x;
+ }
+
+ private static ClassCastException newClassCastException(Class<?> t, Object obj) {
+ return new ClassCastException("Cannot cast " + obj.getClass().getName() + " to " + t.getName());
}
private static final MethodHandle IDENTITY, CAST_REFERENCE, ZERO_OBJECT, IGNORE, EMPTY,
--- a/jdk/src/share/classes/sun/misc/Unsafe.java Thu Dec 20 09:18:20 2012 -0800
+++ b/jdk/src/share/classes/sun/misc/Unsafe.java Fri Dec 21 10:27:22 2012 -0800
@@ -1008,4 +1008,125 @@
* if the load average is unobtainable.
*/
public native int getLoadAverage(double[] loadavg, int nelems);
+
+ // The following contain CAS-based Java implementations used on
+ // platforms not supporting native instructions
+
+ /**
+ * Atomically adds the given value to the current value of a field
+ * or array element within the given object <code>o</code>
+ * at the given <code>offset</code>.
+ *
+ * @param o object/array to update the field/element in
+ * @param offset field/element offset
+ * @param delta the value to add
+ * @return the previous value
+ * @since 1.8
+ */
+ public final int getAndAddInt(Object o, long offset, int delta) {
+ int v;
+ do {
+ v = getIntVolatile(o, offset);
+ } while (!compareAndSwapInt(o, offset, v, v + delta));
+ return v;
+ }
+
+ /**
+ * Atomically adds the given value to the current value of a field
+ * or array element within the given object <code>o</code>
+ * at the given <code>offset</code>.
+ *
+ * @param o object/array to update the field/element in
+ * @param offset field/element offset
+ * @param delta the value to add
+ * @return the previous value
+ * @since 1.8
+ */
+ public final long getAndAddLong(Object o, long offset, long delta) {
+ long v;
+ do {
+ v = getLongVolatile(o, offset);
+ } while (!compareAndSwapLong(o, offset, v, v + delta));
+ return v;
+ }
+
+ /**
+ * Atomically exchanges the given value with the current value of
+ * a field or array element within the given object <code>o</code>
+ * at the given <code>offset</code>.
+ *
+ * @param o object/array to update the field/element in
+ * @param offset field/element offset
+ * @param newValue new value
+ * @return the previous value
+ * @since 1.8
+ */
+ public final int getAndSetInt(Object o, long offset, int newValue) {
+ int v;
+ do {
+ v = getIntVolatile(o, offset);
+ } while (!compareAndSwapInt(o, offset, v, newValue));
+ return v;
+ }
+
+ /**
+ * Atomically exchanges the given value with the current value of
+ * a field or array element within the given object <code>o</code>
+ * at the given <code>offset</code>.
+ *
+ * @param o object/array to update the field/element in
+ * @param offset field/element offset
+ * @param newValue new value
+ * @return the previous value
+ * @since 1.8
+ */
+ public final long getAndSetLong(Object o, long offset, long newValue) {
+ long v;
+ do {
+ v = getLongVolatile(o, offset);
+ } while (!compareAndSwapLong(o, offset, v, newValue));
+ return v;
+ }
+
+ /**
+ * Atomically exchanges the given reference value with the current
+ * reference value of a field or array element within the given
+ * object <code>o</code> at the given <code>offset</code>.
+ *
+ * @param o object/array to update the field/element in
+ * @param offset field/element offset
+ * @param newValue new value
+ * @return the previous value
+ * @since 1.8
+ */
+ public final Object getAndSetObject(Object o, long offset, Object newValue) {
+ Object v;
+ do {
+ v = getObjectVolatile(o, offset);
+ } while (!compareAndSwapObject(o, offset, v, newValue));
+ return v;
+ }
+
+
+ /**
+ * Ensures lack of reordering of loads before the fence
+ * with loads or stores after the fence.
+ * @since 1.8
+ */
+ public native void loadFence();
+
+ /**
+ * Ensures lack of reordering of stores before the fence
+ * with loads or stores after the fence.
+ * @since 1.8
+ */
+ public native void storeFence();
+
+ /**
+ * Ensures lack of reordering of loads or stores before the fence
+ * with loads or stores after the fence.
+ * @since 1.8
+ */
+ public native void fullFence();
+
}